Compare commits

..

1 Commits

Author SHA1 Message Date
drh c0359f0490 If a subquery is used to drive an index, this change avoids making an extra
copy of the result of that subquery.  But, such situations are probably
sufficiently unusual that the added complexity of this enhancement is not
worth the performance gain.  So I'm going to park this check-in on a branch.
If we later find a use case to justify it, we can merge it to trunk then.
This is the "further change" that was promised by the prior check-in comment.

FossilOrigin-Name: 4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
2021-05-28 14:28:54 +00:00
572 changed files with 12210 additions and 114632 deletions
+20 -62
View File
@@ -35,7 +35,7 @@ TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
TCC += -I${TOP}/ext/userauth
# Define this for the autoconf-based build, so that the code knows it can
# include the generated sqlite_cfg.h
# include the generated config.h
#
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
@@ -165,7 +165,6 @@ LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
###############################################################################
USE_AMALGAMATION = @USE_AMALGAMATION@
AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@
# Object files for the SQLite library (non-amalgamation).
#
@@ -180,11 +179,11 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
fts5.lo \
func.lo global.lo hash.lo \
icu.lo insert.lo json.lo legacy.lo loadext.lo \
icu.lo insert.lo json1.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memdb.lo memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo \
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
@@ -234,7 +233,6 @@ SRC = \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
$(TOP)/src/insert.c \
$(TOP)/src/json.c \
$(TOP)/src/legacy.c \
$(TOP)/src/loadext.c \
$(TOP)/src/main.c \
@@ -257,7 +255,6 @@ SRC = \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
@@ -368,6 +365,7 @@ SRC += \
$(TOP)/ext/rbu/sqlite3rbu.h \
$(TOP)/ext/rbu/sqlite3rbu.c
SRC += \
$(TOP)/ext/misc/json1.c \
$(TOP)/ext/misc/stmt.c
# Generated source code files
@@ -378,7 +376,7 @@ SRC += \
opcodes.h \
parse.c \
parse.h \
sqlite_cfg.h \
config.h \
shell.c \
sqlite3.h
@@ -434,9 +432,6 @@ TESTSRC = \
$(TOP)/ext/fts3/fts3_term.c \
$(TOP)/ext/fts3/fts3_test.c \
$(TOP)/ext/session/test_session.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/test_recover.c \
$(TOP)/ext/rbu/test_rbu.c
# Statically linked extensions
@@ -464,7 +459,6 @@ TESTSRC += \
$(TOP)/ext/misc/normalize.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/prefixes.c \
$(TOP)/ext/misc/qpvtab.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/remember.c \
$(TOP)/ext/misc/series.c \
@@ -473,8 +467,7 @@ TESTSRC += \
$(TOP)/ext/misc/unionvtab.c \
$(TOP)/ext/misc/wholenumber.c \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/userauth/userauth.c \
$(TOP)/ext/rtree/test_rtreedoc.c
$(TOP)/ext/userauth/userauth.c
# Source code to the library files needed by the test fixture
#
@@ -496,7 +489,6 @@ TESTSRC2 = \
$(TOP)/src/main.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@@ -508,7 +500,6 @@ TESTSRC2 = \
$(TOP)/src/pcache1.c \
$(TOP)/src/select.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/treeview.c \
$(TOP)/src/utf.c \
$(TOP)/src/util.c \
$(TOP)/src/vdbeapi.c \
@@ -560,7 +551,7 @@ HDR = \
$(TOP)/src/vdbeInt.h \
$(TOP)/src/vxworks.h \
$(TOP)/src/whereInt.h \
sqlite_cfg.h
config.h
# Header files used by extensions
#
@@ -615,7 +606,7 @@ TESTOPTS = --verbose=file --output=test-out.txt
# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_FTS4
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
SHELL_OPT += -DSQLITE_ENABLE_RTREE
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
@@ -625,28 +616,19 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
FUZZERSHELL_OPT =
FUZZCHECK_OPT += -I$(TOP)/test
FUZZCHECK_OPT += -I$(TOP)/ext/recover
FUZZCHECK_OPT += -DSQLITE_OMIT_LOAD_EXTENSION
FUZZCHECK_OPT += -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c
FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c
FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
FUZZCHECK_SRC += $(TOP)/test/vt02.c
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
@@ -695,7 +677,7 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP)
fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
@@ -774,7 +756,7 @@ mptest: mptester$(TEXE)
touch .target_source
sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS)
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
cp tsrc/sqlite3ext.h .
cp $(TOP)/ext/session/sqlite3session.h .
@@ -889,9 +871,6 @@ hash.lo: $(TOP)/src/hash.c $(HDR)
insert.lo: $(TOP)/src/insert.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c
json.lo: $(TOP)/src/json.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c
legacy.lo: $(TOP)/src/legacy.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c
@@ -952,9 +931,6 @@ pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h
os.lo: $(TOP)/src/os.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c
os_kv.lo: $(TOP)/src/os_kv.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c
os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c
@@ -1110,7 +1086,6 @@ SHELL_SRC = \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
@@ -1119,9 +1094,6 @@ SHELL_SRC = \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
@@ -1201,6 +1173,9 @@ userauth.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c
json1.lo: $(TOP)/ext/misc/json1.c
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
stmt.lo: $(TOP)/ext/misc/stmt.c
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c
@@ -1273,10 +1248,7 @@ coretestprogs: $(TESTPROGS)
testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
# A very detailed test running most or all test cases
fulltest: alltest fuzztest
# Run most or all tcl test cases
alltest: $(TESTPROGS)
fulltest: $(TESTPROGS) fuzztest
./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS)
# Really really long testing
@@ -1301,12 +1273,6 @@ valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessio
tcltest: ./testfixture$(TEXE)
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
# Runs all the same tests cases as the "tcltest" target but uses
# the testrunner.tcl script to run them in multiple cores
# concurrently.
testrunner: testfixture$(TEXE)
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl
# Minimal testing that runs in less than 3 minutes
#
quicktest: ./testfixture$(TEXE)
@@ -1407,7 +1373,7 @@ LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c
$(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS)
startup$(TEXE): $(TOP)/test/startup.c sqlite3.c
@@ -1496,7 +1462,6 @@ clean:
rm -rf .libs .deps
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f mksourceid$(BEXE)
rm -f *.da *.bb *.bbg gmon.out
rm -rf tsrc .target_source
rm -f tclsqlite3$(TEXE)
@@ -1521,8 +1486,7 @@ clean:
rm -f threadtest5
distclean: clean
rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \
$(TESTPROGS)
rm -f config.h config.log config.status libtool Makefile sqlite3.pc
#
# Windows section
@@ -1541,9 +1505,3 @@ sqlite3.def: $(REAL_LIBOBJ)
sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def
$(TCC) -shared -o $@ sqlite3.def \
-Wl,"--strip-all" $(REAL_LIBOBJ)
#
# Fiddle app
#
fiddle: sqlite3.c shell.c
make -C ext/wasm fiddle emcc_opt=-Os
+28 -74
View File
@@ -235,9 +235,8 @@ DEBUG = 0
!ENDIF
# <<mark>>
# By default, use --linemacros=1 argument to the mksqlite3c.tcl tool, which
# is used to build the amalgamation. This can be turned off to ease debug
# of the amalgamation away from the source tree.
# Disable use of the --linemacros argument to the mksqlite3c.tcl tool, which
# is used to build the amalgamation.
#
!IFNDEF NO_LINEMACROS
NO_LINEMACROS = 0
@@ -363,6 +362,7 @@ SQLITE_TCL_DEP =
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
@@ -579,17 +579,17 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
#
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
!IF "$(PLATFORM)"=="x86"
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
# <<mark>>
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
# <</mark>>
!ELSE
!IFNDEF PLATFORM
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
# <<mark>>
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
# <</mark>>
!ELSE
CORE_CCONV_OPTS =
@@ -788,9 +788,9 @@ MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl
!IFNDEF MKSQLITE3C_ARGS
!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0
MKSQLITE3C_ARGS = --linemacros=1
MKSQLITE3C_ARGS = --linemacros
!ELSE
MKSQLITE3C_ARGS = --linemacros=0
MKSQLITE3C_ARGS =
!ENDIF
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall
@@ -1247,11 +1247,11 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
fts5.lo \
func.lo global.lo hash.lo \
icu.lo insert.lo json.lo legacy.lo loadext.lo \
icu.lo insert.lo json1.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memdb.lo memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo \
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
@@ -1314,7 +1314,6 @@ SRC00 = \
$(TOP)\src\global.c \
$(TOP)\src\hash.c \
$(TOP)\src\insert.c \
$(TOP)\src\json.c \
$(TOP)\src\legacy.c \
$(TOP)\src\loadext.c \
$(TOP)\src\main.c \
@@ -1332,7 +1331,6 @@ SRC00 = \
$(TOP)\src\mutex_w32.c \
$(TOP)\src\notify.c \
$(TOP)\src\os.c \
$(TOP)\src\os_kv.c \
$(TOP)\src\os_unix.c \
$(TOP)\src\os_win.c
@@ -1446,6 +1444,7 @@ SRC07 = \
$(TOP)\ext\rtree\rtree.c \
$(TOP)\ext\session\sqlite3session.c \
$(TOP)\ext\rbu\sqlite3rbu.c \
$(TOP)\ext\misc\json1.c \
$(TOP)\ext\misc\stmt.c
# Extension header files, part 1.
@@ -1579,7 +1578,6 @@ TESTEXT = \
$(TOP)\ext\misc\normalize.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\prefixes.c \
$(TOP)\ext\misc\qpvtab.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\remember.c \
$(TOP)\ext\misc\series.c \
@@ -1587,10 +1585,6 @@ TESTEXT = \
$(TOP)\ext\misc\totype.c \
$(TOP)\ext\misc\unionvtab.c \
$(TOP)\ext\misc\wholenumber.c \
$(TOP)\ext\rtree\test_rtreedoc.c \
$(TOP)\ext\recover\sqlite3recover.c \
$(TOP)\ext\recover\test_recover.c \
$(TOP)\ext\recover\dbdata.c \
fts5.c
# If use of zlib is enabled, add the "zipfile.c" source file.
@@ -1699,27 +1693,16 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
# <<mark>>
# Extra compiler options for various test tools.
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS =
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -I$(TOP)\test -I$(TOP)\ext\recover
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_OSS_FUZZ
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzcheck.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\ossfuzz.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
@@ -2004,9 +1987,6 @@ hash.lo: $(TOP)\src\hash.c $(HDR)
insert.lo: $(TOP)\src\insert.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\insert.c
json.lo: $(TOP)\src\json.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\json.c
legacy.lo: $(TOP)\src\legacy.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\legacy.c
@@ -2067,9 +2047,6 @@ pcache1.lo: $(TOP)\src\pcache1.c $(HDR) $(TOP)\src\pcache.h
os.lo: $(TOP)\src\os.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os.c
os_kv.lo: $(TOP)\src\os_kv.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os_kv.c
os_unix.lo: $(TOP)\src\os_unix.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os_unix.c
@@ -2231,19 +2208,15 @@ SHELL_SRC = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\decimal.c \
$(TOP)\ext\misc\decimal.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\misc\memtrace.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
$(TOP)/ext/recover/sqlite3recover.h \
$(TOP)\src\test_windirent.c
# If use of zlib is enabled, add the "zipfile.c" source file.
@@ -2321,6 +2294,9 @@ fts3_unicode2.lo: $(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c
json1.lo: $(TOP)\ext\misc\json1.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\json1.c
stmt.lo: $(TOP)\ext\misc\stmt.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\stmt.c
@@ -2412,6 +2388,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
@@ -2457,9 +2434,7 @@ coretestprogs: $(TESTPROGS)
testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe
fulltest: alltest fuzztest
alltest: $(TESTPROGS)
fulltest: $(TESTPROGS) fuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
@@ -2487,20 +2462,10 @@ quicktest: testfixture.exe sourcetest
# This is the common case. Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test: $(TESTPROGS) sourcetest fuzztest tcltest
# The veryquick.test TCL tests.
#
tcltest: testfixture.exe
test: $(TESTPROGS) sourcetest fuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
# Runs all the same tests cases as the "tcltest" target but uses
# the testrunner.tcl script to run them in multiple cores
# concurrently.
testrunner: testfixture.exe
.\testfixture.exe $(TOP)\test\testrunner.tcl
smoketest: $(TESTPROGS)
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
@@ -2619,17 +2584,6 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
THREADTEST3_SRC = \
$(TOP)\test\threadtest3.c \
$(TOP)\test\tt3_checkpoint.c \
$(TOP)\test\tt3_index.c \
$(TOP)\test\tt3_vacuum.c \
$(TOP)\test\tt3_stress.c \
$(TOP)\test\tt3_lookaside1.c
threadtest3.exe: $(THREADTEST3_SRC) $(TOP)\src\test_multiplex.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
LSMDIR=$(TOP)\ext\lsm1
!INCLUDE $(LSMDIR)\Makefile.msc
@@ -2667,7 +2621,7 @@ clean:
del /Q sqlite-*-output.vsix 2>NUL
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
del /Q sqltclsh.* 2>NUL
del /Q dbfuzz.exe sessionfuzz.exe threadtest3.exe 2>NUL
del /Q dbfuzz.exe sessionfuzz.exe 2>NUL
del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL
del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL
del /Q fts5.* fts5parse.* 2>NUL
+25 -27
View File
@@ -1,7 +1,7 @@
<h1 align="center">SQLite Source Repository</h1>
This repository contains the complete source code for the
[SQLite database engine](https://sqlite.org/). Some test scripts
This repository contains the complete source code for the
[SQLite database engine](https://sqlite.org/). Some test scripts
are also included. However, many other test scripts
and most of the documentation are managed separately.
@@ -15,7 +15,7 @@ The [Fossil repository](https://sqlite.org/src/timeline) contains the urtext.
If you are reading this on GitHub or some other Git repository or service,
then you are looking at a mirror. The names of check-ins and
other artifacts in a Git mirror are different from the official
names for those objects. The official names for check-ins are
names for those objects. The offical names for check-ins are
found in a footer on the check-in comment for authorized mirrors.
The official check-in name can also be seen in the `manifest.uuid` file
in the root of the tree. Always use the official name, not the
@@ -30,7 +30,7 @@ verify its integrity, there are hints on how to do that in the
If you do not want to use Fossil, you can download tarballs or ZIP
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
* Latest trunk check-in as
* Lastest trunk check-in as
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
@@ -47,11 +47,11 @@ archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
then click on the "Tarball" or "ZIP Archive" links on the information
page.
If you do want to use Fossil to check out the source tree,
If you do want to use Fossil to check out the source tree,
first install Fossil version 2.0 or later.
(Source tarballs and precompiled binaries available
[here](https://www.fossil-scm.org/fossil/uv/download.html). Fossil is
a stand-alone program. To install, simply download or build the single
a stand-alone program. To install, simply download or build the single
executable file and put that file someplace on your $PATH.)
Then run commands like this:
@@ -61,14 +61,14 @@ Then run commands like this:
fossil open ~/Fossils/sqlite.fossil
After setting up a repository using the steps above, you can always
update to the latest version using:
update to the lastest version using:
fossil update trunk ;# latest trunk check-in
fossil update release ;# latest official release
Or type "fossil ui" to get a web-based user interface.
## Compiling for Unix-like systems
## Compiling
First create a directory in which to place
the build products. It is recommended, but not required, that the
@@ -94,22 +94,22 @@ script does not work out for you, there is a generic makefile named
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
## Using MSVC for Windows systems
## Using MSVC
On Windows, all applicable build products can be compiled with MSVC.
First open the command prompt window associated with the desired compiler
version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE
with the provided "Makefile.msc" to build one of the supported targets.
For example, from the parent directory of the source subtree named "sqlite":
For example:
mkdir bld
cd bld
nmake /f ..\sqlite\Makefile.msc TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.c TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.dll TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc sqlite3.exe TOP=..\sqlite
nmake /f ..\sqlite\Makefile.msc test TOP=..\sqlite
nmake /f Makefile.msc TOP=..\sqlite
nmake /f Makefile.msc sqlite3.c TOP=..\sqlite
nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite
nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite
nmake /f Makefile.msc test TOP=..\sqlite
There are several build options that can be set via the NMAKE command
line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument
@@ -136,7 +136,7 @@ the "tclsqlite.c" file which implements the
extension and only later escaped to the wild as an independent library.)
Test scripts and programs are found in the **test/** subdirectory.
Additional test code is found in other source repositories.
Addtional test code is found in other source repositories.
See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for
additional information.
@@ -170,7 +170,7 @@ at just the right spots. Note that comment text in the sqlite3.h file is
used to generate much of the SQLite API documentation. The Tcl scripts
used to generate that documentation are in a separate source repository.
The SQL language parser is **parse.c** which is generated from a grammar in
The SQL language parser is **parse.c** which is generate from a grammar in
the src/parse.y file. The conversion of "parse.y" into "parse.c" is done
by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code
for lemon is at tool/lemon.c. Lemon uses the tool/lempar.c file as a
@@ -180,7 +180,7 @@ generates parse.c.
The **opcodes.h** header file contains macros that define the numbers
corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h
file is generated by scanning the src/vdbe.c source file. The
file is generated by the scanning the src/vdbe.c source file. The
Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
the **opcodes.c** source file, which contains a reverse mapping from
@@ -237,7 +237,7 @@ prepared statements, the description of
[how transactions work](http://www.sqlite.org/atomiccommit.html), and
the [overview of the query planner](http://www.sqlite.org/optoverview.html).
Years of effort have gone into optimizing SQLite, both
Years of effort have gone into optimizating SQLite, both
for small size and high performance. And optimizations tend to result in
complex code. So there is a lot of complexity in the current SQLite
implementation. It will not be the easiest library in the world to hack.
@@ -294,11 +294,11 @@ Key files:
building the "testfixture.exe" program. The testfixture.exe program is
an enhanced Tcl shell. The testfixture.exe program runs scripts in the
test/ folder to validate the core SQLite code. The testfixture program
(and some other test programs too) is built and run when you type
(and some other test programs too) is build and run when you type
"make test".
* **ext/misc/json1.c** - This file implements the various JSON functions
that are built into SQLite.
that are build into SQLite.
There are many other source files. Each has a succinct header comment that
describes its purpose and role within the larger system.
@@ -307,13 +307,11 @@ describes its purpose and role within the larger system.
## Verifying Code Authenticity
The `manifest` file at the root directory of the source tree
contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for
contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for
older files) for every source file in the repository.
The name of the version of the entire source tree is just the
SHA3-256 hash of the `manifest` file itself, possibly with the
last line of that file omitted if the last line begins with
"`# Remove this line`".
The `manifest.uuid` file should contain the SHA3-256 hash of the
The SHA3-256 hash of the `manifest`
file itself is the official name of the version of the source tree that you
have. The `manifest.uuid` file should contain the SHA3-256 hash of the
`manifest` file. If all of the above hash comparisons are correct, then
you can be confident that your source tree is authentic and unadulterated.
+1 -1
View File
@@ -1 +1 @@
3.40.0
3.36.0
+5 -4
View File
@@ -285,6 +285,7 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
@@ -501,12 +502,12 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
#
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
!IF "$(PLATFORM)"=="x86"
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
!ELSE
!IFNDEF PLATFORM
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
!ELSE
CORE_CCONV_OPTS =
SHELL_CCONV_OPTS =
+1 -1
View File
@@ -105,7 +105,7 @@ may be specified in this manner as some require the amalgamation to be built
with them enabled (see http://www.sqlite.org/compile.html). For example, the
following will work:
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1"
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
However, the following will not compile unless the amalgamation was built
with it enabled:
+15
View File
@@ -173,6 +173,21 @@ else
fi
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# --enable-json1
#
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
[--enable-json1], [include json1 support [default=yes]])],
[],[enable_json1=yes])
AC_MSG_CHECKING([JSON functions])
if test x"$enable_json1" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
AC_MSG_RESULT([enabled])
else
AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# --enable-rtree
#
+74 -109
View File
@@ -11,6 +11,8 @@
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: Makefile.in,v 1.59 2005/07/26 19:17:02 mdejong Exp $
#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
@@ -58,8 +60,6 @@ PKG_HEADERS = @PKG_HEADERS@
#========================================================================
PKG_LIB_FILE = @PKG_LIB_FILE@
PKG_LIB_FILE8 = @PKG_LIB_FILE8@
PKG_LIB_FILE9 = @PKG_LIB_FILE9@
PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE)
@@ -73,11 +73,10 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
datarootdir = @datarootdir@
runstatedir = @runstatedir@
datadir = @datadir@
mandir = @mandir@
includedir = @includedir@
DESTDIR =
@@ -86,25 +85,24 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
top_builddir = @abs_top_builddir@
top_builddir = .
INSTALL_OPTIONS =
INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
CC = @CC@
CCLD = @CCLD@
CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
CFLAGS_WARNING = @CFLAGS_WARNING@
CLEANFILES = @CLEANFILES@
EXEEXT = @EXEEXT@
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
MAKE_LIB = @MAKE_LIB@
MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
MAKE_STUB_LIB = @MAKE_STUB_LIB@
OBJEXT = @OBJEXT@
RANLIB = @RANLIB@
@@ -119,6 +117,8 @@ TCL_SRC_DIR = @TCL_SRC_DIR@
#TK_BIN_DIR = @TK_BIN_DIR@
#TK_SRC_DIR = @TK_SRC_DIR@
# This is no longer necessary even for packages that use private Tcl headers
#TCL_TOP_DIR_NATIVE = @TCL_TOP_DIR_NATIVE@
# Not used, but retained for reference of what libs Tcl required
#TCL_LIBS = @TCL_LIBS@
@@ -132,52 +132,41 @@ TCL_SRC_DIR = @TCL_SRC_DIR@
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH = $(top_builddir)
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
@LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
TCLLIBPATH="$(TCLLIBPATH)"
# TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
TCLSH_PROG = @TCLSH_PROG@
TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
TCLSH = $(TCLSH_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
#WISH = $(TCLSH_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I. -I$(srcdir)/..
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I$(srcdir)/..
#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
PKG_CFLAGS = @PKG_CFLAGS@
# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.ac checks for the necessary components
# must make sure that configure.in checks for the necessary components
# that your library may use. TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS = @DEFS@ $(PKG_CFLAGS)
# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
CLEANFILES = @CLEANFILES@
CPPFLAGS = @CPPFLAGS@
LIBS = @PKG_LIBS@ @LIBS@
AR = @AR@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \
$(CFLAGS_DEFAULT) $(CFLAGS_WARNING) $(SHLIB_CFLAGS) $(CFLAGS)
GDB = gdb
VALGRIND = valgrind
VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
--leak-check=yes --show-reachable=yes -v
.SUFFIXES: .c .$(OBJEXT)
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
#========================================================================
# Start of user-definable TARGETS section
@@ -185,7 +174,7 @@ VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
#========================================================================
# TEA TARGETS. Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes executable programs and
# independent files, and the "binaries:" target inclues executable programs and
# platform-dependent libraries. Modify these targets so that they install
# the various pieces of your package. The make and install rules
# for the BINARIES that you specified above have already been done.
@@ -204,6 +193,7 @@ binaries: $(BINARIES)
libraries:
#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
@@ -226,11 +216,11 @@ install-binaries: binaries install-lib-binaries install-bin-binaries
#========================================================================
install-libraries: libraries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(includedir)"
@mkdir -p $(DESTDIR)$(includedir)
@echo "Installing header files in $(DESTDIR)$(includedir)"
@list='$(PKG_HEADERS)'; for i in $$list; do \
echo "Installing $(srcdir)/$$i" ; \
$(INSTALL_DATA) $(srcdir)/$$i "$(DESTDIR)$(includedir)" ; \
$(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
done;
#========================================================================
@@ -239,11 +229,12 @@ install-libraries: libraries
#========================================================================
install-doc: doc
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(mandir)/mann"
@mkdir -p $(DESTDIR)$(mandir)/mann
@echo "Installing documentation in $(DESTDIR)$(mandir)"
@list='$(srcdir)/doc/*.n'; for i in $$list; do \
echo "Installing $$i"; \
$(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/mann" ; \
rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
done
test: binaries libraries
@@ -253,21 +244,7 @@ shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
$(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
gdb-test: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(GDB) \
--args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
$(TESTFLAGS) -singleproc 1 \
-load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
[list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]"
valgrind: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
depend:
@@ -306,70 +283,49 @@ $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================
VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
.c.@OBJEXT@:
$(COMPILE) -c `@CYGPATH@ $<` -o $@
tclsample.@OBJEXT@: sampleUuid.h
$(srcdir)/manifest.uuid:
printf "git-" >$(srcdir)/manifest.uuid
(cd $(srcdir); git rev-parse HEAD >>$(srcdir)/manifest.uuid || \
(printf "svn-r" >$(srcdir)/manifest.uuid ; \
svn info --show-item last-changed-revision >>$(srcdir)/manifest.uuid) || \
printf "unknown" >$(srcdir)/manifest.uuid)
sampleUuid.h: $(srcdir)/manifest.uuid
echo "#define SAMPLE_VERSION_UUID \\" >$@
cat $(srcdir)/manifest.uuid >>$@
echo "" >>$@
#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================
#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
COMPRESS = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean $(srcdir)/manifest.uuid
$(INSTALL_DATA_DIR) $(DIST_DIR)
dist: dist-clean
mkdir -p $(DIST_DIR)
cp -p $(srcdir)/README* $(srcdir)/license* \
$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
$(DIST_DIR)/
chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
# TEA files
$(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
$(DIST_DIR)/
$(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
for i in $(srcdir)/*.[ch]; do \
if [ -f $$i ]; then \
cp -p $$i $(DIST_DIR)/ ; \
fi; \
done;
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
$(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
$(srcdir)/manifest.uuid \
$(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
$(DIST_DIR)/tclconfig/
mkdir $(DIST_DIR)/tclconfig
cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
$(DIST_DIR)/tclconfig/
chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
chmod +x $(DIST_DIR)/tclconfig/install-sh
# Extension files
$(DIST_INSTALL_DATA) \
$(srcdir)/ChangeLog \
$(srcdir)/README.sha \
$(srcdir)/license.terms \
$(srcdir)/README \
$(srcdir)/pkgIndex.tcl.in \
$(DIST_DIR)/
list='demos doc generic library macosx tests unix win'; \
list='demos doc generic library mac tests unix win'; \
for p in $$list; do \
if test -d $(srcdir)/$$p ; then \
$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
$(DIST_INSTALL_DATA) $(srcdir)/$$p/* $(DIST_DIR)/$$p/; \
mkdir $(DIST_DIR)/$$p; \
cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
fi; \
done
@@ -381,10 +337,10 @@ dist: dist-clean $(srcdir)/manifest.uuid
#========================================================================
# Don't modify the file to clean here. Instead, set the "CLEANFILES"
# variable in configure.ac
# variable in configure.in
#========================================================================
clean:
clean:
-test -z "$(BINARIES)" || rm -f $(BINARIES)
-rm -f *.$(OBJEXT) core *.core
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
@@ -392,7 +348,7 @@ clean:
distclean: clean
-rm -f *.tab.c
-rm -f $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log config.status
-rm -f config.h config.cache config.log config.status
#========================================================================
# Install binary object libraries. On Windows this includes both .dll and
@@ -406,17 +362,25 @@ distclean: clean
#========================================================================
install-lib-binaries: binaries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(pkglibdir)"
@mkdir -p $(DESTDIR)$(pkglibdir)
@list='$(lib_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p "$(DESTDIR)$(pkglibdir)/$$p"; \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
if test "x$$stub" = "xstub"; then \
echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
else \
echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
fi; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
if test -f $$lib; then \
echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
$(INSTALL_DATA) $$lib "$(DESTDIR)$(pkglibdir)/$$lib"; \
$(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
fi; \
fi; \
fi; \
@@ -425,12 +389,12 @@ install-lib-binaries: binaries
if test -f $(srcdir)/$$p; then \
destp=`basename $$p`; \
echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
$(INSTALL_DATA) $(srcdir)/$$p "$(DESTDIR)$(pkglibdir)/$$destp"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
fi; \
done
@if test "x$(SHARED_BUILD)" = "x1"; then \
echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
$(INSTALL_DATA) pkgIndex.tcl "$(DESTDIR)$(pkglibdir)"; \
$(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
fi
#========================================================================
@@ -443,32 +407,33 @@ install-lib-binaries: binaries
#========================================================================
install-bin-binaries: binaries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(bindir)"
@mkdir -p $(DESTDIR)$(bindir)
@list='$(bin_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
$(INSTALL_PROGRAM) $$p "$(DESTDIR)$(bindir)/$$p"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
fi; \
done
.SUFFIXES: .c .$(OBJEXT)
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
uninstall-binaries:
list='$(lib_BINARIES)'; for p in $$list; do \
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
p=`basename $$p`; \
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
list='$(bin_BINARIES)'; for p in $$list; do \
rm -f "$(DESTDIR)$(bindir)/$$p"; \
rm -f $(DESTDIR)$(bindir)/$$p; \
done
.PHONY: all binaries clean depend distclean doc install libraries test
.PHONY: gdb gdb-test valgrind valgrindshell
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
+34 -60
View File
@@ -2,9 +2,11 @@
dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#
# RCS: @(#) $Id: configure.in,v 1.43 2005/07/26 19:17:05 mdejong Exp $
#-----------------------------------------------------------------------
# Sample configure.ac for Tcl Extensions. The only places you should
# Sample configure.in for Tcl Extensions. The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------
@@ -15,11 +17,9 @@ dnl to configure the system for the local environment.
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
# so that we create the export library with the dll.
#-----------------------------------------------------------------------
AC_INIT([sqlite],[3.40.0])
AC_INIT([sqlite], [3.32.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -27,7 +27,7 @@ AC_INIT([sqlite],[3.40.0])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
TEA_INIT()
TEA_INIT([3.9])
AC_CONFIG_AUX_DIR(tclconfig)
@@ -55,8 +55,8 @@ TEA_PREFIX
#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC and a few others to create the basic setup
# necessary to compile executables.
# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
# the basic setup necessary to compile executables.
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
@@ -73,19 +73,11 @@ TEA_SETUP_COMPILER
TEA_ADD_SOURCES([tclsqlite3.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([])
TEA_ADD_INCLUDES([-I\"`\${CYGPATH} \${srcdir}/generic`\"])
TEA_ADD_LIBS([])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS5=1])
TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_GEOPOLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_MATH_FUNCTIONS=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DESERIALIZE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBPAGE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_BYTECODE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])
@@ -107,31 +99,6 @@ if test x$with_system_sqlite != xno; then
LIBS="$LIBS -lsqlite3"])])
fi
#--------------------------------------------------------------------
# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
# Ensure no empty if clauses
:
#TEA_ADD_SOURCES([win/winFile.c])
#TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
# Ensure no empty else clauses
:
#TEA_ADD_SOURCES([unix/unixFile.c])
#TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need. Extension authors should try very
@@ -184,6 +151,28 @@ TEA_CONFIG_CFLAGS
TEA_ENABLE_SYMBOLS
#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library. If you
# can't for some reason, remove this definition. If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library. Add Tk too if necessary.
#--------------------------------------------------------------------
AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
#--------------------------------------------------------------------
# Redefine fdatasync as fsync on systems that lack fdatasync
#--------------------------------------------------------------------
#
#AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
# Check for library functions that SQLite can optionally use.
AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
AC_FUNC_STRERROR_R
#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
@@ -204,24 +193,9 @@ TEA_PROG_TCLSH
#TEA_PROG_WISH
#--------------------------------------------------------------------
# Setup a *Config.sh.in configuration file.
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in. Include these here.
#--------------------------------------------------------------------
#TEA_EXPORT_CONFIG([sample])
#AC_SUBST(SAMPLE_VAR)
#--------------------------------------------------------------------
# Specify files to substitute AC variables in. You may alternatively
# have a special pkgIndex.tcl.in or other files which require
# substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_CONFIG_FILES([Makefile pkgIndex.tcl])
#AC_CONFIG_FILES([sampleConfig.sh])
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the files
# specified with AC_CONFIG_FILES.
#--------------------------------------------------------------------
AC_OUTPUT
AC_OUTPUT([Makefile pkgIndex.tcl])
+6 -9
View File
@@ -1,10 +1,7 @@
# -*- tcl -*-
# Tcl package index file, version 1.1
#
if {[package vsatisfies [package provide Tcl] 9.0-]} {
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE9@] sqlite3]
} else {
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE8@] sqlite3]
}
# Tcl package index file
#
# Note sqlite*3* init specifically
#
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE@] Sqlite3]
File diff suppressed because it is too large Load Diff
+1 -12
View File
@@ -251,18 +251,7 @@ INCLUDES = $(SQL_INCLUDES) $(TCL_INCLUDES) -I"$(WINDIR)" \
-I"$(GENERICDIR)" -I"$(ROOT)\.."
BASE_CLFAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES) \
-DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
-DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1 \
-DSQLITE_ENABLE_FTS4=1 \
-DSQLITE_ENABLE_FTS5=1 \
-DSQLITE_3_SUFFIX_ONLY=1 \
-DSQLITE_ENABLE_RTREE=1 \
-DSQLITE_ENABLE_GEOPOLY=1 \
-DSQLITE_ENABLE_MATH_FUNCTIONS=1 \
-DSQLITE_ENABLE_DESERIALIZE=1 \
-DSQLITE_ENABLE_DBPAGE_VTAB=1 \
-DSQLITE_ENABLE_BYTECODE_VTAB=1 \
-DSQLITE_ENABLE_DBSTAT_VTAB=1
-DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1
CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE -DSQLITE_ENABLE_FTS3=1
TCL_CFLAGS = -DBUILD_sqlite -DUSE_TCL_STUBS \
-DPACKAGE_VERSION="\"$(DOTVERSION)\"" $(BASE_CLFAGS) \
+47 -168
View File
@@ -14,10 +14,13 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#ifdef _MSC_VER
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_REG
#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#endif
#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>
@@ -36,15 +39,15 @@
#endif
/* protos */
static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(char **options, int count);
static int CheckForLinkerFeature(const char *option);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static const char *GetVersionFromFile(const char *filename, const char *match);
static DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
@@ -56,8 +59,8 @@ typedef struct {
char buffer[STATICBUFFERSIZE];
} pipeinfo;
pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
/*
* exitcodes: 0 == no, 1 == yes, 2 == error
@@ -71,7 +74,6 @@ main(
char msg[300];
DWORD dwWritten;
int chars;
const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
@@ -100,16 +102,16 @@ main(
}
return CheckForCompilerFeature(argv[2]);
case 'l':
if (argc < 3) {
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
"usage: %s -l <linker option>\n"
"Tests for whether link.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForLinkerFeature(&argv[2], argc-2);
return CheckForLinkerFeature(argv[2]);
case 'f':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
@@ -151,13 +153,8 @@ main(
&dwWritten, NULL);
return 0;
}
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
if (s && *s) {
printf("%s\n", s);
return 0;
} else
return 1; /* Version not found. Return non-0 exit code */
printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
return 0;
case 'Q':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
@@ -169,18 +166,6 @@ main(
return 2;
}
return QualifyPath(argv[2]);
case 'L':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -L keypath\n"
"Emit the fully qualified path of directory containing keypath\n"
"exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return LocateDependency(argv[2]);
}
}
chars = snprintf(msg, sizeof(msg) - 1,
@@ -275,7 +260,7 @@ CheckForCompilerFeature(
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
@@ -328,8 +313,7 @@ CheckForCompilerFeature(
static int
CheckForLinkerFeature(
char **options,
int count)
const char *option)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
@@ -338,8 +322,7 @@ CheckForLinkerFeature(
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
int i;
char cmdline[255];
char cmdline[100];
hProcess = GetCurrentProcess();
@@ -385,11 +368,7 @@ CheckForLinkerFeature(
* Append our option for testing.
*/
for (i = 0; i < count; i++) {
lstrcat(cmdline, " \"");
lstrcat(cmdline, options[i]);
lstrcat(cmdline, "\"");
}
lstrcat(cmdline, option);
ok = CreateProcess(
NULL, /* Module name. */
@@ -409,7 +388,7 @@ CheckForLinkerFeature(
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
@@ -454,9 +433,7 @@ CheckForLinkerFeature(
return !(strstr(Out.buffer, "LNK1117") != NULL ||
strstr(Err.buffer, "LNK1117") != NULL ||
strstr(Out.buffer, "LNK4044") != NULL ||
strstr(Err.buffer, "LNK4044") != NULL ||
strstr(Out.buffer, "LNK4224") != NULL ||
strstr(Err.buffer, "LNK4224") != NULL);
strstr(Err.buffer, "LNK4044") != NULL);
}
static DWORD WINAPI
@@ -502,9 +479,9 @@ IsIn(
static const char *
GetVersionFromFile(
const char *filename,
const char *match,
int numdots)
const char *match)
{
size_t cbBuffer = 100;
static char szBuffer[100];
char *szResult = NULL;
FILE *fp = fopen(filename, "rt");
@@ -514,17 +491,16 @@ GetVersionFromFile(
* Read data until we see our match string.
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
LPSTR p, q;
p = strstr(szBuffer, match);
if (p != NULL) {
/*
* Skip to first digit after the match.
* Skip to first digit.
*/
p += strlen(match);
while (*p && !isdigit((unsigned char)*p)) {
while (*p && !isdigit(*p)) {
++p;
}
@@ -533,13 +509,13 @@ GetVersionFromFile(
*/
q = p;
while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
&& !strchr("ab", q[-1])) || --numdots))) {
while (*q && (isalnum(*q) || *q == '.')) {
++q;
}
*q = 0;
szResult = p;
memcpy(szBuffer, p, q - p);
szBuffer[q-p] = 0;
szResult = szBuffer;
break;
}
}
@@ -562,7 +538,7 @@ typedef struct list_item_t {
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
list_item_t *itemPtr = malloc(sizeof(list_item_t));
if (itemPtr) {
itemPtr->key = strdup(key);
itemPtr->value = strdup(value);
@@ -611,7 +587,9 @@ SubstituteFile(
const char *substitutions,
const char *filename)
{
size_t cbBuffer = 1024;
static char szBuffer[1024], szCopy[1024];
char *szResult = NULL;
list_item_t *substPtr = NULL;
FILE *fp, *sp;
@@ -624,7 +602,7 @@ SubstituteFile(
sp = fopen(substitutions, "rt");
if (sp != NULL) {
while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
while (fgets(szBuffer, cbBuffer, sp) != NULL) {
unsigned char *ks, *ke, *vs, *ve;
ks = (unsigned char*)szBuffer;
while (ks && *ks && isspace(*ks)) ++ks;
@@ -641,7 +619,7 @@ SubstituteFile(
}
/* debug: dump the list */
#ifndef NDEBUG
#ifdef _DEBUG
{
int n = 0;
list_item_t *p = NULL;
@@ -650,12 +628,12 @@ SubstituteFile(
}
}
#endif
/*
* Run the substitutions over each line of the input
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr) {
char *m = strstr(szBuffer, p->key);
@@ -672,26 +650,15 @@ SubstituteFile(
memcpy(szBuffer, szCopy, sizeof(szCopy));
}
}
printf("%s", szBuffer);
printf(szBuffer);
}
list_free(&substPtr);
}
fclose(fp);
return 0;
}
BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
DWORD pathAttr = GetFileAttributes(szPath);
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* QualifyPath --
*
@@ -705,105 +672,17 @@ QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
char szTmp[MAX_PATH + 1];
char *p;
GetCurrentDirectory(MAX_PATH, szCwd);
while ((p = strchr(szPath, '/')) && *p)
*p = '\\';
PathCombine(szTmp, szCwd, szPath);
PathCanonicalize(szCwd, szTmp);
printf("%s\n", szCwd);
return 0;
}
/*
* Implements LocateDependency for a single directory. See that command
* for an explanation.
* Returns 0 if found after printing the directory.
* Returns 1 if not found but no errors.
* Returns 2 on any kind of error
* Basically, these are used as exit codes for the process.
*/
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
HANDLE hSearch;
char path[MAX_PATH+1];
size_t dirlen;
int keylen, ret;
WIN32_FIND_DATA finfo;
if (dir == NULL || keypath == NULL)
return 2; /* Have no real error reporting mechanism into nmake */
dirlen = strlen(dir);
if ((dirlen + 3) > sizeof(path))
return 2;
strncpy(path, dir, dirlen);
strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
keylen = strlen(keypath);
#if 0 /* This function is not available in Visual C++ 6 */
/*
* Use numerics 0 -> FindExInfoStandard,
* 1 -> FindExSearchLimitToDirectories,
* as these are not defined in Visual C++ 6
*/
hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
hSearch = FindFirstFile(path, &finfo);
#endif
if (hSearch == INVALID_HANDLE_VALUE)
return 1; /* Not found */
/* Loop through all subdirs checking if the keypath is under there */
ret = 1; /* Assume not found */
do {
int sublen;
/*
* We need to check it is a directory despite the
* FindExSearchLimitToDirectories in the above call. See SDK docs
*/
if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
continue;
sublen = strlen(finfo.cFileName);
if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
continue; /* Path does not fit, assume not matched */
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
ret = 0;
break;
}
} while (FindNextFile(hSearch, &finfo));
FindClose(hSearch);
return ret;
}
/*
* LocateDependency --
*
* Locates a dependency for a package.
* keypath - a relative path within the package directory
* that is used to confirm it is the correct directory.
* The search path for the package directory is currently only
* the parent and grandparent of the current working directory.
* If found, the command prints
* name_DIRPATH=<full path of located directory>
* and returns 0. If not found, does not print anything and returns 1.
*/
static int LocateDependency(const char *keypath)
{
size_t i;
int ret;
static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
ret = LocateDependencyHelper(paths[i], keypath);
if (ret == 0)
return ret;
}
return ret;
}
/*
* Local variables:
* mode: c
+7 -18
View File
@@ -1,4 +1,4 @@
/* sqlite_cfg.h.in. Generated from configure.ac by autoheader. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
@@ -45,16 +45,16 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `pread' function. */
/* Define to 1 if you have the pread() function. */
#undef HAVE_PREAD
/* Define to 1 if you have the `pread64' function. */
/* Define to 1 if you have the pread64() function. */
#undef HAVE_PREAD64
/* Define to 1 if you have the `pwrite' function. */
/* Define to 1 if you have the pwrite() function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the `pwrite64' function. */
/* Define to 1 if you have the pwrite64() function. */
#undef HAVE_PWRITE64
/* Define to 1 if you have the <stdint.h> header file. */
@@ -63,7 +63,7 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchrnul' function. */
/* Define to 1 if you have the strchrnul() function */
#undef HAVE_STRCHRNUL
/* Define to 1 if you have the <strings.h> header file. */
@@ -99,12 +99,9 @@
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the `utime' function. */
/* Define to 1 if you have the utime() library function. */
#undef HAVE_UTIME
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
@@ -121,20 +118,12 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
Vendored
+46 -58
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.40.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.36.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.40.0'
PACKAGE_STRING='sqlite 3.40.0'
PACKAGE_VERSION='3.36.0'
PACKAGE_STRING='sqlite 3.36.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -770,7 +770,6 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
BUILD_CFLAGS
AMALGAMATION_LINE_MACROS
USE_GCOV
OPT_FEATURE_FLAGS
HAVE_ZLIB
@@ -905,13 +904,13 @@ enable_debug
enable_amalgamation
enable_load_extension
enable_math
enable_json
enable_all
enable_memsys5
enable_memsys3
enable_fts3
enable_fts4
enable_fts5
enable_json1
enable_update_limit
enable_geopoly
enable_rtree
@@ -1468,7 +1467,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.40.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.36.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1533,7 +1532,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.40.0:";;
short | recursive ) echo "Configuration of sqlite 3.36.0:";;
esac
cat <<\_ACEOF
@@ -1560,13 +1559,13 @@ Optional Features:
--disable-load-extension
Disable loading of external extensions
--disable-math Disable math functions
--disable-json Disable JSON functions
--enable-all Enable FTS4, FTS5, Geopoly, RTree, Sessions
--enable-all Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions
--enable-memsys5 Enable MEMSYS5
--enable-memsys3 Enable MEMSYS3
--enable-fts3 Enable the FTS3 extension
--enable-fts4 Enable the FTS4 extension
--enable-fts5 Enable the FTS5 extension
--enable-json1 Enable the JSON1 extension
--enable-update-limit Enable the UPDATE/DELETE LIMIT clause
--enable-geopoly Enable the GEOPOLY extension
--enable-rtree Enable the RTREE extension
@@ -1661,7 +1660,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.40.0
sqlite configure 3.36.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2080,7 +2079,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.40.0, which was
It was created by sqlite $as_me 3.36.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3938,13 +3937,13 @@ if ${lt_cv_nm_interface+:} false; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3941: $ac_compile\"" >&5)
(eval echo "\"\$as_me:3940: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
(eval echo "\"\$as_me:3944: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval echo "\"\$as_me:3943: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
(eval echo "\"\$as_me:3947: output\"" >&5)
(eval echo "\"\$as_me:3946: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5150,7 +5149,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5153 "configure"' > conftest.$ac_ext
echo '#line 5152 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6675,11 +6674,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6678: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6677: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6682: \$? = $ac_status" >&5
echo "$as_me:6681: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7014,11 +7013,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7017: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7016: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7021: \$? = $ac_status" >&5
echo "$as_me:7020: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7119,11 +7118,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7122: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7121: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7126: \$? = $ac_status" >&5
echo "$as_me:7125: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7174,11 +7173,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7177: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7176: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7181: \$? = $ac_status" >&5
echo "$as_me:7180: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9554,7 +9553,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9557 "configure"
#line 9556 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9650,7 +9649,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9653 "configure"
#line 9652 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11497,24 +11496,6 @@ fi
fi
##########
# Do we want to support JSON functions
#
# Check whether --enable-json was given.
if test "${enable_json+set}" = set; then :
enableval=$enable_json;
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON functions" >&5
$as_echo_n "checking whether to support JSON functions... " >&6; }
if test "$enable_json" = "no"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
########
# The --enable-all argument is short-hand to enable
@@ -11719,6 +11700,24 @@ else
$as_echo "no" >&6; }
fi
#########
# See whether we should enable JSON1
# Check whether --enable-json1 was given.
if test "${enable_json1+set}" = set; then :
enableval=$enable_json1;
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON" >&5
$as_echo_n "checking whether to support JSON... " >&6; }
if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
@@ -11861,21 +11860,10 @@ else
fi
#########
# Enable/disabled amalagamation line macros
########
AMALGAMATION_LINE_MACROS=--linemacros=0
if test "${amalgamation_line_macros}" = "yes" ; then
AMALGAMATION_LINE_MACROS=--linemacros=1
fi
if test "${amalgamation_line_macros}" = "no" ; then
AMALGAMATION_LINE_MACROS=--linemacros=0
fi
#########
# Output the config header
ac_config_headers="$ac_config_headers sqlite_cfg.h"
ac_config_headers="$ac_config_headers config.h"
#########
@@ -12390,7 +12378,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.40.0, which was
This file was extended by sqlite $as_me 3.36.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12456,7 +12444,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.40.0
sqlite config.status 3.36.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -12838,7 +12826,7 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"sqlite_cfg.h") CONFIG_HEADERS="$CONFIG_HEADERS sqlite_cfg.h" ;;
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;;
+13 -25
View File
@@ -605,24 +605,12 @@ else
AC_SEARCH_LIBS(ceil, m)
fi
##########
# Do we want to support JSON functions
#
AC_ARG_ENABLE(json,
AC_HELP_STRING([--disable-json],[Disable JSON functions]))
AC_MSG_CHECKING([whether to support JSON functions])
if test "$enable_json" = "no"; then
AC_MSG_RESULT([no])
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON"
else
AC_MSG_RESULT([yes])
fi
########
# The --enable-all argument is short-hand to enable
# multiple extensions.
AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all],
[Enable FTS4, FTS5, Geopoly, RTree, Sessions]))
[Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions]))
##########
# Do we want to support memsys3 and/or memsys5
@@ -678,6 +666,17 @@ else
AC_MSG_RESULT([no])
fi
#########
# See whether we should enable JSON1
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension]))
AC_MSG_CHECKING([whether to support JSON])
if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
#########
# See whether we should enable the LIMIT clause on UPDATE and DELETE
# statements.
@@ -792,21 +791,10 @@ else
fi
AC_SUBST(USE_GCOV)
#########
# Enable/disabled amalagamation line macros
########
AMALGAMATION_LINE_MACROS=--linemacros=0
if test "${amalgamation_line_macros}" = "yes" ; then
AMALGAMATION_LINE_MACROS=--linemacros=1
fi
if test "${amalgamation_line_macros}" = "no" ; then
AMALGAMATION_LINE_MACROS=--linemacros=0
fi
AC_SUBST(AMALGAMATION_LINE_MACROS)
#########
# Output the config header
AC_CONFIG_HEADERS(sqlite_cfg.h)
AC_CONFIG_HEADERS(config.h)
#########
# Generate the output files.
-144
View File
@@ -1,144 +0,0 @@
# JSON Functions Enhancements (2022)
This document summaries enhancements to the SQLite JSON support added in
early 2022.
## 1.0 Change summary:
1. New **->** and **->>** operators that work like MySQL and PostgreSQL (PG).
2. JSON functions are built-in rather than being an extension. They
are included by default, but can be omitted using the
-DSQLITE_OMIT_JSON compile-time option.
## 2.0 New operators **->** and **->>**
The SQLite language adds two new binary operators **->** and **->>**.
Both operators are similar to json_extract(). The left operand is
JSON and the right operand is a JSON path expression (possibly abbreviated
for compatibility with PG - see below). So they are similar to a
two-argument call to json_extract().
The difference between -> and ->> (and json_extract()) is as follows:
* The -> operator always returns JSON.
* The ->> operator converts the answer into a primitive SQL datatype
such as TEXT, INTEGER, REAL, or NULL. If a JSON object or array
is selected, that object or array is rendered as text. If a JSON
value is selected, that value is converted into its corresponding
SQL type
* The json_extract() interface returns JSON when a JSON object or
array is selected, or a primitive SQL datatype when a JSON value
is selected. This is different from MySQL, in which json_extract()
always returns JSON, but the difference is retained because it has
worked that way for 6 years and changing it now would likely break
a lot of legacy code.
In MySQL and PG, the ->> operator always returns TEXT (or NULL) and never
INTEGER or REAL. This is due to limitations in the type handling capabilities
of those systems. In MySQL and PG, the result type a function or operator
may only depend on the type of its arguments, never the value of its arguments.
But the underlying JSON type depends on the value of the JSON path
expression, not the type of the JSON path expression (which is always TEXT).
Hence, the result type of ->> in MySQL and PG is unable to vary according
to the type of the JSON value being extracted.
The type system in SQLite is more general. Functions in SQLite are able
to return different datatypes depending on the value of their arguments.
So the ->> operator in SQLite is able to return TEXT, INTEGER, REAL, or NULL
depending on the JSON type of the value being extracted. This means that
the behavior of the ->> is slightly different in SQLite versus MySQL and PG
in that it will sometimes return INTEGER and REAL values, depending on its
inputs. It is possible to implement the ->> operator in SQLite so that it
always operates exactly like MySQL and PG and always returns TEXT or NULL,
but I have been unable to think of any situations where returning the
actual JSON value this would cause problems, so I'm including the enhanced
functionality in SQLite.
The table below attempts to summarize the differences between the
-> and ->> operators and the json_extract() function, for SQLite, MySQL,
and PG. JSON values are shown using their SQL text representation but
in a bold font.
<table border=1 cellpadding=5 cellspacing=0>
<tr><th>JSON<th>PATH<th>-&gt; operator<br>(all)<th>-&gt;&gt; operator<br>(MySQL/PG)
<th>-&gt;&gt; operator<br>(SQLite)<th>json_extract()<br>(SQLite)
<tr><td> **'{"a":123}'** <td>'$.a'<td> **'123'** <td> '123' <td> 123 <td> 123
<tr><td> **'{"a":4.5}'** <td>'$.a'<td> **'4.5'** <td> '4.5' <td> 4.5 <td> 4.5
<tr><td> **'{"a":"xyz"}'** <td>'$.a'<td> **'"xyz"'** <td> 'xyz' <td> 'xyz' <td> 'xyz'
<tr><td> **'{"a":null}'** <td>'$.a'<td> **'null'** <td> NULL <td> NULL <td> NULL
<tr><td> **'{"a":[6,7,8]}'** <td>'$.a'<td> **'[6,7,8]'** <td> '[6,7,8]' <td> '[6,7,8]' <td> **'[6,7,8]'**
<tr><td> **'{"a":{"x":9}}'** <td>'$.a'<td> **'{"x":9}'** <td> '{"x":9}' <td> '{"x":9}' <td> **'{"x":9}'**
<tr><td> **'{"b":999}'** <td>'$.a'<td> NULL <td> NULL <td> NULL <td> NULL
</table>
Important points about the table above:
* The -> operator always returns either JSON or NULL.
* The ->> operator never returns JSON. It always returns TEXT or NULL, or in the
case of SQLite, INTEGER or REAL.
* The MySQL json_extract() function works exactly the same
as the MySQL -> operator.
* The SQLite json_extract() operator works like -> for JSON objects and
arrays, and like ->> for JSON values.
* The -> operator works the same for all systems.
* The only difference in ->> between SQLite and other systems is that
when the JSON value is numeric, SQLite returns a numeric SQL value,
whereas the other systems return a text representation of the numeric
value.
### 2.1 Abbreviated JSON path expressions for PG compatibility
The table above always shows the full JSON path expression: '$.a'. But
PG does not accept this syntax. PG only allows a single JSON object label
name or a single integer array index. In order to provide compatibility
with PG, The -> and ->> operators in SQLite are extended to also support
a JSON object label or an integer array index for the right-hand side
operand, in addition to a full JSON path expression.
Thus, a -> or ->> operator that works on MySQL will work in
SQLite. And a -> or ->> operator that works in PG will work in SQLite.
But because SQLite supports the union of the disjoint capabilities of
MySQL and PG, there will always be -> and ->> operators that work in
SQLite that do not work in one of MySQL and PG. This is an unavoidable
consequence of the different syntax for -> and ->> in MySQL and PG.
In the following table, assume that "value1" is a JSON object and
"value2" is a JSON array.
<table border=1 cellpadding=5 cellspacing=0>
<tr><th>SQL expression <th>Works in MySQL?<th>Works in PG?<th>Works in SQLite
<tr><td>value1-&gt;'$.a' <td> yes <td> no <td> yes
<tr><td>value1-&gt;'a' <td> no <td> yes <td> yes
<tr><td>value2-&gt;'$[2]' <td> yes <td> no <td> yes
<tr><td>value2-&gt;2 <td> no <td> yes <td> yes
</table>
The abbreviated JSON path expressions only work for the -> and ->> operators
in SQLite. The json_extract() function, and all other built-in SQLite
JSON functions, continue to require complete JSON path expressions for their
PATH arguments.
## 3.0 JSON moved into the core
The JSON interface is now moved into the SQLite core.
When originally written in 2015, the JSON functions were an extension
that could be optionally included at compile-time, or loaded at run-time.
The implementation was in a source file named ext/misc/json1.c in the
source tree. JSON functions were only compiled in if the
-DSQLITE_ENABLE_JSON1 compile-time option was used.
After these enhancements, the JSON functions are now built-ins.
The source file that implements the JSON functions is moved to src/json.c.
No special compile-time options are needed to load JSON into the build.
Instead, there is a new -DSQLITE_OMIT_JSON compile-time option to leave
them out.
+2 -12
View File
@@ -196,7 +196,7 @@ do_setup_rec_test $tn.9.1 {
} {
SELECT * FROM "t t" WHERE a=?
} {
CREATE INDEX "t t_idx_00000061" ON "t t"(a);
CREATE INDEX 't t_idx_00000061' ON 't t'(a);
SEARCH t t USING INDEX t t_idx_00000061 (a=?)
}
@@ -205,7 +205,7 @@ do_setup_rec_test $tn.9.2 {
} {
SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
} {
CREATE INDEX "t t_idx_00000062" ON "t t"(b);
CREATE INDEX 't t_idx_00000062' ON 't t'(b);
SEARCH t t USING INDEX t t_idx_00000062 (b>? AND b<?)
}
@@ -391,16 +391,6 @@ do_setup_rec_test $tn.18.1 {
SEARCH SomeObject USING COVERING INDEX SomeObject_idx_00000078 (x=?)
}
do_setup_rec_test $tn.19.0 {
CREATE TABLE t1("index");
} {
SELECT * FROM t1 ORDER BY "index";
} {
CREATE INDEX t1_idx_01a7214e ON t1('index');
SCAN t1 USING COVERING INDEX t1_idx_01a7214e
}
}
proc do_candidates_test {tn sql res} {
+26 -112
View File
@@ -15,23 +15,6 @@
#include <string.h>
#include <stdio.h>
#if !defined(SQLITE_AMALGAMATION)
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
#endif
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
#elif !defined(NDEBUG)
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
#endif
#endif /* !defined(SQLITE_AMALGAMATION) */
#ifndef SQLITE_OMIT_VIRTUALTABLE
typedef sqlite3_int64 i64;
@@ -697,31 +680,21 @@ static int idxGetTableInfo(
){
sqlite3_stmt *p1 = 0;
int nCol = 0;
int nTab;
int nByte;
int nTab = STRLEN(zTab);
int nByte = sizeof(IdxTable) + nTab + 1;
IdxTable *pNew = 0;
int rc, rc2;
char *pCsr = 0;
int nPk = 0;
*ppOut = 0;
if( zTab==0 ) return SQLITE_ERROR;
nTab = STRLEN(zTab);
nByte = sizeof(IdxTable) + nTab + 1;
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
const char *zColSeq = 0;
if( zCol==0 ){
rc = SQLITE_ERROR;
break;
}
nByte += 1 + STRLEN(zCol);
rc = sqlite3_table_column_metadata(
db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
);
if( zColSeq==0 ) zColSeq = "binary";
nByte += 1 + STRLEN(zColSeq);
nByte += 1 + STRLEN(zCol);
nCol++;
nPk += (sqlite3_column_int(p1, 5)>0);
}
@@ -741,23 +714,19 @@ static int idxGetTableInfo(
nCol = 0;
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
const char *zColSeq = 0;
int nCopy;
if( zCol==0 ) continue;
nCopy = STRLEN(zCol) + 1;
int nCopy = STRLEN(zCol) + 1;
pNew->aCol[nCol].zName = pCsr;
pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
memcpy(pCsr, zCol, nCopy);
pCsr += nCopy;
rc = sqlite3_table_column_metadata(
db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
);
if( rc==SQLITE_OK ){
if( zColSeq==0 ) zColSeq = "binary";
nCopy = STRLEN(zColSeq) + 1;
nCopy = STRLEN(zCol) + 1;
pNew->aCol[nCol].zColl = pCsr;
memcpy(pCsr, zColSeq, nCopy);
memcpy(pCsr, zCol, nCopy);
pCsr += nCopy;
}
@@ -768,9 +737,9 @@ static int idxGetTableInfo(
if( rc!=SQLITE_OK ){
sqlite3_free(pNew);
pNew = 0;
}else if( ALWAYS(pNew!=0) ){
}else{
pNew->zName = pCsr;
if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1);
memcpy(pNew->zName, zTab, nTab+1);
}
*ppOut = pNew;
@@ -820,10 +789,6 @@ static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
*/
static int idxIdentifierRequiresQuotes(const char *zId){
int i;
int nId = STRLEN(zId);
if( sqlite3_keyword_check(zId, nId) ) return 1;
for(i=0; zId[i]; i++){
if( !(zId[i]=='_')
&& !(zId[i]>='0' && zId[i]<='9')
@@ -900,7 +865,6 @@ static int idxFindCompatible(
IdxConstraint *pT = pTail;
sqlite3_stmt *pInfo = 0;
const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
if( zIdx==0 ) continue;
/* Zero the IdxConstraint.bFlag values in the pEq list */
for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
@@ -946,19 +910,6 @@ static int idxFindCompatible(
return 0;
}
/* Callback for sqlite3_exec() with query with leading count(*) column.
* The first argument is expected to be an int*, referent to be incremented
* if that leading column is not exactly '0'.
*/
static int countNonzeros(void* pCount, int nc,
char* azResults[], char* azColumns[]){
(void)azColumns; /* Suppress unused parameter warning */
if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){
*((int *)pCount) += 1;
}
return 0;
}
static int idxCreateFromCons(
sqlite3expert *p,
IdxScan *pScan,
@@ -985,40 +936,17 @@ static int idxCreateFromCons(
if( rc==SQLITE_OK ){
/* Hash the list of columns to come up with a name for the index */
const char *zTable = pScan->pTab->zName;
int quoteTable = idxIdentifierRequiresQuotes(zTable);
char *zName = 0; /* Index name */
int collisions = 0;
do{
int i;
char *zFind;
for(i=0; zCols[i]; i++){
h += ((h<<3) + zCols[i]);
}
sqlite3_free(zName);
zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
if( zName==0 ) break;
/* Is is unique among table, view and index names? */
zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q"
" AND type in ('index','table','view')";
zFind = sqlite3_mprintf(zFmt, zName);
i = 0;
rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0);
assert(rc==SQLITE_OK);
sqlite3_free(zFind);
if( i==0 ){
collisions = 0;
break;
}
++collisions;
}while( collisions<50 && zName!=0 );
if( collisions ){
/* This return means "Gave up trying to find a unique index name." */
rc = SQLITE_BUSY_TIMEOUT;
}else if( zName==0 ){
char *zName; /* Index name */
int i;
for(i=0; zCols[i]; i++){
h += ((h<<3) + zCols[i]);
}
zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
if( zName==0 ){
rc = SQLITE_NOMEM;
}else{
if( quoteTable ){
zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)";
if( idxIdentifierRequiresQuotes(zTable) ){
zFmt = "CREATE INDEX '%q' ON %Q(%s)";
}else{
zFmt = "CREATE INDEX %s ON %s(%s)";
}
@@ -1027,11 +955,7 @@ static int idxCreateFromCons(
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
if( rc!=SQLITE_OK ){
rc = SQLITE_BUSY_TIMEOUT;
}else{
idxHashAdd(&rc, &p->hIdx, zName, zIdx);
}
idxHashAdd(&rc, &p->hIdx, zName, zIdx);
}
sqlite3_free(zName);
sqlite3_free(zIdx);
@@ -1183,7 +1107,7 @@ static void idxWriteFree(IdxWrite *pTab){
** runs all the queries to see which indexes they prefer, and populates
** IdxStatement.zIdx and IdxStatement.zEQP with the results.
*/
static int idxFindIndexes(
int idxFindIndexes(
sqlite3expert *p,
char **pzErr /* OUT: Error message (sqlite3_malloc) */
){
@@ -1312,7 +1236,6 @@ static int idxProcessOneTrigger(
rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
if( zCreate==0 ) continue;
rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
}
idxFinalize(&rc, pSelect);
@@ -1415,9 +1338,8 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
if( zType==0 || zName==0 ) continue;
if( zType[0]=='v' || zType[1]=='r' ){
if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
}else{
IdxTable *pTab;
rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
@@ -1554,7 +1476,6 @@ static void idxRemFunc(
case SQLITE_BLOB:
case SQLITE_TEXT: {
int nByte = sqlite3_value_bytes(argv[1]);
const void *pData = 0;
if( nByte>pSlot->nByte ){
char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
if( zNew==0 ){
@@ -1566,11 +1487,9 @@ static void idxRemFunc(
}
pSlot->n = nByte;
if( pSlot->eType==SQLITE_BLOB ){
pData = sqlite3_value_blob(argv[1]);
if( pData ) memcpy(pSlot->z, pData, nByte);
memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
}else{
pData = sqlite3_value_text(argv[1]);
memcpy(pSlot->z, pData, nByte);
memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
}
break;
}
@@ -1781,7 +1700,6 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
if( zTab==0 || zIdx==0 ) continue;
if( p->iSample<100 && iPrev!=iRowid ){
samplectx.target = (double)p->iSample / 100.0;
samplectx.iTarget = p->iSample;
@@ -1848,14 +1766,14 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
/* Copy the entire schema of database [db] into [dbm]. */
if( rc==SQLITE_OK ){
sqlite3_stmt *pSql = 0;
sqlite3_stmt *pSql;
rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
"SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
" AND sql NOT LIKE 'CREATE VIRTUAL %%'"
);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
}
idxFinalize(&rc, pSql);
}
@@ -1961,10 +1879,6 @@ int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
/* Create candidate indexes within the in-memory database file */
if( rc==SQLITE_OK ){
rc = idxCreateCandidates(p);
}else if ( rc==SQLITE_BUSY_TIMEOUT ){
if( pzErr )
*pzErr = sqlite3_mprintf("Cannot find a unique index name to propose.");
return rc;
}
/* Generate the stat1 data */
+35 -46
View File
@@ -308,17 +308,18 @@
SQLITE_EXTENSION_INIT1
#endif
typedef struct Fts3HashWrapper Fts3HashWrapper;
struct Fts3HashWrapper {
Fts3Hash hash; /* Hash table */
int nRef; /* Number of pointers to this object */
};
static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_DEBUG)
int sqlite3Fts3Always(int b) { assert( b ); return b; }
int sqlite3Fts3Never(int b) { assert( !b ); return b; }
# endif
#endif
/*
** This variable is set to false when running tests for which the on disk
** structures should not be corrupt. Otherwise, true. If it is false, extra
@@ -1178,7 +1179,7 @@ static int fts3InitVtab(
sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
char **pzErr /* Write any error message here */
){
Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash;
Fts3Hash *pHash = (Fts3Hash *)pAux;
Fts3Table *p = 0; /* Pointer to allocated vtab */
int rc = SQLITE_OK; /* Return code */
int i; /* Iterator variable */
@@ -2888,7 +2889,7 @@ static int fts3TermSelectMerge(
**
** Similar padding is added in the fts3DoclistOrMerge() function.
*/
pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1);
pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -4013,12 +4014,9 @@ static const sqlite3_module fts3Module = {
** allocated for the tokenizer hash table.
*/
static void hashDestroy(void *p){
Fts3HashWrapper *pHash = (Fts3HashWrapper *)p;
pHash->nRef--;
if( pHash->nRef<=0 ){
sqlite3Fts3HashClear(&pHash->hash);
sqlite3_free(pHash);
}
Fts3Hash *pHash = (Fts3Hash *)p;
sqlite3Fts3HashClear(pHash);
sqlite3_free(pHash);
}
/*
@@ -4048,7 +4046,7 @@ void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
*/
int sqlite3Fts3Init(sqlite3 *db){
int rc = SQLITE_OK;
Fts3HashWrapper *pHash = 0;
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
#ifndef SQLITE_DISABLE_FTS3_UNICODE
@@ -4076,24 +4074,23 @@ int sqlite3Fts3Init(sqlite3 *db){
sqlite3Fts3PorterTokenizerModule(&pPorter);
/* Allocate and initialize the hash-table used to store tokenizers. */
pHash = sqlite3_malloc(sizeof(Fts3HashWrapper));
pHash = sqlite3_malloc(sizeof(Fts3Hash));
if( !pHash ){
rc = SQLITE_NOMEM;
}else{
sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1);
pHash->nRef = 0;
sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
}
/* Load the built-in tokenizers into the hash table */
if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter)
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|| sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode)
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif
#ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu))
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif
){
rc = SQLITE_NOMEM;
@@ -4102,7 +4099,7 @@ int sqlite3Fts3Init(sqlite3 *db){
#ifdef SQLITE_TEST
if( rc==SQLITE_OK ){
rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash);
rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
}
#endif
@@ -4111,26 +4108,23 @@ int sqlite3Fts3Init(sqlite3 *db){
** module with sqlite.
*/
if( SQLITE_OK==rc
&& SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer"))
&& SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2))
&& SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1))
){
pHash->nRef++;
rc = sqlite3_create_module_v2(
db, "fts3", &fts3Module, (void *)pHash, hashDestroy
);
if( rc==SQLITE_OK ){
pHash->nRef++;
rc = sqlite3_create_module_v2(
db, "fts4", &fts3Module, (void *)pHash, hashDestroy
db, "fts4", &fts3Module, (void *)pHash, 0
);
}
if( rc==SQLITE_OK ){
pHash->nRef++;
rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy);
rc = sqlite3Fts3InitTok(db, (void *)pHash);
}
return rc;
}
@@ -4139,7 +4133,7 @@ int sqlite3Fts3Init(sqlite3 *db){
/* An error has occurred. Delete the hash table and return the error code. */
assert( rc!=SQLITE_OK );
if( pHash ){
sqlite3Fts3HashClear(&pHash->hash);
sqlite3Fts3HashClear(pHash);
sqlite3_free(pHash);
}
return rc;
@@ -4308,7 +4302,8 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
char *aPoslist = 0; /* Position list for deferred tokens */
int nPoslist = 0; /* Number of bytes in aPoslist */
int iPrev = -1; /* Token number of previous deferred token */
char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0);
assert( pPhrase->doclist.bFreeList==0 );
for(iToken=0; iToken<pPhrase->nToken; iToken++){
Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
@@ -4322,7 +4317,6 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
if( pList==0 ){
sqlite3_free(aPoslist);
sqlite3_free(aFree);
pPhrase->doclist.pList = 0;
pPhrase->doclist.nList = 0;
return SQLITE_OK;
@@ -4343,7 +4337,6 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
nPoslist = (int)(aOut - aPoslist);
if( nPoslist==0 ){
sqlite3_free(aPoslist);
sqlite3_free(aFree);
pPhrase->doclist.pList = 0;
pPhrase->doclist.nList = 0;
return SQLITE_OK;
@@ -4376,14 +4369,13 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
nDistance = iPrev - nMaxUndeferred;
}
aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING);
aOut = (char *)sqlite3_malloc(nPoslist+8);
if( !aOut ){
sqlite3_free(aPoslist);
return SQLITE_NOMEM;
}
pPhrase->doclist.pList = aOut;
assert( p1 && p2 );
if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){
pPhrase->doclist.bFreeList = 1;
pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList);
@@ -4396,7 +4388,6 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
}
}
if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree);
return SQLITE_OK;
}
#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
@@ -4489,7 +4480,7 @@ void sqlite3Fts3DoclistPrev(
assert( nDoclist>0 );
assert( *pbEof==0 );
assert_fts3_nc( p || *piDocid==0 );
assert( p || *piDocid==0 );
assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) );
if( p==0 ){
@@ -4745,7 +4736,7 @@ static int fts3EvalIncrPhraseNext(
if( bEof==0 ){
int nList = 0;
int nByte = a[p->nToken-1].nList;
char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING);
char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
@@ -5353,8 +5344,8 @@ static void fts3EvalNextRow(
Fts3Expr *pRight = pExpr->pRight;
sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid );
assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
fts3EvalNextRow(pCsr, pLeft, pRc);
@@ -5571,10 +5562,11 @@ static int fts3EvalTestExpr(
default: {
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
if( pCsr->pDeferred && (pExpr->bDeferred || (
pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList
))){
if( pCsr->pDeferred
&& (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
){
Fts3Phrase *pPhrase = pExpr->pPhrase;
assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
if( pExpr->bDeferred ){
fts3EvalInvalidatePoslist(pPhrase);
}
@@ -5991,9 +5983,6 @@ int sqlite3Fts3EvalPhrasePoslist(
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
}
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
rc = FTS_CORRUPT_VTAB;
}
}
if( bTreeEof ){
while( rc==SQLITE_OK && !pNear->bEof ){
+12 -14
View File
@@ -151,18 +151,17 @@ extern int sqlite3_fts3_may_be_corrupt;
** Macros indicating that conditional expressions are always true or
** false.
*/
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
#endif
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
#elif !defined(NDEBUG)
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
#ifdef SQLITE_COVERAGE_TEST
# define ALWAYS(x) (1)
# define NEVER(X) (0)
#elif defined(SQLITE_DEBUG)
# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
# define NEVER(x) sqlite3Fts3Never((x)!=0)
int sqlite3Fts3Always(int b);
int sqlite3Fts3Never(int b);
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
# define ALWAYS(x) (x)
# define NEVER(x) (x)
#endif
/*
@@ -558,7 +557,7 @@ struct Fts3MultiSegReader {
int nAdvance; /* How many seg-readers to advance */
Fts3SegFilter *pFilter; /* Pointer to filter object */
char *aBuffer; /* Buffer to merge doclists in */
i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
int nBuffer; /* Allocated size of aBuffer[] in bytes */
int iColFilter; /* If >=0, filter for this column */
int bRestart;
@@ -621,7 +620,6 @@ void sqlite3Fts3ExprFree(Fts3Expr *);
int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
int sqlite3Fts3InitTerm(sqlite3 *db);
#endif
void *sqlite3Fts3MallocZero(i64 nByte);
int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
sqlite3_tokenizer_cursor **
@@ -641,7 +639,7 @@ int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
/* fts3_tokenize_vtab.c */
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifndef SQLITE_DISABLE_FTS3_UNICODE
+1 -5
View File
@@ -297,7 +297,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
iCol = 0;
rc = SQLITE_OK;
while( i<nDoclist ){
sqlite3_int64 v = 0;
@@ -341,10 +340,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
/* State 3. The integer just read is a column number. */
default: assert( eState==3 );
iCol = (int)v;
if( iCol<1 ){
rc = SQLITE_CORRUPT_VTAB;
break;
}
if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
pCsr->aStat[iCol+1].nDoc++;
eState = 2;
@@ -353,6 +348,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
}
pCsr->iCol = 0;
rc = SQLITE_OK;
}else{
pCsr->isEof = 1;
}
+5 -5
View File
@@ -122,7 +122,7 @@ static int fts3isspace(char c){
** zero the memory before returning a pointer to it. If unsuccessful,
** return NULL.
*/
void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){
static void *fts3MallocZero(sqlite3_int64 nByte){
void *pRet = sqlite3_malloc64(nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
@@ -203,7 +203,7 @@ static int getNextToken(
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
pRet = (Fts3Expr *)fts3MallocZero(nByte);
if( !pRet ){
rc = SQLITE_NOMEM;
}else{
@@ -458,7 +458,7 @@ static int getNextNode(
if( fts3isspace(cNext)
|| cNext=='"' || cNext=='(' || cNext==')' || cNext==0
){
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr));
pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
if( !pRet ){
return SQLITE_NOMEM;
}
@@ -637,7 +637,7 @@ static int fts3ExprParse(
&& p->eType==FTSQUERY_PHRASE && pParse->isNot
){
/* Create an implicit NOT operator. */
Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
if( !pNot ){
sqlite3Fts3ExprFree(p);
rc = SQLITE_NOMEM;
@@ -671,7 +671,7 @@ static int fts3ExprParse(
/* Insert an implicit AND operator. */
Fts3Expr *pAnd;
assert( pRet && pPrev );
pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
pAnd = fts3MallocZero(sizeof(Fts3Expr));
if( !pAnd ){
sqlite3Fts3ExprFree(p);
rc = SQLITE_NOMEM;
+1 -1
View File
@@ -621,7 +621,7 @@ static int porterNext(
if( n>c->nAllocated ){
char *pNew;
c->nAllocated = n+20;
pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
pNew = sqlite3_realloc(c->zToken, c->nAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->zToken = pNew;
}
+12 -11
View File
@@ -138,8 +138,9 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
+ sizeof(MatchinfoBuffer);
sqlite3_int64 nStr = strlen(zMatchinfo);
pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
pRet = sqlite3_malloc64(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)*((int)nElem+1);
@@ -543,10 +544,11 @@ static int fts3BestSnippet(
** the required space using malloc().
*/
nByte = sizeof(SnippetPhrase) * nList;
sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte);
sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
if( !sIter.aPhrase ){
return SQLITE_NOMEM;
}
memset(sIter.aPhrase, 0, nByte);
/* Initialize the contents of the SnippetIter object. Then iterate through
** the set of phrases in the expression to populate the aPhrase[] array.
@@ -1110,12 +1112,10 @@ static int fts3MatchinfoLcsCb(
** position list for the next column.
*/
static int fts3LcsIteratorAdvance(LcsIterator *pIter){
char *pRead;
char *pRead = pIter->pRead;
sqlite3_int64 iRead;
int rc = 0;
if( NEVER(pIter==0) ) return 1;
pRead = pIter->pRead;
pRead += sqlite3Fts3GetVarint(pRead, &iRead);
if( iRead==0 || iRead==1 ){
pRead = 0;
@@ -1149,8 +1149,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
/* Allocate and populate the array of LcsIterator objects. The array
** contains one element for each matchable phrase in the query.
**/
aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase);
aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
if( !aIter ) return SQLITE_NOMEM;
memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
for(i=0; i<pInfo->nPhrase; i++){
@@ -1611,7 +1612,7 @@ void sqlite3Fts3Offsets(
if( rc!=SQLITE_OK ) goto offsets_out;
/* Allocate the array of TermOffset iterators. */
sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
if( 0==sCtx.aTerm ){
rc = SQLITE_NOMEM;
goto offsets_out;
@@ -1632,13 +1633,13 @@ void sqlite3Fts3Offsets(
const char *zDoc;
int nDoc;
/* Initialize the contents of sCtx.aTerm[] for column iCol. This
** operation may fail if the database contains corrupt records.
/* Initialize the contents of sCtx.aTerm[] for column iCol. There is
** no way that this operation can fail, so the return code from
** fts3ExprIterate() can be discarded.
*/
sCtx.iCol = iCol;
sCtx.iTerm = 0;
rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
if( rc!=SQLITE_OK ) goto offsets_out;
(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.
+2 -4
View File
@@ -420,7 +420,7 @@ static int fts3tokRowidMethod(
** Register the fts3tok module with database connection db. Return SQLITE_OK
** if successful or an error code if sqlite3_create_module() fails.
*/
int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){
int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
static const sqlite3_module fts3tok_module = {
0, /* iVersion */
fts3tokConnectMethod, /* xCreate */
@@ -449,9 +449,7 @@ int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){
};
int rc; /* Return code */
rc = sqlite3_create_module_v2(
db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy
);
rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
return rc;
}
+1 -1
View File
@@ -185,7 +185,7 @@ static int simpleNext(
if( n>c->nTokenAllocated ){
char *pNew;
c->nTokenAllocated = n+20;
pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->pToken = pNew;
}
+39 -56
View File
@@ -649,7 +649,7 @@ static int fts3PendingListAppendVarint(
/* Allocate or grow the PendingList as required. */
if( !p ){
p = sqlite3_malloc64(sizeof(*p) + 100);
p = sqlite3_malloc(sizeof(*p) + 100);
if( !p ){
return SQLITE_NOMEM;
}
@@ -658,14 +658,14 @@ static int fts3PendingListAppendVarint(
p->nData = 0;
}
else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
i64 nNew = p->nSpace * 2;
p = sqlite3_realloc64(p, sizeof(*p) + nNew);
int nNew = p->nSpace * 2;
p = sqlite3_realloc(p, sizeof(*p) + nNew);
if( !p ){
sqlite3_free(*pp);
*pp = 0;
return SQLITE_NOMEM;
}
p->nSpace = (int)nNew;
p->nSpace = nNew;
p->aData = (char *)&p[1];
}
@@ -1222,7 +1222,7 @@ int sqlite3Fts3ReadBlock(
int nByte = sqlite3_blob_bytes(p->pSegments);
*pnBlob = nByte;
if( paBlob ){
char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING);
char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
if( !aByte ){
rc = SQLITE_NOMEM;
}else{
@@ -1335,19 +1335,9 @@ static int fts3SegReaderNext(
char *aCopy;
PendingList *pList = (PendingList *)fts3HashData(pElem);
int nCopy = pList->nData+1;
int nTerm = fts3HashKeysize(pElem);
if( (nTerm+1)>pReader->nTermAlloc ){
sqlite3_free(pReader->zTerm);
pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2);
if( !pReader->zTerm ) return SQLITE_NOMEM;
pReader->nTermAlloc = (nTerm+1)*2;
}
memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
pReader->zTerm[nTerm] = '\0';
pReader->nTerm = nTerm;
aCopy = (char*)sqlite3_malloc64(nCopy);
pReader->zTerm = (char *)fts3HashKey(pElem);
pReader->nTerm = fts3HashKeysize(pElem);
aCopy = (char*)sqlite3_malloc(nCopy);
if( !aCopy ) return SQLITE_NOMEM;
memcpy(aCopy, pList->aData, nCopy);
pReader->nNode = pReader->nDoclist = nCopy;
@@ -1599,7 +1589,9 @@ int sqlite3Fts3MsrOvfl(
*/
void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
if( pReader ){
sqlite3_free(pReader->zTerm);
if( !fts3SegReaderIsPending(pReader) ){
sqlite3_free(pReader->zTerm);
}
if( !fts3SegReaderIsRootOnly(pReader) ){
sqlite3_free(pReader->aNode);
}
@@ -1634,7 +1626,7 @@ int sqlite3Fts3SegReaderNew(
nExtra = nRoot + FTS3_NODE_PADDING;
}
pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra);
pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
if( !pReader ){
return SQLITE_NOMEM;
}
@@ -1726,7 +1718,7 @@ int sqlite3Fts3SegReaderPending(
if( nElem==nAlloc ){
Fts3HashElem **aElem2;
nAlloc += 16;
aElem2 = (Fts3HashElem **)sqlite3_realloc64(
aElem2 = (Fts3HashElem **)sqlite3_realloc(
aElem, nAlloc*sizeof(Fts3HashElem *)
);
if( !aElem2 ){
@@ -2011,8 +2003,8 @@ static int fts3PrefixCompress(
int nNext /* Size of buffer zNext in bytes */
){
int n;
for(n=0; n<nPrev && n<nNext && zPrev[n]==zNext[n]; n++);
assert_fts3_nc( n<nNext );
UNUSED_PARAMETER(nNext);
for(n=0; n<nPrev && zPrev[n]==zNext[n]; n++);
return n;
}
@@ -2060,7 +2052,7 @@ static int fts3NodeAddTerm(
** this is not expected to be a serious problem.
*/
assert( pTree->aData==(char *)&pTree[1] );
pTree->aData = (char *)sqlite3_malloc64(nReq);
pTree->aData = (char *)sqlite3_malloc(nReq);
if( !pTree->aData ){
return SQLITE_NOMEM;
}
@@ -2078,7 +2070,7 @@ static int fts3NodeAddTerm(
if( isCopyTerm ){
if( pTree->nMalloc<nTerm ){
char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2);
char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2104,7 +2096,7 @@ static int fts3NodeAddTerm(
** now. Instead, the term is inserted into the parent of pTree. If pTree
** has no parent, one is created here.
*/
pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize);
pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
if( !pNew ){
return SQLITE_NOMEM;
}
@@ -2242,7 +2234,7 @@ static int fts3SegWriterAdd(
){
int nPrefix; /* Size of term prefix in bytes */
int nSuffix; /* Size of term suffix in bytes */
i64 nReq; /* Number of bytes required on leaf page */
int nReq; /* Number of bytes required on leaf page */
int nData;
SegmentWriter *pWriter = *ppWriter;
@@ -2251,13 +2243,13 @@ static int fts3SegWriterAdd(
sqlite3_stmt *pStmt;
/* Allocate the SegmentWriter structure */
pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter));
pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
if( !pWriter ) return SQLITE_NOMEM;
memset(pWriter, 0, sizeof(SegmentWriter));
*ppWriter = pWriter;
/* Allocate a buffer in which to accumulate data */
pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize);
pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
if( !pWriter->aData ) return SQLITE_NOMEM;
pWriter->nSize = p->nNodeSize;
@@ -2332,7 +2324,7 @@ static int fts3SegWriterAdd(
** the buffer to make it large enough.
*/
if( nReq>pWriter->nSize ){
char *aNew = sqlite3_realloc64(pWriter->aData, nReq);
char *aNew = sqlite3_realloc(pWriter->aData, nReq);
if( !aNew ) return SQLITE_NOMEM;
pWriter->aData = aNew;
pWriter->nSize = nReq;
@@ -2357,7 +2349,7 @@ static int fts3SegWriterAdd(
*/
if( isCopyTerm ){
if( nTerm>pWriter->nMalloc ){
char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2);
char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2665,12 +2657,12 @@ static void fts3ColumnFilter(
static int fts3MsrBufferData(
Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
char *pList,
i64 nList
int nList
){
if( nList>pMsr->nBuffer ){
char *pNew;
pMsr->nBuffer = nList*2;
pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
if( !pNew ) return SQLITE_NOMEM;
pMsr->aBuffer = pNew;
}
@@ -2726,7 +2718,7 @@ int sqlite3Fts3MsrIncrNext(
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1);
rc = fts3MsrBufferData(pMsr, pList, nList+1);
if( rc!=SQLITE_OK ) return rc;
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
pList = pMsr->aBuffer;
@@ -2863,11 +2855,11 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){
return SQLITE_OK;
}
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
if( nReq>pCsr->nBuffer ){
char *aNew;
pCsr->nBuffer = nReq*2;
aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer);
aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
if( !aNew ){
return SQLITE_NOMEM;
}
@@ -2958,8 +2950,7 @@ int sqlite3Fts3SegReaderStep(
){
pCsr->nDoclist = apSegment[0]->nDoclist;
if( fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist,
(i64)pCsr->nDoclist);
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
pCsr->aDoclist = pCsr->aBuffer;
}else{
pCsr->aDoclist = apSegment[0]->aDoclist;
@@ -3012,8 +3003,7 @@ int sqlite3Fts3SegReaderStep(
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
rc = fts3GrowSegReaderBuffer(pCsr,
(i64)nByte+nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist);
if( rc ) return rc;
if( isFirst ){
@@ -3039,7 +3029,7 @@ int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, j, xCmp);
}
if( nDoclist>0 ){
rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
pCsr->aDoclist = pCsr->aBuffer;
@@ -3752,7 +3742,7 @@ struct NodeReader {
static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
int nAlloc = nMin;
char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc);
char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
if( a ){
pBlob->nAlloc = nAlloc;
pBlob->a = a;
@@ -3793,7 +3783,7 @@ static int nodeReaderNext(NodeReader *p){
return FTS_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){
if( rc==SQLITE_OK ){
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
p->term.n = nPrefix+nSuffix;
p->iOff += nSuffix;
@@ -3901,8 +3891,6 @@ static int fts3IncrmergePush(
pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
}
pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
assert( nPrefix+nSuffix<=nTerm );
assert( nPrefix>=0 );
memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
pBlk->n += nSuffix;
@@ -4025,7 +4013,6 @@ static int fts3IncrmergeAppend(
pLeaf = &pWriter->aNodeWriter[0];
nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
nSuffix = nTerm - nPrefix;
if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;
nSpace = sqlite3Fts3VarintLen(nPrefix);
nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
@@ -4190,11 +4177,7 @@ static int fts3TermCmp(
int nCmp = MIN(nLhs, nRhs);
int res;
if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){
res = memcmp(zLhs, zRhs, nCmp);
}else{
res = 0;
}
res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
if( res==0 ) res = nLhs - nRhs;
return res;
@@ -4549,7 +4532,7 @@ static int fts3RepackSegdirLevel(
if( nIdx>=nAlloc ){
int *aNew;
nAlloc += 16;
aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int));
aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
if( !aNew ){
rc = SQLITE_NOMEM;
break;
@@ -4838,7 +4821,7 @@ static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){
if( aHint ){
blobGrowBuffer(pHint, nHint, &rc);
if( rc==SQLITE_OK ){
if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint);
memcpy(pHint->a, aHint, nHint);
pHint->n = nHint;
}
}
@@ -4923,7 +4906,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
/* Allocate space for the cursor, filter and writer objects */
const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc);
pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
if( !pWriter ) return SQLITE_NOMEM;
pFilter = (Fts3SegFilter *)&pWriter[1];
pCsr = (Fts3MultiSegReader *)&pFilter[1];
@@ -5559,7 +5542,7 @@ int sqlite3Fts3DeferredTokenList(
return SQLITE_OK;
}
pRet = (char *)sqlite3_malloc64(p->pList->nData);
pRet = (char *)sqlite3_malloc(p->pList->nData);
if( !pRet ) return SQLITE_NOMEM;
nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
@@ -5579,7 +5562,7 @@ int sqlite3Fts3DeferToken(
int iCol /* Column that token must appear in (or -1) */
){
Fts3DeferredToken *pDeferred;
pDeferred = sqlite3_malloc64(sizeof(*pDeferred));
pDeferred = sqlite3_malloc(sizeof(*pDeferred));
if( !pDeferred ){
return SQLITE_NOMEM;
}
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/tclsh
#
# This script builds a single C code file holding all of FTS3 code.
# The name of the output file is fts3amal.c. To build this file,
# first do:
#
# make target_source
#
# The make target above moves all of the source code files into
# a subdirectory named "tsrc". (This script expects to find the files
# there and will not work if they are not found.)
#
# After the "tsrc" directory has been created and populated, run
# this script:
#
# tclsh mkfts3amal.tcl
#
# The amalgamated FTS3 code will be written into fts3amal.c
#
# Open the output file and write a header comment at the beginning
# of the file.
#
set out [open fts3amal.c w]
set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
puts $out [subst \
{/******************************************************************************
** This file is an amalgamation of separate C source files from the SQLite
** Full Text Search extension 2 (fts3). By combining all the individual C
** code files into this single large file, the entire code can be compiled
** as a one translation unit. This allows many compilers to do optimizations
** that would not be possible if the files were compiled separately. It also
** makes the code easier to import into other projects.
**
** This amalgamation was generated on $today.
*/}]
# These are the header files used by FTS3. The first time any of these
# files are seen in a #include statement in the C code, include the complete
# text of the file in-line. The file only needs to be included once.
#
foreach hdr {
fts3.h
fts3_hash.h
fts3_tokenizer.h
sqlite3.h
sqlite3ext.h
} {
set available_hdr($hdr) 1
}
# 78 stars used for comment formatting.
set s78 \
{*****************************************************************************}
# Insert a comment into the code
#
proc section_comment {text} {
global out s78
set n [string length $text]
set nstar [expr {60 - $n}]
set stars [string range $s78 0 $nstar]
puts $out "/************** $text $stars/"
}
# Read the source file named $filename and write it into the
# sqlite3.c output file. If any #include statements are seen,
# process them approprately.
#
proc copy_file {filename} {
global seen_hdr available_hdr out
set tail [file tail $filename]
section_comment "Begin file $tail"
set in [open $filename r]
while {![eof $in]} {
set line [gets $in]
if {[regexp {^#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
if {[info exists available_hdr($hdr)]} {
if {$available_hdr($hdr)} {
section_comment "Include $hdr in the middle of $tail"
copy_file tsrc/$hdr
section_comment "Continuing where we left off in $tail"
}
} elseif {![info exists seen_hdr($hdr)]} {
set seen_hdr($hdr) 1
puts $out $line
}
} elseif {[regexp {^#ifdef __cplusplus} $line]} {
puts $out "#if 0"
} elseif {[regexp {^#line} $line]} {
# Skip #line directives.
} else {
puts $out $line
}
}
close $in
section_comment "End of $tail"
}
# Process the source files. Process files containing commonly
# used subroutines first in order to help the compiler find
# inlining opportunities.
#
foreach file {
fts3.c
fts3_hash.c
fts3_porter.c
fts3_tokenizer.c
fts3_tokenizer1.c
} {
copy_file tsrc/$file
}
close $out
+4 -19
View File
@@ -35,20 +35,8 @@ typedef sqlite3_uint64 u64;
#endif
#define testcase(x)
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
#endif
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
#elif !defined(NDEBUG)
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
#endif
#define ALWAYS(x) 1
#define NEVER(x) 0
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
@@ -108,7 +96,7 @@ extern int sqlite3_fts5_may_be_corrupt;
** A version of memcmp() that does not cause asan errors if one of the pointer
** parameters is NULL and the number of bytes to compare is zero.
*/
#define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n)))
#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
@@ -286,7 +274,7 @@ void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c)
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
@@ -447,9 +435,6 @@ void sqlite3Fts5IndexCloseReader(Fts5Index*);
*/
const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
int sqlite3Fts5IterNextScan(Fts5IndexIter*);
void *sqlite3Fts5StructureRef(Fts5Index*);
void sqlite3Fts5StructureRelease(void*);
int sqlite3Fts5StructureTest(Fts5Index*, void*);
/*
+10 -15
View File
@@ -66,6 +66,7 @@ void sqlite3Fts5BufferAppendBlob(
u32 nData,
const u8 *pData
){
assert_nc( *pRc || nData>=0 );
if( nData ){
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
memcpy(&pBuf->p[pBuf->n], pData, nData);
@@ -175,7 +176,7 @@ int sqlite3Fts5PoslistNext64(
return 1;
}else{
i64 iOff = *piOff;
u32 iVal;
int iVal;
fts5FastGetVarint32(a, i, iVal);
if( iVal<=1 ){
if( iVal==0 ){
@@ -184,19 +185,15 @@ int sqlite3Fts5PoslistNext64(
}
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
assert( iOff>=0 );
fts5FastGetVarint32(a, i, iVal);
if( iVal<2 ){
/* This is a corrupt record. So stop parsing it here. */
*piOff = -1;
return 1;
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
}else{
*piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF);
}
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
assert_nc( *piOff>=iOff );
return 0;
}
}
@@ -235,16 +232,14 @@ void sqlite3Fts5PoslistSafeAppend(
i64 *piPrev,
i64 iPos
){
if( iPos>=*piPrev ){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
if( (iPos & colmask) != (*piPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
*piPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
*piPrev = iPos;
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
if( (iPos & colmask) != (*piPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
*piPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
*piPrev = iPos;
}
int sqlite3Fts5PoslistWriterAppend(
+1 -6
View File
@@ -562,7 +562,6 @@ int sqlite3Fts5ConfigParse(
z = fts5ConfigSkipWhitespace(z);
if( z && *z=='=' ){
bOption = 1;
assert( zOne!=0 );
z++;
if( bMustBeCol ) z = 0;
}
@@ -579,11 +578,7 @@ int sqlite3Fts5ConfigParse(
rc = SQLITE_ERROR;
}else{
if( bOption ){
rc = fts5ConfigParseSpecial(pGlobal, pRet,
ALWAYS(zOne)?zOne:"",
zTwo?zTwo:"",
pzErr
);
rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
}else{
rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
zOne = 0;
+10 -20
View File
@@ -135,7 +135,6 @@ void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
va_list ap;
va_start(ap, zFmt);
if( pParse->rc==SQLITE_OK ){
assert( pParse->zErr==0 );
pParse->zErr = sqlite3_vmprintf(zFmt, ap);
pParse->rc = SQLITE_ERROR;
}
@@ -434,7 +433,6 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
int bRetValid = 0;
Fts5ExprTerm *p;
assert( pTerm );
assert( pTerm->pSynonym );
assert( bDesc==0 || bDesc==1 );
for(p=pTerm; p; p=p->pSynonym){
@@ -1627,9 +1625,6 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
}else{
if( pRet->nPhrase>0 ){
Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
assert( pParse!=0 );
assert( pParse->apPhrase!=0 );
assert( pParse->nPhrase>=2 );
assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
if( pPhrase->nTerm==0 ){
fts5ExprPhraseFree(pPhrase);
@@ -1878,7 +1873,7 @@ int sqlite3Fts5ExprClonePhrase(
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
}
if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
if( rc==SQLITE_OK ){
/* All the allocations succeeded. Put the expression object together. */
pNew->pIndex = pExpr->pIndex;
pNew->pConfig = pExpr->pConfig;
@@ -2149,8 +2144,9 @@ void sqlite3Fts5ParseSetColset(
){
Fts5Colset *pFree = pColset;
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
sqlite3Fts5ParseError(pParse,
"fts5: column queries are not supported (detail=none)"
pParse->rc = SQLITE_ERROR;
pParse->zErr = sqlite3_mprintf(
"fts5: column queries are not supported (detail=none)"
);
}else{
fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
@@ -2324,10 +2320,13 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
|| pPhrase->nTerm>1
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
){
sqlite3Fts5ParseError(pParse,
assert( pParse->rc==SQLITE_OK );
pParse->rc = SQLITE_ERROR;
assert( pParse->zErr==0 );
pParse->zErr = sqlite3_mprintf(
"fts5: %s queries are not supported (detail!=full)",
pNear->nPhrase==1 ? "phrase": "NEAR"
);
);
sqlite3_free(pRet);
pRet = 0;
}
@@ -2859,15 +2858,6 @@ struct Fts5PoslistPopulator {
int bMiss;
};
/*
** Clear the position lists associated with all phrases in the expression
** passed as the first argument. Argument bLive is true if the expression
** might be pointing to a real entry, otherwise it has just been reset.
**
** At present this function is only used for detail=col and detail=none
** fts5 tables. This implies that all phrases must be at most 1 token
** in size, as phrase matches are not supported without detail=full.
*/
Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
Fts5PoslistPopulator *pRet;
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
@@ -2877,7 +2867,7 @@ Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
for(i=0; i<pExpr->nPhrase; i++){
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
assert( pExpr->apExprPhrase[i]->nTerm<=1 );
assert( pExpr->apExprPhrase[i]->nTerm==1 );
if( bLive &&
(pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
){
+1 -1
View File
@@ -356,7 +356,7 @@ int sqlite3Fts5HashWrite(
p->bContent = 1;
}else{
/* Append a new column value, if necessary */
assert_nc( iCol>=p->iCol );
assert( iCol>=p->iCol );
if( iCol!=p->iCol ){
if( pHash->eDetail==FTS5_DETAIL_FULL ){
pPtr[p->nData++] = 0x01;
+47 -135
View File
@@ -296,7 +296,7 @@ struct Fts5Index {
sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */
sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */
sqlite3_stmt *pIdxSelect;
int nRead; /* Total number of blocks read */
@@ -600,11 +600,8 @@ static int fts5BufferCompareBlob(
** res = *pLeft - *pRight
*/
static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
int nCmp, res;
nCmp = MIN(pLeft->n, pRight->n);
assert( nCmp<=0 || pLeft->p!=0 );
assert( nCmp<=0 || pRight->p!=0 );
res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
int nCmp = MIN(pLeft->n, pRight->n);
int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
return (res==0 ? (pLeft->n - pRight->n) : res);
}
@@ -700,7 +697,6 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
return pRet;
}
/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
@@ -825,58 +821,6 @@ static void fts5StructureRef(Fts5Structure *pStruct){
pStruct->nRef++;
}
void *sqlite3Fts5StructureRef(Fts5Index *p){
fts5StructureRef(p->pStruct);
return (void*)p->pStruct;
}
void sqlite3Fts5StructureRelease(void *p){
if( p ){
fts5StructureRelease((Fts5Structure*)p);
}
}
int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
if( p->pStruct!=(Fts5Structure*)pStruct ){
return SQLITE_ABORT;
}
return SQLITE_OK;
}
/*
** Ensure that structure object (*pp) is writable.
**
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If
** an error occurs, (*pRc) is set to an SQLite error code before returning.
*/
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
Fts5Structure *p = *pp;
if( *pRc==SQLITE_OK && p->nRef>1 ){
i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
Fts5Structure *pNew;
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
if( pNew ){
int i;
memcpy(pNew, p, nByte);
for(i=0; i<p->nLevel; i++) pNew->aLevel[i].aSeg = 0;
for(i=0; i<p->nLevel; i++){
Fts5StructureLevel *pLvl = &pNew->aLevel[i];
nByte = sizeof(Fts5StructureSegment) * pNew->aLevel[i].nSeg;
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(pRc, nByte);
if( pLvl->aSeg==0 ){
for(i=0; i<p->nLevel; i++){
sqlite3_free(pNew->aLevel[i].aSeg);
}
sqlite3_free(pNew);
return;
}
memcpy(pLvl->aSeg, p->aLevel[i].aSeg, nByte);
}
p->nRef--;
pNew->nRef = 1;
}
*pp = pNew;
}
}
/*
** Deserialize and return the structure record currently stored in serialized
** form within buffer pData/nData.
@@ -978,11 +922,9 @@ static int fts5StructureDecode(
}
/*
** Add a level to the Fts5Structure.aLevel[] array of structure object
** (*ppStruct).
**
*/
static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
fts5StructureMakeWritable(pRc, ppStruct);
if( *pRc==SQLITE_OK ){
Fts5Structure *pStruct = *ppStruct;
int nLevel = pStruct->nLevel;
@@ -1776,7 +1718,6 @@ static void fts5SegIterInit(
if( p->rc==SQLITE_OK ){
pIter->iLeafOffset = 4;
assert( pIter->pLeaf!=0 );
assert_nc( pIter->pLeaf->nn>4 );
assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
@@ -1879,12 +1820,8 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
int iRowidOff;
iRowidOff = fts5LeafFirstRowidOff(pNew);
if( iRowidOff ){
if( iRowidOff>=pNew->szLeaf ){
p->rc = FTS5_CORRUPT;
}else{
pIter->pLeaf = pNew;
pIter->iLeafOffset = iRowidOff;
}
pIter->pLeaf = pNew;
pIter->iLeafOffset = iRowidOff;
}
}
@@ -2164,7 +2101,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
if( pDlidx ){
int iSegid = pIter->pSeg->iSegid;
pgnoLast = fts5DlidxIterPgno(pDlidx);
pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
}else{
Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
@@ -2191,7 +2128,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
** forward to find the page containing the last rowid. */
for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
Fts5Data *pNew = fts5LeafRead(p, iAbs);
Fts5Data *pNew = fts5DataRead(p, iAbs);
if( pNew ){
int iRowid, bTermless;
iRowid = fts5LeafFirstRowidOff(pNew);
@@ -2222,10 +2159,6 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
pIter->pLeaf = pLast;
pIter->iLeafPgno = pgnoLast;
iOff = fts5LeafFirstRowidOff(pLast);
if( iOff>pLast->szLeaf ){
p->rc = FTS5_CORRUPT;
return;
}
iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
@@ -2234,6 +2167,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
}else{
pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
}
}
fts5SegIterReverseInitPage(p, pIter);
@@ -2285,20 +2219,21 @@ static void fts5LeafSeek(
Fts5SegIter *pIter, /* Iterator to seek */
const u8 *pTerm, int nTerm /* Term to search for */
){
u32 iOff;
int iOff;
const u8 *a = pIter->pLeaf->p;
u32 n = (u32)pIter->pLeaf->nn;
int szLeaf = pIter->pLeaf->szLeaf;
int n = pIter->pLeaf->nn;
u32 nMatch = 0;
u32 nKeep = 0;
u32 nNew = 0;
u32 iTermOff;
u32 iPgidx; /* Current offset in pgidx */
int iPgidx; /* Current offset in pgidx */
int bEndOfPage = 0;
assert( p->rc==SQLITE_OK );
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx = szLeaf;
iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
iOff = iTermOff;
if( iOff>n ){
@@ -2364,15 +2299,15 @@ static void fts5LeafSeek(
if( pIter->pLeaf==0 ) return;
a = pIter->pLeaf->p;
if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx = pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
return;
}else{
nKeep = 0;
iTermOff = iOff;
n = (u32)pIter->pLeaf->nn;
n = pIter->pLeaf->nn;
iOff += fts5GetVarint32(&a[iOff], nNew);
break;
}
@@ -2740,7 +2675,7 @@ static void fts5SegIterGotoPage(
fts5SegIterNextPage(p, pIter);
assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){
if( p->rc==SQLITE_OK ){
int iOff;
u8 *a = pIter->pLeaf->p;
int n = pIter->pLeaf->szLeaf;
@@ -3172,11 +3107,7 @@ static void fts5SegiterPoslist(
Fts5Colset *pColset,
Fts5Buffer *pBuf
){
assert( pBuf!=0 );
assert( pSeg!=0 );
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
assert( pBuf->p!=0 );
assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING );
memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
if( pColset==0 ){
fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
@@ -3252,7 +3183,7 @@ static void fts5IndexExtractColset(
}
fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy);
}
if( p>=pEnd ){
if( p==pEnd ){
pIter->base.pData = pIter->poslist.p;
pIter->base.nData = pIter->poslist.n;
return;
@@ -3400,7 +3331,6 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
}
static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
assert( pIter!=0 || (*pRc)!=SQLITE_OK );
if( *pRc==SQLITE_OK ){
Fts5Config *pConfig = pIter->pIndex->pConfig;
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
@@ -3472,10 +3402,7 @@ static void fts5MultiIterNew(
}
}
*ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
if( pNew==0 ){
assert( p->rc!=SQLITE_OK );
goto fts5MultiIterNew_post_check;
}
if( pNew==0 ) return;
pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
pNew->pColset = pColset;
@@ -3539,10 +3466,6 @@ static void fts5MultiIterNew(
fts5MultiIterFree(pNew);
*ppOut = 0;
}
fts5MultiIterNew_post_check:
assert( (*ppOut)!=0 || p->rc!=SQLITE_OK );
return;
}
/*
@@ -3590,8 +3513,7 @@ static void fts5MultiIterNew2(
** False otherwise.
*/
static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
assert( pIter!=0 || p->rc!=SQLITE_OK );
assert( p->rc!=SQLITE_OK
assert( p->rc
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof
);
return (p->rc || pIter->base.bEof);
@@ -4087,9 +4009,7 @@ static void fts5WriteAppendRowid(
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
}else{
assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
fts5BufferAppendVarint(&p->rc, &pPage->buf,
(u64)iRowid - (u64)pWriter->iPrevRowid
);
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
}
pWriter->iPrevRowid = iRowid;
pWriter->bFirstRowidInDoclist = 0;
@@ -4397,7 +4317,6 @@ static void fts5IndexMergeLevel(
** and last leaf page number at the same time. */
fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
assert( pIter!=0 || p->rc!=SQLITE_OK );
if( fts5MultiIterEof(p, pIter) ){
int i;
@@ -4498,7 +4417,7 @@ static void fts5IndexAutomerge(
Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
int nLeaf /* Number of output leaves just written */
){
if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){
if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){
Fts5Structure *pStruct = *ppStruct;
u64 nWrite; /* Initial value of write-counter */
int nWork; /* Number of work-quanta to perform */
@@ -4853,7 +4772,7 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
static void fts5AppendRowid(
Fts5Index *p,
u64 iDelta,
i64 iDelta,
Fts5Iter *pUnused,
Fts5Buffer *pBuf
){
@@ -4863,7 +4782,7 @@ static void fts5AppendRowid(
static void fts5AppendPoslist(
Fts5Index *p,
u64 iDelta,
i64 iDelta,
Fts5Iter *pMulti,
Fts5Buffer *pBuf
){
@@ -4938,10 +4857,10 @@ static void fts5MergeAppendDocid(
}
#endif
#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
fts5BufferSafeAppendVarint((pBuf), (u64)(iRowid) - (u64)(iLastRowid)); \
(iLastRowid) = (iRowid); \
#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
(iLastRowid) = (iRowid); \
}
/*
@@ -5060,7 +4979,7 @@ static void fts5MergePrefixLists(
Fts5Buffer *aBuf /* Other lists to merge in */
){
#define fts5PrefixMergerNextPosition(p) \
sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos)
sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos);
#define FTS5_MERGE_NLIST 16
PrefixMerger aMerger[FTS5_MERGE_NLIST];
PrefixMerger *pHead = 0;
@@ -5212,7 +5131,7 @@ static void fts5SetupPrefixIter(
int nMerge = 1;
void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*);
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
xMerge = fts5MergeRowidLists;
xAppend = fts5AppendRowid;
@@ -5251,7 +5170,7 @@ static void fts5SetupPrefixIter(
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
p1->xSetOutputs(p1, pSeg);
if( p1->base.nData ){
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
iLastRowid = p1->base.iRowid;
}
}
@@ -5299,7 +5218,7 @@ static void fts5SetupPrefixIter(
iLastRowid = 0;
}
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist);
iLastRowid = p1->base.iRowid;
}
@@ -5567,7 +5486,7 @@ int sqlite3Fts5IndexQuery(
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
int iIdx = 0; /* Index to search */
int iPrefixIdx = 0; /* +1 prefix index */
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
if( nToken ) memcpy(&buf.p[1], pToken, nToken);
/* Figure out which index to search and set iIdx accordingly. If this
** is a prefix query for which there is no prefix index, set iIdx to
@@ -5608,15 +5527,11 @@ int sqlite3Fts5IndexQuery(
/* Scan multiple terms in the main index */
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
if( pRet==0 ){
assert( p->rc!=SQLITE_OK );
}else{
assert( pRet->pColset==0 );
fts5IterSetOutputCb(&p->rc, pRet);
if( p->rc==SQLITE_OK ){
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
fts5IterSetOutputCb(&p->rc, pRet);
if( p->rc==SQLITE_OK ){
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
}
@@ -5864,7 +5779,7 @@ static int fts5QueryCksum(
Fts5IndexIter *pIter = 0;
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
i64 rowid = pIter->iRowid;
if( eDetail==FTS5_DETAIL_NONE ){
@@ -6229,7 +6144,6 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
Fts5Iter *pIter; /* Used to iterate through entire index */
Fts5Structure *pStruct; /* Index structure */
int iLvl, iSeg;
#ifdef SQLITE_DEBUG
/* Used by extra internal tests only run if NDEBUG is not defined */
@@ -6240,16 +6154,15 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
/* Load the FTS index structure */
pStruct = fts5StructureRead(p);
if( pStruct==0 ){
assert( p->rc!=SQLITE_OK );
return fts5IndexReturn(p);
}
/* Check that the internal nodes of each segment match the leaves */
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
fts5IndexIntegrityCheckSegment(p, pSeg);
if( pStruct ){
int iLvl, iSeg;
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
fts5IndexIntegrityCheckSegment(p, pSeg);
}
}
}
@@ -6278,7 +6191,6 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
/* If this is a new term, query for it. Update cksum3 with the results. */
fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
if( p->rc ) break;
if( eDetail==FTS5_DETAIL_NONE ){
if( 0==fts5MultiIterIsEmpty(p, pIter) ){
+2 -3
View File
@@ -804,7 +804,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
rc = sqlite3_step(pSorter->pStmt);
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
CsrFlagSet(pCsr, FTS5CSR_EOF);
}else if( rc==SQLITE_ROW ){
const u8 *a;
const u8 *aBlob;
@@ -1374,8 +1374,7 @@ static int fts5FilterMethod(
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
);
if( rc==SQLITE_OK ){
if( pRowidEq!=0 ){
assert( pCsr->ePlan==FTS5_PLAN_ROWID );
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
}else{
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
+2 -9
View File
@@ -417,16 +417,12 @@ static int fts5StorageDeleteFromIndex(
if( pConfig->abUnindexed[iCol-1]==0 ){
const char *zText;
int nText;
assert( pSeek==0 || apVal==0 );
assert( pSeek!=0 || apVal!=0 );
if( pSeek ){
zText = (const char*)sqlite3_column_text(pSeek, iCol);
nText = sqlite3_column_bytes(pSeek, iCol);
}else if( ALWAYS(apVal) ){
}else{
zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
nText = sqlite3_value_bytes(apVal[iCol-1]);
}else{
continue;
}
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
@@ -1062,9 +1058,8 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
assert( p->pConfig->bColumnsize );
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
if( pLookup ){
if( rc==SQLITE_OK ){
int bCorrupt = 1;
assert( rc==SQLITE_OK );
sqlite3_bind_int64(pLookup, 1, iRowid);
if( SQLITE_ROW==sqlite3_step(pLookup) ){
const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
@@ -1077,8 +1072,6 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
if( bCorrupt && rc==SQLITE_OK ){
rc = FTS5_CORRUPT;
}
}else{
assert( rc!=SQLITE_OK );
}
return rc;
+2 -10
View File
@@ -60,7 +60,6 @@ struct Fts5VocabCursor {
int bEof; /* True if this cursor is at EOF */
Fts5IndexIter *pIter; /* Term/rowid iterator object */
void *pStruct; /* From sqlite3Fts5StructureRef() */
int nLeTerm; /* Size of zLeTerm in bytes */
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
@@ -374,7 +373,7 @@ static int fts5VocabOpenMethod(
}
if( rc==SQLITE_OK ){
i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
}
@@ -394,8 +393,6 @@ static int fts5VocabOpenMethod(
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
sqlite3Fts5StructureRelease(pCsr->pStruct);
pCsr->pStruct = 0;
pCsr->pIter = 0;
sqlite3_free(pCsr->zLeTerm);
pCsr->nLeTerm = -1;
@@ -473,11 +470,9 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
int rc = SQLITE_OK;
int nCol = pCsr->pFts5->pConfig->nCol;
int rc;
rc = sqlite3Fts5StructureTest(pCsr->pFts5->pIndex, pCsr->pStruct);
if( rc!=SQLITE_OK ) return rc;
pCsr->rowid++;
if( pTab->eType==FTS5_VOCAB_INSTANCE ){
@@ -651,9 +646,6 @@ static int fts5VocabFilterMethod(
if( rc==SQLITE_OK ){
Fts5Index *pIndex = pCsr->pFts5->pIndex;
rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
if( rc==SQLITE_OK ){
pCsr->pStruct = sqlite3Fts5StructureRef(pIndex);
}
}
if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
rc = fts5VocabInstanceNewTerm(pCsr);
+1 -7
View File
@@ -165,7 +165,7 @@ do_execsql_test 4.0 {
}
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE p1 USING fts5(a, b, detail=%DETAIL%);
CREATE VIRTUAL TABLE p1 USING fts5(a, b);
INSERT INTO p1 VALUES(
'x a a a a a a a a a a',
'a a a a a a a a a a a a a a a a a a a x'
@@ -184,12 +184,6 @@ do_execsql_test 5.3 {
do_execsql_test 5.4 {
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x');
} {{[x a a a a a...}}
do_execsql_test 5.5 {
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x OR ""');
} {{[x a a a a a...}}
do_execsql_test 5.6 {
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x OR ' || x'DB');
} {{[x a a a a a...}}
} ;# foreach_detail_mode
-1
View File
@@ -11,7 +11,6 @@
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
# TESTRUNNER: slow
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5ah
+1 -598
View File
@@ -14791,7 +14791,7 @@ do_test 75.0 {
do_catchsql_test 75.1 {
SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {unable to use function matchinfo in the requested context}}
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
@@ -14922,603 +14922,6 @@ do_catchsql_test 76.1 {
SELECT * FROM t4;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 77.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-53216796d7c3d8.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 06 40 00 00 06 .....@ ....@...
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 ................
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
| 3920: 57 49 44 55 35 07 17 1b 1b 01 81 01 74 61 62 6c WIDU5.......tabl
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
| page 2 offset 4096
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H..........
| 96: 0a 8c 0a 6d 00 00 00 00 00 00 00 00 00 00 00 00 ...m............
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
| 2640: 82 d0 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
| 2736: 81 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f.
| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
| 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table.........
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f fc 01 03 02 .......,........
| 2880: 30 6e 03 06 01 00 f2 07 1b 8c 80 80 80 80 01 03 0n..............
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 18 ea 00 ....is..........
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
| 2944: 80 80 80 80 12 03 00 12 10 00 00 05 02 1c 88 80 ................
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
| 2992: 15 88 80 80 80 80 10 03 00 2f ff ff f0 11 02 01 ........./......
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
| 3056: 80 80 80 80 0d 03 00 3c 00 00 00 16 01 01 02 04 .......<........
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<...
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
| 3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
| 3328: 16 06 30 74 68 65 72 65 e7 02 02 00 02 31 31 02 ..0there.....11.
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
| 3488: 34 01 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 02 01 04 70 .....4each.....p
| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
| 3968: 6c 65 01 06 01 01 05 04 15 84 7f 80 80 80 03 03 le..............
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
| page 3 offset 8192
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 03 .V.M.A.8./.&....
| 64: 0f 0a 0f 00 9e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
| 80: 0e c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
| 3840: 1c 18 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
| 3872: 10 01 02 31 74 14 08 04 01 0f 01 02 31 6e 12 0a ...1t.......1n..
| 3888: d4 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
| 3936: 04 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
| 4016: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f
| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
| 4064: 0a 07 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
| 4080: 06 08 04 09 1e 61 30 66 74 04 05 04 09 0c 01 02 .....a0ft.......
| page 4 offset 12288
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
| page 5 offset 16384
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
| page 6 offset 20480
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 03 03 02 01 da 03 02 02 01 02 00 00 00 00 ................
| end crash-53216796d7c3d8.db
}]} {}
do_catchsql_test 77.1 {
UPDATE t1 SET B =quote(zeroblob(200)) WHERE b MATCH 'threa*thrad*tlrad*thed';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 78.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
DELETE FROM t1_data;
INSERT INTO t1_data VALUES(1,X'245a2424');
INSERT INTO t1_data VALUES(10,X'000000000101010001010101');
INSERT INTO t1_data VALUES(137438953473,X'0000032b0230300102060102060102061f0203010203010203010832303136303630390102070102070102070101340102050102050102050101350102040102040102040207303030303030301c0204010204010204010662696e6172790306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020108636f6d70696c657201200102020201020201066462737ccccccccccccccccccccccccccccccccccccccccccccbccccccccccccccccccccccccccccccccccccccccccccccca2cccccccccc461740702030102030102030204656275670402020102020102020106656e61626c6507020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020201020523d6763632d352e342e30203230313630363039584e4f4341534526010500430f17434f4d50494c45523d6763632d352e342e3020323031363036303958525452494d0d000000240ee00004a810000fe80fe00fd80fd00fc80fc00fb80fb00fa80fa00f980f900f880f800f780f700f680f60945736502060102020306010202030601020203060102020306010202030601020203060102020306010202030601020203060102020306010202030601020201046f6d59741f0202010202010202010572747265651945030102030102030402696d010601020203060102020306010202030601120203060102020306010202030601020203060102020306010202030601020203060102020306010202010a7468726561647361666522020201020201020201047674616207020401020401020401407801060cb102010601010201060101020106010102010601010201060101020106010102010601010201060e0102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601010201060101021106010102010601010201060101020106010102010601010201060101020106010102010601010201060101020106010102010601011201060101020106010102010601010201060101020106010102041513020c124413110f47130f0c0e11100f0e100f440f1040150f');
}
do_execsql_test 78.1 {
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
}
do_execsql_test 78.2 {
SELECT count(rowid) FROM t3 WHERE term>='nsocse';
} 2
#-------------------------------------------------------------------------
reset_db
do_test 79.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename sql053282.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00 ................
| 96: 00 00 00 00 0d 0f c7 00 06 0d b6 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d b5 00 00 00 00 00 00 ...k............
| 3504: 00 00 00 00 00 00 56 07 06 17 1f 1f 01 7d 74 61 ......V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
| page 3 offset 8192
| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 01 ................
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................
| 3488: 02 02 01 02 02 01 02 02 01 02 12 01 02 02 01 02 ................
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
| 3776: 01 02 02 03 06 01 01 02 03 06 01 02 02 03 06 01 ................
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
| 3856: 04 01 02 04 01 01 78 01 05 f1 01 02 01 06 01 01 ......x.........
| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3952: 01 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 4 offset 12288
| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 5 offset 16384
| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t
| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$......
| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 00 00 00 00 00 .......h.O......
| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE..
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS
| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3..
| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 2c 00000XRTRIM....,
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE.
| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
| 3440: 4e 41 42 4c 45 20 4d 45 4d 5a 69 53 35 58 42 49 NABLE MEMZiS5XBI
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 3f d8 .#..ENABLE FTS?.
| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY..
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN
| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3840: 55 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e UAT VTABXBINARY.
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 46 CASE.......DEBUF
| 3968: e8 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d .RTRIM'...C..COM
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
| 4064: 4f 4d 50 49 4c 45 52 3d 67 62 63 2d 35 2e 34 2e OMPILER=gbc-5.4.
| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM
| page 6 offset 20480
| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$...........
| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f bb 1f a8 0f a0 ................
| 32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.`
| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 00 00 00 00 .X.P.H.@.8.0....
| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . ..............
| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
| 4080: 06 0a 83 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end sql053282.txt.db
}]} {}
do_execsql_test 79.1 {
CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
}
do_catchsql_test 79.2 {
INSERT INTO t1(t1) SELECT 'merge' FROM t2;
} {1 {query aborted}}
#-------------------------------------------------------------------------
reset_db
do_test 80.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 40960 pagesize 4096 filename crash-f928a9c1ec68dd.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 0a .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 0d 00 00 00 04 ................
| 96: 00 00 00 00 0d 00 00 00 0d 0b 6e 00 0f a3 0f 4c ..........n....L
| 112: 0e e1 0e 81 0e 24 0d cc 0d 72 0d 1b 0c b0 0c 50 .....$...r.....P
| 128: 0b f8 0b b3 0b 6e 00 00 00 00 00 00 00 00 00 00 .....n..........
| 2912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 0d ..............C.
| 2928: 06 17 11 11 08 75 74 61 62 6c 65 74 34 74 34 43 .....utablet4t4C
| 2944: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA
| 2960: 42 4c 45 20 74 34 20 55 53 49 4e 47 20 66 74 73 BLE t4 USING fts
| 2976: 35 76 6f 63 61 62 28 27 74 32 27 2c 20 27 72 6f 5vocab('t2', 'ro
| 2992: 77 27 29 43 0c 06 17 11 11 08 75 74 61 62 6c 65 w')C......utable
| 3008: 74 33 74 33 43 52 45 41 54 45 20 56 49 52 54 55 t3t3CREATE VIRTU
| 3024: 41 4c 20 54 41 42 4c 45 20 74 33 20 55 53 49 4e AL TABLE t3 USIN
| 3040: 47 20 66 74 73 35 76 6f 63 61 62 28 27 74 31 27 G fts5vocab('t1'
| 3056: 2c 20 27 72 6f 77 27 29 56 0b 06 17 1f 1f 01 7d , 'row')V.......
| 3072: 74 61 62 6c 65 74 32 5f 63 6f 6e 66 69 67 74 32 tablet2_configt2
| 3088: 5f 63 6f 6e 66 69 67 0a 43 52 45 41 54 45 20 54 _config.CREATE T
| 3104: 41 42 4c 45 20 27 74 32 5f 63 6f 6e 66 69 67 27 ABLE 't2_config'
| 3120: 28 6b 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 (k PRIMARY KEY,
| 3136: 76 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 v) WITHOUT ROWID
| 3152: 5e 0a 07 17 21 21 01 81 07 74 61 62 6c 65 74 32 ^...!!...tablet2
| 3168: 5f 63 6f 6e 74 65 6e 74 74 32 5f 63 6f 6e 74 65 _contentt2_conte
| 3184: 6e 74 09 43 52 45 41 54 45 20 54 41 42 4c 45 20 nt.CREATE TABLE
| 3200: 27 74 32 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 't2_content'(id
| 3216: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
| 3232: 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 29 KEY, c0, c1, c2)
| 3248: 69 09 07 17 19 19 01 81 2d 74 61 62 6c 65 74 32 i.......-tablet2
| 3264: 5f 69 64 78 74 32 5f 69 64 78 08 43 52 45 41 54 _idxt2_idx.CREAT
| 3280: 45 20 54 41 42 4c 45 20 27 74 32 5f 69 64 78 27 E TABLE 't2_idx'
| 3296: 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 (segid, term, pg
| 3312: 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 no, PRIMARY KEY(
| 3328: 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 segid, term)) WI
| 3344: 54 48 4f 55 54 20 52 4f 57 49 44 55 08 07 17 1b THOUT ROWIDU....
| 3360: 1b 01 81 01 74 61 62 6c 65 74 32 5f 64 61 74 61 ....tablet2_data
| 3376: 74 32 5f 64 61 74 61 07 43 52 45 41 54 45 20 54 t2_data.CREATE T
| 3392: 41 42 4c 45 20 27 74 32 5f 64 61 74 61 27 28 69 ABLE 't2_data'(i
| 3408: 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 d INTEGER PRIMAR
| 3424: 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f Y KEY, block BLO
| 3440: 42 29 58 07 07 17 11 11 08 81 1d 74 61 62 6c 65 B)X........table
| 3456: 74 32 74 32 43 52 45 41 54 45 20 56 49 52 54 55 t2t2CREATE VIRTU
| 3472: 41 4c 20 54 41 42 4c 45 20 74 32 20 55 53 49 4e AL TABLE t2 USIN
| 3488: 47 20 66 74 73 35 28 27 61 27 2c 5b 62 5d 2c 22 G fts5('a',[b],.
| 3504: 63 22 2c 64 65 74 61 69 6c 3d 6e 6f 6e 65 2c 63 c.,detail=none,c
| 3520: 6f 6c 75 6d 6e 73 69 7a 65 3d 30 29 56 06 06 17 olumnsize=0)V...
| 3536: 1f 1f 01 7d 74 61 62 6c 65 74 31 5f 63 6f 6e 66 ....tablet1_conf
| 3552: 69 67 74 31 5f 63 6f 6e 66 69 67 06 43 52 45 41 igt1_config.CREA
| 3568: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e TE TABLE 't1_con
| 3584: 66 69 67 27 28 6b 20 50 52 49 4d 41 52 59 20 4b fig'(k PRIMARY K
| 3600: 45 59 2c 20 76 29 20 57 49 54 48 4f 55 54 20 52 EY, v) WITHOUT R
| 3616: 4f 57 49 44 5b 05 07 17 21 21 01 81 01 74 61 62 OWID[...!!...tab
| 3632: 6c 65 74 31 5f 64 6f 63 73 69 7a 65 74 31 5f 64 let1_docsizet1_d
| 3648: 6f 63 73 69 7a 65 05 43 52 45 41 54 45 20 54 41 ocsize.CREATE TA
| 3664: 42 4c 45 20 27 74 31 5f 64 6f 63 73 69 7a 65 27 BLE 't1_docsize'
| 3680: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
| 3696: 41 52 59 20 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 ARY KEY, sz BLOB
| 3712: 29 5e 04 07 17 21 21 01 81 07 74 61 62 6c 65 74 )^...!!...tablet
| 3728: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3744: 65 6e 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3760: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 69 64 't1_content'(id
| 3776: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
| 3792: 20 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 KEY, c0, c1, c2
| 3808: 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 )i.......-tablet
| 3824: 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 1_idxt1_idx.CREA
| 3840: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 78 TE TABLE 't1_idx
| 3856: 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 '(segid, term, p
| 3872: 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 gno, PRIMARY KEY
| 3888: 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 (segid, term)) W
| 3904: 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 17 ITHOUT ROWIDU...
| 3920: 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 74 .....tablet1_dat
| 3936: 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 20 at1_data.CREATE
| 3952: 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 28 TABLE 't1_data'(
| 3968: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 id INTEGER PRIMA
| 3984: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
| 4000: 4f 42 29 5b 01 07 17 11 11 08 81 23 74 61 62 6c OB)[.......#tabl
| 4016: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
| 4032: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
| 4048: 4e 47 20 66 74 73 35 28 61 2c 62 20 75 6e 69 6e NG fts5(a,b unin
| 4064: 64 65 78 65 64 2c 63 2c 74 6f 6b 65 6e 69 7a 65 dexed,c,tokenize
| 4080: 3d 22 70 6f 72 74 65 72 20 61 73 63 69 69 22 29 =.porter ascii.)
| page 2 offset 4096
| 0: 0d 0f 68 00 05 0f 13 00 0f e6 0f 13 0f a8 0f 7c ..h............|
| 16: 0f 2a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .*..............
| 3856: 00 00 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 .......0........
| 3872: 03 01 01 01 02 01 01 03 01 01 37 8c 80 80 80 80 ..........7.....
| 3888: 01 03 00 74 00 00 00 2e 02 30 61 03 02 02 01 01 ...t.....0a.....
| 3904: 62 03 02 03 01 01 63 03 02 04 01 01 67 03 06 01 b.....c.....g...
| 3920: 02 02 01 01 68 03 06 01 02 03 01 01 69 03 06 01 ....h.......i...
| 3936: 02 04 04 06 06 06 08 08 0f ef 00 14 2a 00 00 00 ............*...
| 3952: 00 01 02 02 00 02 01 01 01 02 01 01 25 88 80 80 ............%...
| 3968: 80 80 01 03 00 50 00 00 00 1f 02 30 67 02 08 02 .....P.....0g...
| 3984: 01 02 02 01 01 68 02 08 03 01 02 03 01 01 69 02 .....h........i.
| 4000: 08 04 01 02 04 04 09 09 37 84 80 80 80 80 01 03 ........7.......
| 4016: 00 74 00 00 00 2e 02 30 61 01 02 02 01 01 62 01 .t.....0a.....b.
| 4032: 02 03 01 01 63 01 02 04 01 01 67 01 06 01 02 02 ....c.....g.....
| 4048: 01 01 68 01 06 01 02 03 01 01 69 01 06 01 02 04 ..h.......i.....
| 4064: 04 06 06 06 08 08 07 01 03 00 14 03 09 00 09 00 ................
| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 3 offset 8192
| 0: 0a 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................
| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................
| page 4 offset 12288
| 0: 0d 00 00 00 03 0f be 00 0f ea 0f d4 0f be 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 05 00 17 17 a b cg h i......
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
| page 5 offset 16384
| 0: 0d 00 00 00 03 0f e8 00 0f f8 0f f0 0f e8 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 06 03 03 00 12 03 00 03 ................
| 4080: 06 02 03 00 12 03 00 03 06 01 03 00 12 03 00 03 ................
| page 6 offset 20480
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 01 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 7 offset 24576
| 0: 0d 00 00 00 03 0f 9e 00 0f e6 0f ef 00 00 00 00 ................
| 3984: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 84 ..............A.
| 4000: 80 80 80 80 01 04 00 81 06 00 00 00 34 02 30 61 ............4.0a
| 4016: 01 01 01 01 01 62 01 01 01 01 01 63 01 01 01 01 .....b.....c....
| 4032: 01 64 01 01 01 65 01 01 01 66 01 01 01 67 01 01 .d...e...f...g..
| 4048: 01 01 01 68 01 01 01 01 01 69 01 01 01 04 06 06 ...h.....i......
| 4064: 06 04 04 04 06 06 07 01 03 00 14 03 09 09 09 0f ................
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 8 offset 28672
| 0: 0a 00 00 00 01 0f fa 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 12 ................
| page 9 offset 32768
| 0: 0d 00 00 00 03 0f be 00 0f ea 0f d4 0f be 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 05 00 17 17 a b cg h i......
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
| page 10 offset 36864
| 0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 00 00 00 00 ........vers....
| end crash-f928a9c1ec68dd.db
}]} {}
do_catchsql_test 80.1 {
SELECT snippet(rowid, -1, '.', '..', '[', '(]'),snippet(rowid, -1, '.', '.', '', '(]'), highlight(t1, 29, 1 , '') FROM t1('g+ h') WHERE rank MATCH 'bm25(1.0, 10)' ORDER BY NOT (SELECT 1 FROM t1('g+ æ') WHERE rank MATCH 'bm25(1.0, 10)' ORDER BY rank);
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
-798
View File
@@ -1,798 +0,0 @@
# 2015 Apr 24
#
# 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 tests that FTS5 handles corrupt databases (i.e. internal
# inconsistencies in the backing tables) correctly. In this case
# "correctly" means without crashing.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5corrupt3
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
sqlite3_fts5_may_be_corrupt 1
database_may_be_corrupt
#-------------------------------------------------------------------------
# dbsqlfuzz crash-0f47112aa7520cf08c6a835a88fdff8c2a32a188
#
reset_db
do_test 1.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-0f47112aa7520c.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
| page 2 offset 4096
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00 ...~.H..........
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
| 2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12 0......5........
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
| 2720: 01 02 05 01 00 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
| 2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03 ......6......1f.
| 2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80 ....i...........
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
| 2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
| 2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80 .0table.B.......
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32 .........<.....2
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 9e 00 ............<...
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11.
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
| 3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03 res.............
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
| 3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01 ..<.....3.re....
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
| 3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06 .....<.....2th..
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62 ............0dab
| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66 .....0each.....f
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
| page 3 offset 8192
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
| 80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00 ................
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
| 3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
| 4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66 ..d...2i......2f
| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
| 4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
| 4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00 ................
| page 4 offset 12288
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
| page 5 offset 16384
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
| page 6 offset 20480
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00 ................
| end crash-0f47112aa7520c.db
}]
} {}
do_catchsql_test 1.1 {
SELECT * FROM t1('R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
do_test 2.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename sql047467.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
| 112: 0e e8 0e 8b 0e 33 0e 0f 01 00 00 00 00 00 00 00 .....3..........
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
| page 2 offset 4096
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00 ...~.H..........
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
| 2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12 0......5........
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
| 2480: 00 3b ff f0 00 16 04 33 74 68 65 03 06 01 01 04 .;.....3the.....
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
| 2720: 01 02 05 01 00 6f 03 06 01 01 06 14 09 18 8c 80 .....o..........
| 2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03 ......6......1f.
| 2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80 ....i...........
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
| 2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
| 2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80 .0table.B.......
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32 .........<.....2
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 94 50 ............<..P
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11.
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
| 3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03 res.............
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
| 3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01 ..<.....3.re....
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
| 3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06 .....<.....2th..
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62 ............0dab
| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66 .....0each.....f
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
| page 3 offset 8192
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
| 80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00 ................
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
| 3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
| 4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66 ..d...2i......2f
| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
| 4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
| 4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00 ................
| page 4 offset 12288
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
| page 5 offset 16384
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
| page 6 offset 20480
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00 ................
| end sql047467.txt.db
}]} {}
do_catchsql_test 2.1 {
SELECT * FROM t1('R*R*R*R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 3.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 32768 pagesize 4096 filename crash-c69fcaceff1e50.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
| page 3 offset 8192
| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
| 3232: 00 00 01 bb 02 30 30 01 02 06 01 02 06 01 02 06 .....00.........
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
| 3440: 6b b1 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 k.ble...........
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 3472: 01 02 02 01 02 02 05 02 02 01 02 02 01 02 02 01 ................
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 1a 02 03 .........fts4...
| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 01 ...omit.........
| 3744: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 ................
| 3760: 58 81 96 4d 01 06 01 02 02 03 06 01 02 02 03 06 X..M............
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
| 3872: 02 01 06 01 c6 02 01 06 01 01 02 01 06 01 01 02 ................
| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3904: 06 01 01 02 00 f6 01 01 02 01 06 01 01 02 01 06 ................
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 4 offset 12288
| 0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end crash-c69fcaceff1e50.db
}]} {}
do_catchsql_test 3.1 {
UPDATE t1 SET b=quote(zeroblob(200)) WHERE a MATCH 'thra*T';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 4.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-ef6738247b1344.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 10 00 06 40 00 00 06 .....@ ....@...
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 ................
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
| 3872: 74 65 72 6d 2c 20 6f 67 6e 6f 2c 20 50 52 49 4d term, ogno, PRIM
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
| 3920: 57 49 44 55 35 07 17 1b 1b 01 81 01 74 61 62 6c WIDU5.......tabl
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
| page 2 offset 4096
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a 00 ...~.H..........
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........
| 2400: 03 01 11 1c 8c 80 80 80 80 10 02 9c 3e 00 00 00 ............>...
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
| 2560: 04 00 04 33 66 74 73 03 12 02 04 07 18 8c 80 80 ...3fts.........
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
| 2640: 82 d0 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
| 2736: 81 80 80 06 03 00 36 00 00 00 13 04 12 31 66 03 ......6......1f.
| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
| 2800: 8c 80 65 80 80 04 03 00 30 00 00 00 11 01 01 06 ..e.....0.......
| 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table.........
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f fc 01 03 02 .......,........
| 2880: 30 6e 03 06 01 00 f2 07 1b 8c 80 80 80 80 01 03 0n..............
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
| 2912: 03 02 01 02 69 73 03 06 04 0c 00 00 00 18 ea 00 ....is..........
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
| 2944: 80 80 80 80 12 03 00 12 10 00 00 05 02 1c 88 80 ................
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
| 2992: 15 88 80 80 80 80 10 03 00 2f ff ff f0 11 02 01 ........./......
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
| 3024: 80 80 0f cf 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
| 3056: 80 80 80 80 0d 03 00 3c 00 00 00 16 00 01 02 04 .......<........
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<...
| 3200: 16 12 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
| 3248: 01 01 05 04 08 17 78 80 80 80 80 08 03 00 34 10 ......x.......4.
| 3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
| 3328: 16 06 30 74 68 65 72 65 e7 02 02 00 02 31 31 02 ..0there.....11.
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
| 3360: 00 00 11 01 01 05 e5 30 74 68 65 02 06 01 01 07 .......0the.....
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
| 3488: 34 01 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 02 01 04 70 .....4each.....p
| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
| 3664: 80 0d 03 0d 1a 00 00 00 15 04 33 66 6e 72 01 02 ..........3fnr..
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 30 c9 6e 01 ......8.....0.n.
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
| 3808: 02 0b e2 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
| 3824: 86 f0 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
| 3968: 6c 65 01 06 01 01 05 04 15 84 7f 80 80 80 03 03 le..............
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
| 4000: 01 02 05 05 1b 84 80 22 80 80 02 03 00 3c 00 00 .............<..
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
| page 3 offset 8192
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
| 48: 0f 56 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 .V..............
| 3392: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
| 3408: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
| 3424: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
| 3440: 34 6e 1a 08 04 01 10 01 03 32 67 18 08 04 01 10 4n.......2g.....
| 3456: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
| 3472: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
| 3488: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
| 3504: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
| 3520: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
| 3536: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
| 3552: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
| 3568: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
| 3584: 1c 18 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
| 3600: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
| 3616: 10 01 02 31 74 2a 08 04 01 0f 01 02 31 6e 12 0a ...1t*......1n..
| 3632: d4 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
| 3648: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
| 3664: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
| 3680: 04 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
| 3696: 04 06 03 f1 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
| 3712: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
| 3728: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
| 3744: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
| 3760: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f
| 3776: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
| 3792: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
| 3808: 0a 07 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
| 3824: 06 08 04 09 1e 61 30 66 74 04 05 00 00 00 00 00 .....a0ft.......
| page 4 offset 12288
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
| page 5 offset 16384
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
| end crash-ef6738247b1344.db
}]} {}
do_catchsql_test 4.1 {
BEGIN;
REPLACE INTO t1(rowid,b,a,rowid) VALUES(200,1,2,3);
} {1 {database disk image is malformed}}
do_catchsql_test 4.2 {
INSERT INTO t1(t1) VALUES('delete-all');
} {1 {database disk image is malformed}}
do_catchsql_test 4.3 {
REPLACE INTO t1(rowid,b,rowid,a) VALUES(200,1,2,3);
} {1 {database disk image is malformed}}
do_catchsql_test 4.4 {
REPLACE INTO t1(rowid,b,a,rowid) VALUES(0,1,2,3);
} {1 {database disk image is malformed}}
do_catchsql_test 4.5 {
REPLACE INTO t1(rowid,a,b,rowid) VALUES(200,1,2,3);
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
-54
View File
@@ -1,54 +0,0 @@
# 2015 Apr 24
#
# 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 tests that FTS5 handles corrupt databases (i.e. internal
# inconsistencies in the backing tables) correctly. In this case
# "correctly" means without crashing.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5corrupt6
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
sqlite3_fts5_may_be_corrupt 1
database_may_be_corrupt
proc editblock {block} {
binary format Sa* 20000 [string range $block 2 end]
}
db func editblock editblock
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ft USING fts5(abc, def);
WITH a(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM a WHERE i<1000
)
INSERT INTO ft SELECT
'abc abc abc abc abc abc abc abc abc abc',
'def def def def def def def def def def'
FROM a;
UPDATE ft_data SET block = editblock(block) WHERE id=(
SELECT id FROM ft_data ORDER BY id LIMIT 1 OFFSET 5
);
}
do_catchsql_test 1.1 {
SELECT rowid FROM ft('def') ORDER BY rowid DESC LIMIT 1 OFFSET 9999;
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
-4
View File
@@ -212,10 +212,6 @@ do_catchsql_test 4.1 {
SELECT * FROM t4('a:a')
} {1 {fts5: column queries are not supported (detail=none)}}
do_catchsql_test 4.2 {
SELECT * FROM t4('a:a &')
} {1 {fts5: syntax error near "&"}}
#-------------------------------------------------------------------------
# Test that for the same content detail=none uses less space than
# detail=col, and that detail=col uses less space than detail=full
+1 -1
View File
@@ -83,7 +83,7 @@ for {set i 0} {$i < 255} {incr i} {
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61');
INSERT INTO e1 VALUES ('just a few words with a / inside');
INSERT INTO e1 VALUES ("just a few words with a / inside");
}
do_execsql_test 3.1 {
SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank;
+2 -6
View File
@@ -16,16 +16,12 @@ source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault4
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
#-------------------------------------------------------------------------
# An OOM while dropping an fts5 table.
#
@@ -395,7 +391,7 @@ do_faultsim_test 14.1 -faults oom-t* -prep {
} -body {
db eval { ALTER TABLE "tbl one" RENAME TO "tbl two" }
} -test {
faultsim_test_result {0 {}} $::TMPDBERROR
faultsim_test_result {0 {}}
}
finish_test
+2 -2
View File
@@ -188,11 +188,11 @@ foreach {tn pgsz} {
INSERT INTO hh(hh, rank) VALUES('pgsz', $pgsz);
WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999)
INSERT INTO hh SELECT printf('%.3d%.3d%.3d %.3d%.3d%.3d',i,i,i,i+1,i+1,i+1)
INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1)
FROM s;
WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999)
INSERT INTO hh SELECT printf('%.3d%.3d%.3d %.3d%.3d%.3d',i,i,i,i+1,i+1,i+1)
INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1)
FROM s;
INSERT INTO hh(hh) VALUES('optimize');
-29
View File
@@ -323,34 +323,5 @@ do_execsql_test 12.3 {
SELECT * FROM t2 JOIN ft USING (ft)
} {3 4 b b}
#-------------------------------------------------------------------------
# Forum post https://sqlite.org/forum/forumpost/21127c1160
#
reset_db
sqlite3_db_config db DEFENSIVE 1
do_execsql_test 13.0 {
CREATE TABLE a (id INTEGER PRIMARY KEY, name TEXT);
CREATE VIRTUAL TABLE b USING fts5(name);
CREATE TRIGGER a_trigger AFTER INSERT ON a BEGIN
INSERT INTO b (name) VALUES ('foo');
END;
}
do_test 13.1 {
set ::STMT [
sqlite3_prepare db "INSERT INTO a VALUES (1, 'foo') RETURNING id;" -1 dummy
]
sqlite3_step $::STMT
} {SQLITE_ROW}
do_test 13.2 {
sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test 13.3 {
sqlite3_errmsg db
} {not an error}
finish_test
-60
View File
@@ -1,60 +0,0 @@
# 2022 August 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 test is focused on edge cases that cause ubsan errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5ubsan
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
}
set BIG 9000000000000000000
set SMALL -9000000000000000000
do_execsql_test 1.1 {
BEGIN;
INSERT INTO x1 (rowid, x) VALUES($BIG, 'aaa aba acc');
INSERT INTO x1 (rowid, x) VALUES($SMALL, 'aaa abc acb');
COMMIT;
}
do_execsql_test 1.2 {
SELECT rowid, x FROM x1('ab*');
} [list $SMALL {aaa abc acb} $BIG {aaa aba acc}]
do_execsql_test 1.3 {
SELECT rowid, x FROM x1('ac*');
} [list $SMALL {aaa abc acb} $BIG {aaa aba acc}]
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
}
do_execsql_test 2.1 {
INSERT INTO x1 (rowid, x) VALUES($BIG, 'aaa aba acc');
INSERT INTO x1 (rowid, x) VALUES($SMALL, 'aaa abc acb');
}
do_execsql_test 2.2 {
INSERT INTO x1 (x1) VALUES('optimize');
}
finish_test
-49
View File
@@ -234,53 +234,4 @@ ifcapable fts3 {
} {1 {no such fts5 table: main.nosuchtable}}
}
#-------------------------------------------------------------------------
# Check that the fts5 table cannot be written while there are vocab
# cursors open.
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance);
INSERT INTO t1 VALUES('one'), ('two'), ('three'), ('four');
}
do_test 5.1 {
list [catch {
db eval { SELECT * FROM v1 } {
db eval {INSERT INTO t1 VALUES('five')}
}
} msg] $msg
} {1 {query aborted}}
do_execsql_test 5.2 {
SELECT * FROM t1
} {one two three four five}
#-------------------------------------------------------------------------
# Check that the fts5 table cannot be written while there are vocab
# cursors open.
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance);
WITH s(i) AS (
VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<10000
)
INSERT INTO t1 SELECT
'State Emergency Service (SES), Rural Fire Service (RFS) and Volunteers'
FROM s;
}
do_catchsql_test 5.1 {
INSERT INTO t1 SELECT rowid FROM v1
} {1 {query aborted}}
do_catchsql_test 5.2 {
DELETE FROM t1 WHERE rowid>100;
INSERT INTO t1 SELECT randomblob(3000) FROM v1
} {1 {query aborted}}
finish_test
+1 -2
View File
@@ -60,8 +60,7 @@ proc fts5_source_id {zDir} {
set L [split [readfile [file join $top manifest]]]
set date [lindex $L [expr [lsearch -exact $L D]+1]]
set idx [expr {[string last . $date]-1}]
set date [string range $date 0 $idx]
set date [string range $date 0 [string last . $date]-1]
set date [string map {T { }} $date]
return "fts5: $date $uuid"
+10 -4
View File
@@ -153,12 +153,18 @@ SQLite. Documentation follows.
the ICU extension LIKE operator is 50000, defined in source
file "icu.c".
3.3 Collation Sequence Security
3.3 Collation Sequence Security Issue
Internally, SQLite assumes that indices stored in database files
are sorted according to the collation sequence indicated by the
SQL schema. Changing the definition of a collation sequence after
an index has been built is therefore equivalent to database
corruption. The SQLite library is well tested for robustness in
the fact of database corruption. Database corruption may well
lead to incorrect answers, but should not cause memory errors.
corruption. The SQLite library is not very well tested under
these conditions, and may contain potential buffer overruns
or other programming errors that could be exploited by a malicious
programmer.
If the ICU extension is used in an environment where potentially
malicious users may execute arbitrary SQL (i.e. gears), they
should be prevented from invoking the icu_load_collation() function,
possibly using the authorisation callback.
+2 -3
View File
@@ -299,9 +299,8 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
if( U_SUCCESS(status) ){
sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
pExpr = sqlite3_get_auxdata(p, 0);
}
if( !pExpr ){
}else{
assert(!pExpr);
icuFunctionError(p, "uregex_open", status);
return;
}
+1 -1
View File
@@ -26,7 +26,7 @@
**
** The virtual table contains read-only hidden columns:
**
** lsm1_key A BLOB which is the raw LSM key. If the "keytype"
** lsm1_key A BLOB which is the raw LSM key. If the "keytype"
** is BLOB or TEXT then this column is exactly the
** same as the key. For the UINT keytype, this column
** will be a variable-length integer encoding of the key.
-1
View File
@@ -657,7 +657,6 @@ int sqlite3_appendvfs_init(
(void)pzErrMsg;
(void)db;
pOrig = sqlite3_vfs_find(0);
if( pOrig==0 ) return SQLITE_ERROR;
apnd_vfs.iVersion = pOrig->iVersion;
apnd_vfs.pAppData = pOrig;
apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
+14 -18
View File
@@ -56,24 +56,14 @@
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h.
*/
#ifndef CARRAY_INT32
# define CARRAY_INT32 0 /* Data is 32-bit signed integers */
# define CARRAY_INT64 1 /* Data is 64-bit signed integers */
# define CARRAY_DOUBLE 2 /* Data is doubles */
# define CARRAY_TEXT 3 /* Data is char* */
#endif
#ifndef SQLITE_API
# ifdef _WIN32
# define SQLITE_API __declspec(dllexport)
# else
# define SQLITE_API
# endif
#endif
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE 2 /* Data is doubles */
#define CARRAY_TEXT 3 /* Data is char* */
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -410,7 +400,10 @@ static void carrayBindDel(void *pPtr){
** Invoke this interface in order to bind to the single-argument
** version of CARRAY().
*/
SQLITE_API int sqlite3_carray_bind(
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_carray_bind(
sqlite3_stmt *pStmt,
int idx,
void *aData,
@@ -464,7 +457,7 @@ SQLITE_API int sqlite3_carray_bind(
z += n+1;
}
}else{
memcpy(pNew->aData, aData, sz);
memcpy(pNew->aData, aData, sz*nData);
}
pNew->xDel = sqlite3_free;
}else{
@@ -505,7 +498,10 @@ static void inttoptrFunc(
#endif /* SQLITE_OMIT_VIRTUALTABLE */
SQLITE_API int sqlite3_carray_init(
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_carray_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
+1 -28
View File
@@ -1,32 +1,12 @@
/*
** 2020-11-17
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** Interface definitions for the CARRAY table-valued function
** extension.
*/
#ifndef _CARRAY_H
#define _CARRAY_H
#include "sqlite3.h" /* Required for error code definitions */
#ifdef __cplusplus
extern "C" {
#endif
/* Use this interface to bind an array to the single-argument version
** of CARRAY().
*/
SQLITE_API int sqlite3_carray_bind(
int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
void *aData, /* Pointer to array data */
@@ -41,10 +21,3 @@ SQLITE_API int sqlite3_carray_bind(
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
#define CARRAY_DOUBLE 2 /* Data is doubles */
#define CARRAY_TEXT 3 /* Data is char* */
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* ifndef _CARRAY_H */
+4 -2
View File
@@ -47,7 +47,7 @@
**
** sqlite3 *db;
** sqlite3_open(":memory:", &db);
** sqlite3_load_extension(db, "./cksumvfs");
** sqlite3_load_extention(db, "./cksumvfs");
** sqlite3_close(db);
**
** If this extension is compiled with -DSQLITE_CKSUMVFS_STATIC and
@@ -823,7 +823,6 @@ static int cksmRegisterVfs(void){
sqlite3_vfs *pOrig;
if( sqlite3_vfs_find("cksmvfs")!=0 ) return SQLITE_OK;
pOrig = sqlite3_vfs_find(0);
if( pOrig==0 ) return SQLITE_ERROR;
cksm_vfs.iVersion = pOrig->iVersion;
cksm_vfs.pAppData = pOrig;
cksm_vfs.szOsFile = pOrig->szOsFile + sizeof(CksmFile);
@@ -871,6 +870,9 @@ int sqlite3_cksumvfs_init(
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* not used */
rc = cksmRegisterFunc(db, 0, 0);
if( rc==SQLITE_OK ){
}
if( rc==SQLITE_OK ){
rc = cksmRegisterVfs();
}
+2 -9
View File
@@ -280,7 +280,6 @@ static char *csv_read_one_field(CsvReader *p){
}
p->cTerm = (char)c;
}
assert( p->z==0 || p->n<p->nAlloc );
if( p->z ) p->z[p->n] = 0;
p->bNotFirst = 1;
return p->z;
@@ -751,7 +750,7 @@ static int csvtabNext(sqlite3_vtab_cursor *cur){
i++;
}
}while( pCur->rdr.cTerm==',' );
if( z==0 && i==0 ){
if( z==0 || (pCur->rdr.cTerm==EOF && i<pTab->nCol) ){
pCur->iRowid = -1;
}else{
pCur->iRowid++;
@@ -812,12 +811,6 @@ static int csvtabFilter(
CsvCursor *pCur = (CsvCursor*)pVtabCursor;
CsvTable *pTab = (CsvTable*)pVtabCursor->pVtab;
pCur->iRowid = 0;
/* Ensure the field buffer is always allocated. Otherwise, if the
** first field is zero bytes in size, this may be mistaken for an OOM
** error in csvtabNext(). */
if( csv_append(&pCur->rdr, 0) ) return SQLITE_NOMEM;
if( pCur->rdr.in==0 ){
assert( pCur->rdr.zIn==pTab->zData );
assert( pTab->iStart>=0 );
@@ -948,7 +941,7 @@ int sqlite3_csv_init(
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
#ifndef SQLITE_OMIT_VIRTUALTABLE
#ifndef SQLITE_OMIT_VIRTUALTABLE
int rc;
SQLITE_EXTENSION_INIT2(pApi);
rc = sqlite3_create_module(db, "csv", &CsvModule, 0);
+42 -133
View File
@@ -71,20 +71,16 @@
** It contains one entry for each b-tree pointer between a parent and
** child page in the database.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
typedef unsigned char u8;
typedef unsigned int u32;
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
#define DBDATA_PADDING_BYTES 100
typedef struct DbdataTable DbdataTable;
@@ -106,12 +102,11 @@ struct DbdataCursor {
/* Only for the sqlite_dbdata table */
u8 *pRec; /* Buffer containing current record */
sqlite3_int64 nRec; /* Size of pRec[] in bytes */
sqlite3_int64 nHdr; /* Size of header in bytes */
int nRec; /* Size of pRec[] in bytes */
int nHdr; /* Size of header in bytes */
int iField; /* Current field number */
u8 *pHdrPtr;
u8 *pPtr;
u32 enc; /* Text encoding */
sqlite3_int64 iIntkey; /* Integer key value */
};
@@ -304,14 +299,14 @@ static int dbdataClose(sqlite3_vtab_cursor *pCursor){
/*
** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
*/
static u32 get_uint16(unsigned char *a){
static unsigned int get_uint16(unsigned char *a){
return (a[0]<<8)|a[1];
}
static u32 get_uint32(unsigned char *a){
return ((u32)a[0]<<24)
| ((u32)a[1]<<16)
| ((u32)a[2]<<8)
| ((u32)a[3]);
static unsigned int get_uint32(unsigned char *a){
return ((unsigned int)a[0]<<24)
| ((unsigned int)a[1]<<16)
| ((unsigned int)a[2]<<8)
| ((unsigned int)a[3]);
}
/*
@@ -326,7 +321,7 @@ static u32 get_uint32(unsigned char *a){
*/
static int dbdataLoadPage(
DbdataCursor *pCsr, /* Cursor object */
u32 pgno, /* Page number of page to load */
unsigned int pgno, /* Page number of page to load */
u8 **ppPage, /* OUT: pointer to page buffer */
int *pnPage /* OUT: Size of (*ppPage) in bytes */
){
@@ -336,27 +331,25 @@ static int dbdataLoadPage(
*ppPage = 0;
*pnPage = 0;
if( pgno>0 ){
sqlite3_bind_int64(pStmt, 2, pgno);
if( SQLITE_ROW==sqlite3_step(pStmt) ){
int nCopy = sqlite3_column_bytes(pStmt, 0);
if( nCopy>0 ){
u8 *pPage;
pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
if( pPage==0 ){
rc = SQLITE_NOMEM;
}else{
const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
memcpy(pPage, pCopy, nCopy);
memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
}
*ppPage = pPage;
*pnPage = nCopy;
sqlite3_bind_int64(pStmt, 2, pgno);
if( SQLITE_ROW==sqlite3_step(pStmt) ){
int nCopy = sqlite3_column_bytes(pStmt, 0);
if( nCopy>0 ){
u8 *pPage;
pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
if( pPage==0 ){
rc = SQLITE_NOMEM;
}else{
const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
memcpy(pPage, pCopy, nCopy);
memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
}
*ppPage = pPage;
*pnPage = nCopy;
}
rc2 = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
}
rc2 = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
@@ -365,30 +358,17 @@ static int dbdataLoadPage(
** Read a varint. Put the value in *pVal and return the number of bytes.
*/
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
sqlite3_uint64 u = 0;
sqlite3_int64 v = 0;
int i;
for(i=0; i<8; i++){
u = (u<<7) + (z[i]&0x7f);
if( (z[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; }
v = (v<<7) + (z[i]&0x7f);
if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
}
u = (u<<8) + (z[i]&0xff);
*pVal = (sqlite3_int64)u;
v = (v<<8) + (z[i]&0xff);
*pVal = v;
return 9;
}
/*
** Like dbdataGetVarint(), but set the output to 0 if it is less than 0
** or greater than 0xFFFFFFFF. This can be used for all varints in an
** SQLite database except for key values in intkey tables.
*/
static int dbdataGetVarintU32(const u8 *z, sqlite3_int64 *pVal){
sqlite3_int64 val;
int nRet = dbdataGetVarint(z, &val);
if( val<0 || val>0xFFFFFFFF ) val = 0;
*pVal = val;
return nRet;
}
/*
** Return the number of bytes of space used by an SQLite value of type
** eType.
@@ -425,10 +405,9 @@ static int dbdataValueBytes(int eType){
*/
static void dbdataValue(
sqlite3_context *pCtx,
u32 enc,
int eType,
u8 *pData,
sqlite3_int64 nData
int nData
){
if( eType>=0 && dbdataValueBytes(eType)<=nData ){
switch( eType ){
@@ -470,19 +449,7 @@ static void dbdataValue(
default: {
int n = ((eType-12) / 2);
if( eType % 2 ){
switch( enc ){
#ifndef SQLITE_OMIT_UTF16
case SQLITE_UTF16BE:
sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT);
break;
case SQLITE_UTF16LE:
sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT);
break;
#endif
default:
sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT);
break;
}
sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
}else{
sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
}
@@ -510,7 +477,6 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
if( rc!=SQLITE_OK ) return rc;
if( pCsr->aPage ) break;
if( pCsr->bOnePage ) return SQLITE_OK;
pCsr->iPgno++;
}
pCsr->iCell = pTab->bPtr ? -2 : 0;
@@ -574,7 +540,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
if( bNextPage || iOff>pCsr->nPage ){
bNextPage = 1;
}else{
iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
}
/* If this is a leaf intkey cell, load the rowid */
@@ -621,7 +587,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
/* Load content from overflow pages */
if( nPayload>nLocal ){
sqlite3_int64 nRem = nPayload - nLocal;
u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
while( nRem>0 ){
u8 *aOvfl = 0;
int nOvfl = 0;
@@ -641,8 +607,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
}
}
iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr);
if( nHdr>nPayload ) nHdr = 0;
iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
pCsr->nHdr = nHdr;
pCsr->pHdrPtr = &pCsr->pRec[iHdr];
pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
@@ -656,7 +621,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
bNextPage = 1;
}else{
pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
pCsr->pPtr += dbdataValueBytes(iType);
}
}
@@ -695,18 +660,6 @@ static int dbdataEof(sqlite3_vtab_cursor *pCursor){
return pCsr->aPage==0;
}
/*
** Return true if nul-terminated string zSchema ends in "()". Or false
** otherwise.
*/
static int dbdataIsFunction(const char *zSchema){
size_t n = strlen(zSchema);
if( n>2 && zSchema[n-2]=='(' && zSchema[n-1]==')' ){
return (int)n-2;
}
return 0;
}
/*
** Determine the size in pages of database zSchema (where zSchema is
** "main", "temp" or the name of an attached database) and set
@@ -717,16 +670,10 @@ static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
char *zSql = 0;
int rc, rc2;
int nFunc = 0;
sqlite3_stmt *pStmt = 0;
if( (nFunc = dbdataIsFunction(zSchema))>0 ){
zSql = sqlite3_mprintf("SELECT %.*s(0)", nFunc, zSchema);
}else{
zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
}
zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
@@ -737,25 +684,6 @@ static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
return rc;
}
/*
** Attempt to figure out the encoding of the database by retrieving page 1
** and inspecting the header field. If successful, set the pCsr->enc variable
** and return SQLITE_OK. Otherwise, return an SQLite error code.
*/
static int dbdataGetEncoding(DbdataCursor *pCsr){
int rc = SQLITE_OK;
int nPg1 = 0;
u8 *aPg1 = 0;
rc = dbdataLoadPage(pCsr, 1, &aPg1, &nPg1);
assert( rc!=SQLITE_OK || nPg1==0 || nPg1>=512 );
if( rc==SQLITE_OK && nPg1>0 ){
pCsr->enc = get_uint32(&aPg1[56]);
}
sqlite3_free(aPg1);
return rc;
}
/*
** xFilter method for sqlite_dbdata and sqlite_dbptr.
*/
@@ -773,28 +701,19 @@ static int dbdataFilter(
assert( pCsr->iPgno==1 );
if( idxNum & 0x01 ){
zSchema = (const char*)sqlite3_value_text(argv[0]);
if( zSchema==0 ) zSchema = "";
}
if( idxNum & 0x02 ){
pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
pCsr->bOnePage = 1;
}else{
pCsr->nPage = dbdataDbsize(pCsr, zSchema);
rc = dbdataDbsize(pCsr, zSchema);
}
if( rc==SQLITE_OK ){
int nFunc = 0;
if( pTab->pStmt ){
pCsr->pStmt = pTab->pStmt;
pTab->pStmt = 0;
}else if( (nFunc = dbdataIsFunction(zSchema))>0 ){
char *zSql = sqlite3_mprintf("SELECT %.*s(?2)", nFunc, zSchema);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
}else{
rc = sqlite3_prepare_v2(pTab->db,
"SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
@@ -807,20 +726,13 @@ static int dbdataFilter(
}else{
pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
}
/* Try to determine the encoding of the db by inspecting the header
** field on page 1. */
if( rc==SQLITE_OK ){
rc = dbdataGetEncoding(pCsr);
}
if( rc==SQLITE_OK ){
rc = dbdataNext(pCursor);
}
return rc;
}
/*
/*
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
*/
static int dbdataColumn(
@@ -864,12 +776,11 @@ static int dbdataColumn(
case DBDATA_COLUMN_VALUE: {
if( pCsr->iField<0 ){
sqlite3_result_int64(ctx, pCsr->iIntkey);
}else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){
}else{
sqlite3_int64 iType;
dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
dbdataGetVarint(pCsr->pHdrPtr, &iType);
dbdataValue(
ctx, pCsr->enc, iType, pCsr->pPtr,
&pCsr->pRec[pCsr->nRec] - pCsr->pPtr
ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
);
}
break;
@@ -938,5 +849,3 @@ int sqlite3_dbdata_init(
SQLITE_EXTENSION_INIT2(pApi);
return sqlite3DbdataRegister(db);
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+1 -31
View File
@@ -72,11 +72,6 @@
** $path is a relative path, then $path is interpreted relative to $dir.
** And the paths returned in the "name" column of the table are also
** relative to directory $dir.
**
** Notes on building this extension for Windows:
** Unless linked statically with the SQLite library, a preprocessor
** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
** DLL form of this extension for WIN32. See its use below for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
@@ -230,22 +225,6 @@ static sqlite3_uint64 fileTimeToUnixTime(
return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
}
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
# /* To allow a standalone DLL, use this next replacement function: */
# undef sqlite3_win32_utf8_to_unicode
# define sqlite3_win32_utf8_to_unicode utf8_to_utf16
#
LPWSTR utf8_to_utf16(const char *z){
int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
return rv;
sqlite3_free(rv);
return 0;
}
#endif
/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC. This is necessary on Win32, where the runtime library
@@ -368,11 +347,10 @@ static int writeFile(
mode_t mode, /* MODE parameter passed to writefile() */
sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
){
if( zFile==0 ) return 1;
#if !defined(_WIN32) && !defined(WIN32)
if( S_ISLNK(mode) ){
const char *zTo = (const char*)sqlite3_value_text(pData);
if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
if( symlink(zTo, zFile)<0 ) return 1;
}else
#endif
{
@@ -1020,11 +998,3 @@ int sqlite3_fileio_init(
}
return rc;
}
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
/* To allow a standalone DLL, make test_windirent.c use the same
* redefined SQLite API calls as the above extension code does.
* Just pull in this .c to accomplish this. As a beneficial side
* effect, this extension becomes a single translation unit. */
# include "test_windirent.c"
#endif
+2 -6
View File
@@ -194,11 +194,7 @@ static void ieee754func(
e += 1075;
if( e<=0 ){
/* Subnormal */
if( 1-e >= 64 ){
m = 0;
}else{
m >>= 1-e;
}
m >>= 1-e;
e = 0;
}else if( e>0x7ff ){
e = 0x7ff;
@@ -284,7 +280,7 @@ int sqlite3_ieee_init(
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
SQLITE_UTF8|SQLITE_INNOCUOUS,
(void*)&aFunc[i].iAux,
aFunc[i].xFunc, 0, 0);
File diff suppressed because it is too large Load Diff
-1
View File
@@ -559,7 +559,6 @@ int sqlite3_memvfs_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
mem_vfs.pAppData = sqlite3_vfs_find(0);
if( mem_vfs.pAppData==0 ) return SQLITE_ERROR;
mem_vfs.szOsFile = sizeof(MemFile);
rc = sqlite3_vfs_register(&mem_vfs, 1);
#ifdef MEMVFS_TEST
-461
View File
@@ -1,461 +0,0 @@
/*
** 2022-01-19
**
** 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 a virtual-table that returns information about
** how the query planner called the xBestIndex method. This virtual table
** is intended for testing and debugging only.
**
** The schema of the virtual table is this:
**
** CREATE TABLE qpvtab(
** vn TEXT, -- Name of an sqlite3_index_info field
** ix INTEGER, -- Array index or value
** cn TEXT, -- Column name
** op INTEGER, -- operator
** ux BOOLEAN, -- "usable" field
** rhs TEXT, -- sqlite3_vtab_rhs_value()
**
** a, b, c, d, e, -- Extra columns to attach constraints to
**
** flags INTEGER HIDDEN -- control flags
** );
**
** The virtual table returns a description of the sqlite3_index_info object
** that was provided to the (successful) xBestIndex method. There is one
** row in the result table for each field in the sqlite3_index_info object.
**
** The values of the "a" through "e" columns are one of:
**
** 1. TEXT - the same as the column name
** 2. INTEGER - 1 for "a", 2 for "b", and so forth
**
** Option 1 is the default behavior. 2 is use if there is a usable
** constraint on "flags" with an integer right-hand side that where the
** value of the right-hand side has its 0x001 bit set.
**
** All constraints on columns "a" through "e" are marked as "omit".
**
** If there is a usable constraint on "flags" that has a RHS value that
** is an integer and that integer has its 0x02 bit set, then the
** orderByConsumed flag is set.
**
** FLAGS SUMMARY:
**
** 0x001 Columns 'a' through 'e' have INT values
** 0x002 orderByConsumed is set
** 0x004 OFFSET and LIMIT have omit set
**
** COMPILE:
**
** gcc -Wall -g -shared -fPIC -I. qpvtab.c -o qqvtab.so
**
** EXAMPLE USAGE:
**
** .load ./qpvtab
** SELECT rowid, *, flags FROM qpvtab(102)
** WHERE a=19
** AND b BETWEEN 4.5 and 'hello'
** AND c<>x'aabbcc'
** ORDER BY d, e DESC;
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
/* qpvtab_vtab is a subclass of sqlite3_vtab which is
** underlying representation of the virtual table
*/
typedef struct qpvtab_vtab qpvtab_vtab;
struct qpvtab_vtab {
sqlite3_vtab base; /* Base class - must be first */
};
/* qpvtab_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct qpvtab_cursor qpvtab_cursor;
struct qpvtab_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_int64 iRowid; /* The rowid */
const char *zData; /* Data to return */
int nData; /* Number of bytes of data */
int flags; /* Flags value */
};
/*
** Names of columns
*/
static const char *azColname[] = {
"vn",
"ix",
"cn",
"op",
"ux",
"rhs",
"a", "b", "c", "d", "e",
"flags",
""
};
/*
** The qpvtabConnect() method is invoked to create a new
** qpvtab virtual table.
*/
static int qpvtabConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
qpvtab_vtab *pNew;
int rc;
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x("
" vn TEXT,"
" ix INT,"
" cn TEXT,"
" op INT,"
" ux BOOLEAN,"
" rhs TEXT,"
" a, b, c, d, e,"
" flags INT HIDDEN)"
);
#define QPVTAB_VN 0
#define QPVTAB_IX 1
#define QPVTAB_CN 2
#define QPVTAB_OP 3
#define QPVTAB_UX 4
#define QPVTAB_RHS 5
#define QPVTAB_A 6
#define QPVTAB_B 7
#define QPVTAB_C 8
#define QPVTAB_D 9
#define QPVTAB_E 10
#define QPVTAB_FLAGS 11
#define QPVTAB_NONE 12
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
return rc;
}
/*
** This method is the destructor for qpvtab_vtab objects.
*/
static int qpvtabDisconnect(sqlite3_vtab *pVtab){
qpvtab_vtab *p = (qpvtab_vtab*)pVtab;
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Constructor for a new qpvtab_cursor object.
*/
static int qpvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
qpvtab_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Destructor for a qpvtab_cursor.
*/
static int qpvtabClose(sqlite3_vtab_cursor *cur){
qpvtab_cursor *pCur = (qpvtab_cursor*)cur;
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a qpvtab_cursor to its next row of output.
*/
static int qpvtabNext(sqlite3_vtab_cursor *cur){
qpvtab_cursor *pCur = (qpvtab_cursor*)cur;
if( pCur->iRowid<pCur->nData ){
const char *z = &pCur->zData[pCur->iRowid];
const char *zEnd = strchr(z, '\n');
if( zEnd ) zEnd++;
pCur->iRowid = (int)(zEnd - pCur->zData);
}
return SQLITE_OK;
}
/*
** Return values of columns for the row at which the qpvtab_cursor
** is currently pointing.
*/
static int qpvtabColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
qpvtab_cursor *pCur = (qpvtab_cursor*)cur;
if( i>=QPVTAB_VN && i<=QPVTAB_RHS && pCur->iRowid<pCur->nData ){
const char *z = &pCur->zData[pCur->iRowid];
const char *zEnd;
int j;
j = QPVTAB_VN;
while(1){
zEnd = strchr(z, j==QPVTAB_RHS ? '\n' : ',');
if( j==i || zEnd==0 ) break;
z = zEnd+1;
j++;
}
if( zEnd==z ){
sqlite3_result_null(ctx);
}else if( i==QPVTAB_IX || i==QPVTAB_OP || i==QPVTAB_UX ){
sqlite3_result_int(ctx, atoi(z));
}else{
sqlite3_result_text64(ctx, z, zEnd-z, SQLITE_TRANSIENT, SQLITE_UTF8);
}
}else if( i>=QPVTAB_A && i<=QPVTAB_E ){
if( pCur->flags & 0x001 ){
sqlite3_result_int(ctx, i-QPVTAB_A+1);
}else{
char x = 'a'+i-QPVTAB_A;
sqlite3_result_text64(ctx, &x, 1, SQLITE_TRANSIENT, SQLITE_UTF8);
}
}else if( i==QPVTAB_FLAGS ){
sqlite3_result_int(ctx, pCur->flags);
}
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int qpvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
qpvtab_cursor *pCur = (qpvtab_cursor*)cur;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int qpvtabEof(sqlite3_vtab_cursor *cur){
qpvtab_cursor *pCur = (qpvtab_cursor*)cur;
return pCur->iRowid>=pCur->nData;
}
/*
** This method is called to "rewind" the qpvtab_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to qpvtabColumn() or qpvtabRowid() or
** qpvtabEof().
*/
static int qpvtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
qpvtab_cursor *pCur = (qpvtab_cursor *)pVtabCursor;
pCur->iRowid = 0;
pCur->zData = idxStr;
pCur->nData = (int)strlen(idxStr);
pCur->flags = idxNum;
return SQLITE_OK;
}
/*
** Append the text of a value to pStr
*/
static void qpvtabStrAppendValue(
sqlite3_str *pStr,
sqlite3_value *pVal
){
switch( sqlite3_value_type(pVal) ){
case SQLITE_NULL:
sqlite3_str_appendf(pStr, "NULL");
break;
case SQLITE_INTEGER:
sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pVal));
break;
case SQLITE_FLOAT:
sqlite3_str_appendf(pStr, "%!f", sqlite3_value_double(pVal));
break;
case SQLITE_TEXT: {
int i;
const char *a = (const char*)sqlite3_value_text(pVal);
int n = sqlite3_value_bytes(pVal);
sqlite3_str_append(pStr, "'", 1);
for(i=0; i<n; i++){
char c = a[i];
if( c=='\n' ) c = ' ';
sqlite3_str_append(pStr, &c, 1);
if( c=='\'' ) sqlite3_str_append(pStr, &c, 1);
}
sqlite3_str_append(pStr, "'", 1);
break;
}
case SQLITE_BLOB: {
int i;
const unsigned char *a = sqlite3_value_blob(pVal);
int n = sqlite3_value_bytes(pVal);
sqlite3_str_append(pStr, "x'", 2);
for(i=0; i<n; i++){
sqlite3_str_appendf(pStr, "%02x", a[i]);
}
sqlite3_str_append(pStr, "'", 1);
break;
}
}
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int qpvtabBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
sqlite3_str *pStr = sqlite3_str_new(0);
int i, k = 0;
int rc;
sqlite3_str_appendf(pStr, "nConstraint,%d,,,,\n", pIdxInfo->nConstraint);
for(i=0; i<pIdxInfo->nConstraint; i++){
sqlite3_value *pVal;
int iCol = pIdxInfo->aConstraint[i].iColumn;
int op = pIdxInfo->aConstraint[i].op;
if( iCol==QPVTAB_FLAGS && pIdxInfo->aConstraint[i].usable ){
pVal = 0;
rc = sqlite3_vtab_rhs_value(pIdxInfo, i, &pVal);
assert( rc==SQLITE_OK || pVal==0 );
if( pVal ){
pIdxInfo->idxNum = sqlite3_value_int(pVal);
if( pIdxInfo->idxNum & 0x002 ) pIdxInfo->orderByConsumed = 1;
}
}
if( op==SQLITE_INDEX_CONSTRAINT_LIMIT
|| op==SQLITE_INDEX_CONSTRAINT_OFFSET
){
iCol = QPVTAB_NONE;
}
sqlite3_str_appendf(pStr,"aConstraint,%d,%s,%d,%d,",
i,
azColname[iCol],
op,
pIdxInfo->aConstraint[i].usable);
pVal = 0;
rc = sqlite3_vtab_rhs_value(pIdxInfo, i, &pVal);
assert( rc==SQLITE_OK || pVal==0 );
if( pVal ){
qpvtabStrAppendValue(pStr, pVal);
}
sqlite3_str_append(pStr, "\n", 1);
}
for(i=0; i<pIdxInfo->nConstraint; i++){
int iCol = pIdxInfo->aConstraint[i].iColumn;
int op = pIdxInfo->aConstraint[i].op;
if( op==SQLITE_INDEX_CONSTRAINT_LIMIT
|| op==SQLITE_INDEX_CONSTRAINT_OFFSET
){
iCol = QPVTAB_NONE;
}
if( iCol>=QPVTAB_A && pIdxInfo->aConstraint[i].usable ){
pIdxInfo->aConstraintUsage[i].argvIndex = ++k;
if( iCol<=QPVTAB_FLAGS || (pIdxInfo->idxNum & 0x004)!=0 ){
pIdxInfo->aConstraintUsage[i].omit = 1;
}
}
}
sqlite3_str_appendf(pStr, "nOrderBy,%d,,,,\n", pIdxInfo->nOrderBy);
for(i=0; i<pIdxInfo->nOrderBy; i++){
int iCol = pIdxInfo->aOrderBy[i].iColumn;
sqlite3_str_appendf(pStr, "aOrderBy,%d,%s,%d,,\n",i,
iCol>=0 ? azColname[iCol] : "rowid",
pIdxInfo->aOrderBy[i].desc
);
}
sqlite3_str_appendf(pStr, "sqlite3_vtab_distinct,%d,,,,\n",
sqlite3_vtab_distinct(pIdxInfo));
sqlite3_str_appendf(pStr, "idxFlags,%d,,,,\n", pIdxInfo->idxFlags);
sqlite3_str_appendf(pStr, "colUsed,%d,,,,\n", (int)pIdxInfo->colUsed);
pIdxInfo->estimatedCost = (double)10;
pIdxInfo->estimatedRows = 10;
sqlite3_str_appendf(pStr, "idxNum,%d,,,,\n", pIdxInfo->idxNum);
sqlite3_str_appendf(pStr, "orderByConsumed,%d,,,,\n",
pIdxInfo->orderByConsumed);
pIdxInfo->idxStr = sqlite3_str_finish(pStr);
pIdxInfo->needToFreeIdxStr = 1;
return SQLITE_OK;
}
/*
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module qpvtabModule = {
/* iVersion */ 0,
/* xCreate */ 0,
/* xConnect */ qpvtabConnect,
/* xBestIndex */ qpvtabBestIndex,
/* xDisconnect */ qpvtabDisconnect,
/* xDestroy */ 0,
/* xOpen */ qpvtabOpen,
/* xClose */ qpvtabClose,
/* xFilter */ qpvtabFilter,
/* xNext */ qpvtabNext,
/* xEof */ qpvtabEof,
/* xColumn */ qpvtabColumn,
/* xRowid */ qpvtabRowid,
/* xUpdate */ 0,
/* xBegin */ 0,
/* xSync */ 0,
/* xCommit */ 0,
/* xRollback */ 0,
/* xFindMethod */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_qpvtab_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "qpvtab", &qpvtabModule, 0);
#endif
return rc;
}
+28 -148
View File
@@ -72,7 +72,6 @@ SQLITE_EXTENSION_INIT1
/* The end-of-input character */
#define RE_EOF 0 /* End of input */
#define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */
/* The NFA is implemented as sequence of opcodes taken from the following
** set. Each opcode has a single integer argument.
@@ -94,33 +93,6 @@ SQLITE_EXTENSION_INIT1
#define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */
#define RE_OP_NOTSPACE 16 /* Not a digit */
#define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */
#define RE_OP_ATSTART 18 /* Currently at the start of the string */
#if defined(SQLITE_DEBUG)
/* Opcode names used for symbolic debugging */
static const char *ReOpName[] = {
"EOF",
"MATCH",
"ANY",
"ANYSTAR",
"FORK",
"GOTO",
"ACCEPT",
"CC_INC",
"CC_EXC",
"CC_VALUE",
"CC_RANGE",
"WORD",
"NOTWORD",
"DIGIT",
"NOTDIGIT",
"SPACE",
"NOTSPACE",
"BOUNDARY",
"ATSTART",
};
#endif /* SQLITE_DEBUG */
/* Each opcode is a "state" in the NFA */
typedef unsigned short ReStateNumber;
@@ -155,7 +127,7 @@ struct ReCompiled {
int *aArg; /* Arguments to each operator */
unsigned (*xNextChar)(ReInput*); /* Next character function */
unsigned char zInit[12]; /* Initial text to match */
int nInit; /* Number of bytes in zInit */
int nInit; /* Number of characters in zInit */
unsigned nState; /* Number of entries in aOp[] and aArg[] */
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
};
@@ -185,7 +157,7 @@ static unsigned re_next_char(ReInput *p){
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
p->i += 2;
if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
}else if( (c&0xf8)==0xf0 && p->i+2<p->mx && (p->z[p->i]&0xc0)==0x80
}else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
| (p->z[p->i+2]&0x3f);
@@ -228,7 +200,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
ReStateNumber *pToFree;
unsigned int i = 0;
unsigned int iSwap = 0;
int c = RE_START;
int c = RE_EOF+1;
int cPrev = 0;
int rc = 0;
ReInput in;
@@ -247,7 +219,6 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
in.i++;
}
if( in.i+pRe->nInit>in.mx ) return 0;
c = RE_START-1;
}
if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
@@ -276,12 +247,8 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
break;
}
case RE_OP_ATSTART: {
if( cPrev==RE_START ) re_add_state(pThis, x+1);
break;
}
case RE_OP_ANY: {
if( c!=0 ) re_add_state(pNext, x+1);
re_add_state(pNext, x+1);
break;
}
case RE_OP_WORD: {
@@ -289,7 +256,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
break;
}
case RE_OP_NOTWORD: {
if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1);
if( !re_word_char(c) ) re_add_state(pNext, x+1);
break;
}
case RE_OP_DIGIT: {
@@ -297,7 +264,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
break;
}
case RE_OP_NOTDIGIT: {
if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1);
if( !re_digit_char(c) ) re_add_state(pNext, x+1);
break;
}
case RE_OP_SPACE: {
@@ -305,7 +272,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
break;
}
case RE_OP_NOTSPACE: {
if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1);
if( !re_space_char(c) ) re_add_state(pNext, x+1);
break;
}
case RE_OP_BOUNDARY: {
@@ -330,11 +297,8 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
rc = 1;
goto re_match_end;
}
case RE_OP_CC_INC:
case RE_OP_CC_EXC: {
if( c==0 ) break;
/* fall-through */ goto re_op_cc_inc;
}
case RE_OP_CC_INC: re_op_cc_inc: {
int j = 1;
int n = pRe->aArg[x];
int hit = 0;
@@ -355,15 +319,13 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
}
if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
if( hit ) re_add_state(pNext, x+n);
break;
break;
}
}
}
}
for(i=0; i<pNext->nState; i++){
int x = pNext->aState[i];
while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
}
re_match_end:
sqlite3_free(pToFree);
@@ -518,6 +480,7 @@ static const char *re_subcompile_string(ReCompiled *p){
iStart = p->nState;
switch( c ){
case '|':
case '$':
case ')': {
p->sIn.i--;
return 0;
@@ -533,7 +496,7 @@ static const char *re_subcompile_string(ReCompiled *p){
if( rePeek(p)=='*' ){
re_append(p, RE_OP_ANYSTAR, 0);
p->sIn.i++;
}else{
}else{
re_append(p, RE_OP_ANY, 0);
}
break;
@@ -554,14 +517,6 @@ static const char *re_subcompile_string(ReCompiled *p){
re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
break;
}
case '$': {
re_append(p, RE_OP_MATCH, RE_EOF);
break;
}
case '^': {
re_append(p, RE_OP_ATSTART, 0);
break;
}
case '{': {
int m = 0, n = 0;
int sz, j;
@@ -580,7 +535,6 @@ static const char *re_subcompile_string(ReCompiled *p){
if( m==0 ){
if( n==0 ) return "both m and n are zero in '{m,n}'";
re_insert(p, iPrev, RE_OP_FORK, sz+1);
iPrev++;
n--;
}else{
for(j=1; j<m; j++) re_copy(p, iPrev, sz);
@@ -699,7 +653,11 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
re_free(pRe);
return zErr;
}
if( pRe->sIn.i>=pRe->sIn.mx ){
if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
re_append(pRe, RE_OP_MATCH, RE_EOF);
re_append(pRe, RE_OP_ACCEPT, 0);
*ppRe = pRe;
}else if( pRe->sIn.i>=pRe->sIn.mx ){
re_append(pRe, RE_OP_ACCEPT, 0);
*ppRe = pRe;
}else{
@@ -712,19 +670,19 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
** one or more matching characters, enter those matching characters into
** zInit[]. The re_match() routine can then search ahead in the input
** string looking for the initial match without having to run the whole
** regex engine over the string. Do not worry about trying to match
** regex engine over the string. Do not worry able trying to match
** unicode characters beyond plane 0 - those are very rare and this is
** just an optimization. */
if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
if( pRe->aOp[0]==RE_OP_ANYSTAR ){
for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
unsigned x = pRe->aArg[i];
if( x<=0x7f ){
if( x<=127 ){
pRe->zInit[j++] = (unsigned char)x;
}else if( x<=0x7ff ){
}else if( x<=0xfff ){
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else if( x<=0xffff ){
pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else{
@@ -747,8 +705,8 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
** is implemented as regexp(B,A).
*/
static void re_sql_func(
sqlite3_context *context,
int argc,
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
ReCompiled *pRe; /* Compiled regular expression */
@@ -757,12 +715,11 @@ static void re_sql_func(
const char *zErr; /* Compile error message */
int setAux = 0; /* True to invoke sqlite3_set_auxdata() */
(void)argc; /* Unused */
pRe = sqlite3_get_auxdata(context, 0);
if( pRe==0 ){
zPattern = (const char*)sqlite3_value_text(argv[0]);
if( zPattern==0 ) return;
zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
zErr = re_compile(&pRe, zPattern, 0);
if( zErr ){
re_free(pRe);
sqlite3_result_error(context, zErr, -1);
@@ -783,67 +740,6 @@ static void re_sql_func(
}
}
#if defined(SQLITE_DEBUG)
/*
** This function is used for testing and debugging only. It is only available
** if the SQLITE_DEBUG compile-time option is used.
**
** Compile a regular expression and then convert the compiled expression into
** text and return that text.
*/
static void re_bytecode_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zPattern;
const char *zErr;
ReCompiled *pRe;
sqlite3_str *pStr;
int i;
int n;
char *z;
zPattern = (const char*)sqlite3_value_text(argv[0]);
if( zPattern==0 ) return;
zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
if( zErr ){
re_free(pRe);
sqlite3_result_error(context, zErr, -1);
return;
}
if( pRe==0 ){
sqlite3_result_error_nomem(context);
return;
}
pStr = sqlite3_str_new(0);
if( pStr==0 ) goto re_bytecode_func_err;
if( pRe->nInit>0 ){
sqlite3_str_appendf(pStr, "INIT ");
for(i=0; i<pRe->nInit; i++){
sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]);
}
sqlite3_str_appendf(pStr, "\n");
}
for(i=0; (unsigned)i<pRe->nState; i++){
sqlite3_str_appendf(pStr, "%-8s %4d\n",
ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
}
n = sqlite3_str_length(pStr);
z = sqlite3_str_finish(pStr);
if( n==0 ){
sqlite3_free(z);
}else{
sqlite3_result_text(context, z, n-1, sqlite3_free);
}
re_bytecode_func_err:
re_free(pRe);
}
#endif /* SQLITE_DEBUG */
/*
** Invoke this routine to register the regexp() function with the
** SQLite database connection.
@@ -858,23 +754,7 @@ int sqlite3_regexp_init(
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused */
rc = sqlite3_create_function(db, "regexp", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, re_sql_func, 0, 0);
if( rc==SQLITE_OK ){
/* The regexpi(PATTERN,STRING) function is a case-insensitive version
** of regexp(PATTERN,STRING). */
rc = sqlite3_create_function(db, "regexpi", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
(void*)db, re_sql_func, 0, 0);
#if defined(SQLITE_DEBUG)
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "regexp_bytecode", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, re_bytecode_func, 0, 0);
}
#endif /* SQLITE_DEBUG */
}
rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS,
0, re_sql_func, 0, 0);
return rc;
}
+4 -18
View File
@@ -323,12 +323,11 @@ static int seriesFilter(
** (8) output in descending order
*/
static int seriesBestIndex(
sqlite3_vtab *pVTab,
sqlite3_vtab *tabUnused,
sqlite3_index_info *pIdxInfo
){
int i, j; /* Loop over constraints */
int idxNum = 0; /* The query plan bitmask */
int bStartSeen = 0; /* EQ constraint seen on the START column */
int unusableMask = 0; /* Mask of unusable constraints */
int nArg = 0; /* Number of arguments that seriesFilter() expects */
int aIdx[3]; /* Constraints on start, stop, and step */
@@ -338,7 +337,7 @@ static int seriesBestIndex(
** are the last three columns in the virtual table. */
assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
(void)tabUnused;
aIdx[0] = aIdx[1] = aIdx[2] = -1;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
@@ -348,7 +347,6 @@ static int seriesBestIndex(
iCol = pConstraint->iColumn - SERIES_COLUMN_START;
assert( iCol>=0 && iCol<=2 );
iMask = 1 << iCol;
if( iCol==0 ) bStartSeen = 1;
if( pConstraint->usable==0 ){
unusableMask |= iMask;
continue;
@@ -363,18 +361,6 @@ static int seriesBestIndex(
pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
}
}
/* The current generate_column() implementation requires at least one
** argument (the START value). Legacy versions assumed START=0 if the
** first argument was omitted. Compile with -DZERO_ARGUMENT_GENERATE_SERIES
** to obtain the legacy behavior */
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
if( !bStartSeen ){
sqlite3_free(pVTab->zErrMsg);
pVTab->zErrMsg = sqlite3_mprintf(
"first argument to \"generate_series()\" missing or unusable");
return SQLITE_ERROR;
}
#endif
if( (unusableMask & ~idxNum)!=0 ){
/* The start, stop, and step columns are inputs. Therefore if there
** are unusable constraints on any of start, stop, or step then
@@ -386,7 +372,7 @@ static int seriesBestIndex(
** the preferred case */
pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
pIdxInfo->estimatedRows = 1000;
if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
if( pIdxInfo->nOrderBy==1 ){
if( pIdxInfo->aOrderBy[0].desc ){
idxNum |= 8;
}else{
@@ -448,7 +434,7 @@ int sqlite3_series_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){
if( sqlite3_libversion_number()<3008012 ){
*pzErrMsg = sqlite3_mprintf(
"generate_series() requires SQLite 3.8.12 or later");
return SQLITE_ERROR;
+1 -1
View File
@@ -71,7 +71,7 @@ struct SHA1Context {
/*
* Hash a single 512-bit block. This is the core of the algorithm.
*/
static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
unsigned int qq[5]; /* a, b, c, d, e; */
static int one = 1;
unsigned int block[16];
+1 -2
View File
@@ -19,7 +19,7 @@
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
** X is NULL.
**
** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
** and returns a hash of their results.
**
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
@@ -436,7 +436,6 @@ static void SHA3Update(
unsigned int nData
){
unsigned int i = 0;
if( aData==0 ) return;
#if SHA3_BYTEORDER==1234
if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
for(; i+7<nData; i+=8){
+44 -81
View File
@@ -30,16 +30,6 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_OMIT_VIRTUALTABLE
#define STMT_NUM_INTEGER_COLUMN 10
typedef struct StmtRow StmtRow;
struct StmtRow {
sqlite3_int64 iRowid; /* Rowid value */
char *zSql; /* column "sql" */
int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */
StmtRow *pNext; /* Next row to return */
};
/* stmt_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a stmt virtual table
*/
@@ -57,7 +47,8 @@ typedef struct stmt_cursor stmt_cursor;
struct stmt_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this cursor */
StmtRow *pRow; /* Current row */
sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
sqlite3_int64 iRowid; /* The rowid */
};
/*
@@ -101,7 +92,7 @@ static int stmtConnect(
"CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
"reprep,run,mem)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -123,7 +114,7 @@ static int stmtDisconnect(sqlite3_vtab *pVtab){
*/
static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
stmt_cursor *pCur;
pCur = sqlite3_malloc64( sizeof(*pCur) );
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((stmt_vtab*)p)->db;
@@ -131,21 +122,10 @@ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
return SQLITE_OK;
}
static void stmtCsrReset(stmt_cursor *pCur){
StmtRow *pRow = 0;
StmtRow *pNext = 0;
for(pRow=pCur->pRow; pRow; pRow=pNext){
pNext = pRow->pNext;
sqlite3_free(pRow);
}
pCur->pRow = 0;
}
/*
** Destructor for a stmt_cursor.
*/
static int stmtClose(sqlite3_vtab_cursor *cur){
stmtCsrReset((stmt_cursor*)cur);
sqlite3_free(cur);
return SQLITE_OK;
}
@@ -156,9 +136,8 @@ static int stmtClose(sqlite3_vtab_cursor *cur){
*/
static int stmtNext(sqlite3_vtab_cursor *cur){
stmt_cursor *pCur = (stmt_cursor*)cur;
StmtRow *pNext = pCur->pRow->pNext;
sqlite3_free(pCur->pRow);
pCur->pRow = pNext;
pCur->iRowid++;
pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
return SQLITE_OK;
}
@@ -172,11 +151,39 @@ static int stmtColumn(
int i /* Which column to return */
){
stmt_cursor *pCur = (stmt_cursor*)cur;
StmtRow *pRow = pCur->pRow;
if( i==STMT_COLUMN_SQL ){
sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT);
}else{
sqlite3_result_int(ctx, pRow->aCol[i]);
switch( i ){
case STMT_COLUMN_SQL: {
sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
break;
}
case STMT_COLUMN_NCOL: {
sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
break;
}
case STMT_COLUMN_RO: {
sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
break;
}
case STMT_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
default: {
assert( i==STMT_COLUMN_MEM );
i = SQLITE_STMTSTATUS_MEMUSED +
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
/* Fall thru */
}
case STMT_COLUMN_NSCAN:
case STMT_COLUMN_NSORT:
case STMT_COLUMN_NAIDX:
case STMT_COLUMN_NSTEP:
case STMT_COLUMN_REPREP:
case STMT_COLUMN_RUN: {
sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
break;
}
}
return SQLITE_OK;
}
@@ -187,7 +194,7 @@ static int stmtColumn(
*/
static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
stmt_cursor *pCur = (stmt_cursor*)cur;
*pRowid = pCur->pRow->iRowid;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
@@ -197,7 +204,7 @@ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
static int stmtEof(sqlite3_vtab_cursor *cur){
stmt_cursor *pCur = (stmt_cursor*)cur;
return pCur->pRow==0;
return pCur->pStmt==0;
}
/*
@@ -212,53 +219,9 @@ static int stmtFilter(
int argc, sqlite3_value **argv
){
stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
sqlite3_stmt *p = 0;
sqlite3_int64 iRowid = 1;
StmtRow **ppRow = 0;
stmtCsrReset(pCur);
ppRow = &pCur->pRow;
for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){
const char *zSql = sqlite3_sql(p);
sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0;
StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql);
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(StmtRow));
if( zSql ){
pNew->zSql = (char*)&pNew[1];
memcpy(pNew->zSql, zSql, nSql);
}
pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p);
pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p);
pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p);
pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0
);
pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_SORT, 0
);
pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_AUTOINDEX, 0
);
pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_VM_STEP, 0
);
pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_REPREPARE, 0
);
pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_RUN, 0
);
pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_MEMUSED, 0
);
pNew->iRowid = iRowid++;
*ppRow = pNew;
ppRow = &pNew->pNext;
}
return SQLITE_OK;
pCur->pStmt = 0;
pCur->iRowid = 0;
return stmtNext(pVtabCursor);
}
/*
-1
View File
@@ -754,7 +754,6 @@ static int vlogCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
*/
int sqlite3_register_vfslog(const char *zArg){
vlog_vfs.pVfs = sqlite3_vfs_find(0);
if( vlog_vfs.pVfs==0 ) return SQLITE_ERROR;
vlog_vfs.base.szOsFile = sizeof(VLogFile) + vlog_vfs.pVfs->szOsFile;
return sqlite3_vfs_register(&vlog_vfs.base, 1);
}
-1
View File
@@ -806,7 +806,6 @@ int sqlite3_vfsstat_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
vstat_vfs.pVfs = sqlite3_vfs_find(0);
if( vstat_vfs.pVfs==0 ) return SQLITE_ERROR;
vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile;
rc = sqlite3_vfs_register(&vstat_vfs.base, 1);
if( rc==SQLITE_OK ){
+4 -18
View File
@@ -57,9 +57,6 @@ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
#endif
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
#elif !defined(NDEBUG)
@@ -564,7 +561,6 @@ static u16 zipfileGetU16(const u8 *aBuf){
** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
*/
static u32 zipfileGetU32(const u8 *aBuf){
if( aBuf==0 ) return 0;
return ((u32)(aBuf[3]) << 24)
+ ((u32)(aBuf[2]) << 16)
+ ((u32)(aBuf[1]) << 8)
@@ -867,7 +863,7 @@ static int zipfileGetEntry(
aRead = (u8*)&aBlob[pNew->cds.iOffset];
}
if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
rc = zipfileReadLFH(aRead, &lfh);
if( rc==SQLITE_OK ){
pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
pNew->iDataOff += lfh.nFile + lfh.nExtra;
@@ -1143,13 +1139,13 @@ static int zipfileReadEOCD(
int nRead; /* Bytes to read from file */
int rc = SQLITE_OK;
memset(pEOCD, 0, sizeof(ZipfileEOCD));
if( aBlob==0 ){
i64 iOff; /* Offset to read from */
i64 szFile; /* Total size of file in bytes */
fseek(pFile, 0, SEEK_END);
szFile = (i64)ftell(pFile);
if( szFile==0 ){
memset(pEOCD, 0, sizeof(ZipfileEOCD));
return SQLITE_OK;
}
nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
@@ -1262,14 +1258,9 @@ static int zipfileFilter(
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
return SQLITE_ERROR;
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
static const u8 aEmptyBlob = 0;
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
int nBlob = sqlite3_value_bytes(argv[0]);
assert( pTab->pFirstEntry==0 );
if( aBlob==0 ){
aBlob = &aEmptyBlob;
nBlob = 0;
}
rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
pCsr->pFreeEntry = pTab->pFirstEntry;
pTab->pFirstEntry = pTab->pLastEntry = 0;
@@ -1495,7 +1486,6 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
static u32 zipfileTime(void){
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
u32 ret;
if( pVfs==0 ) return 0;
if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
i64 ms;
pVfs->xCurrentTimeInt64(pVfs, &ms);
@@ -1943,7 +1933,7 @@ static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
** SELECT zipfile(name,mode,mtime,data) ...
** SELECT zipfile(name,mode,mtime,data,method) ...
*/
static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
ZipfileCtx *p; /* Aggregate function context */
ZipfileEntry e; /* New entry to add to zip archive */
@@ -2118,7 +2108,7 @@ static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
/*
** xFinalize() callback for zipfile aggregate function.
*/
static void zipfileFinal(sqlite3_context *pCtx){
void zipfileFinal(sqlite3_context *pCtx){
ZipfileCtx *p;
ZipfileEOCD eocd;
sqlite3_int64 nZip;
@@ -2175,10 +2165,6 @@ static int zipfileRegister(sqlite3 *db){
zipfileRollback, /* xRollback */
zipfileFindFunction, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollback */
0 /* xShadowName */
};
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
+1 -1
View File
@@ -56,7 +56,7 @@ void usage(const char *zArgv0){
void report_default_vfs(){
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
fprintf(stdout, "default vfs is \"%s\"\n", pVfs ? pVfs->zName : "NULL");
fprintf(stdout, "default vfs is \"%s\"\n", pVfs->zName);
}
void report_rbu_vfs(sqlite3rbu *pRbu){
+1 -1
View File
@@ -50,7 +50,7 @@ do_test 1.1 {
#
ifcapable fts3 {
do_execsql_test 2.0 {
create virtual TABLE ft USING fts4(a, b, languageid='langid');
CREATE VIRTUAL TABLE ft USING fts4(a, b, languageid='langid');
}
do_test 2.1 {
apply_rbu {
-87
View File
@@ -1,87 +0,0 @@
# 2014 August 30
#
# 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.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbubusy
db close
sqlite3_shutdown
test_sqlite3_log xLog
reset_db
set db_sql {
CREATE TABLE t1(a PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1000, 2000, 3000);
}
set rbu_sql {
CREATE TABLE data_t1(a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 2, 3, 0);
INSERT INTO data_t1 VALUES(4, 5, 6, 0);
INSERT INTO data_t1 VALUES(7, 8, 9, 0);
}
do_test 1.1 {
forcedelete rbu.db
sqlite3 rbu rbu.db
rbu eval $rbu_sql
rbu close
db eval $db_sql
} {}
do_execsql_test 1.2 {
BEGIN;
SELECT * FROM t1
} {1000 2000 3000}
do_test 1.3 {
sqlite3rbu rbu test.db rbu.db
rbu step
} {SQLITE_OK}
do_test 1.4 {
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
set rc
} {SQLITE_BUSY}
do_test 1.5 {
rbu step
} {SQLITE_BUSY}
do_test 1.6 {
db eval COMMIT
rbu step
} {SQLITE_BUSY}
catch { rbu close }
do_test 1.7 {
sqlite3rbu rbu test.db rbu.db
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
set rc
} {SQLITE_DONE}
rbu close
db close
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize
finish_test
-207
View File
@@ -1,207 +0,0 @@
# 2021 November 06
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbuexlock
db close
sqlite3_shutdown
sqlite3_config_uri 1
# Create a simple RBU database. That expects to write to a table:
#
# CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
#
proc create_rbu {filename} {
forcedelete $filename
sqlite3 rbu1 $filename
rbu1 eval {
CREATE TABLE data_t1(a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(10, random(), random(), 0);
INSERT INTO data_t1 VALUES(20, random(), random(), 0);
INSERT INTO data_t1 VALUES(30, random(), random(), 0);
INSERT INTO data_t1 VALUES(40, random(), random(), 0);
INSERT INTO data_t1 VALUES(50, random(), random(), 0);
INSERT INTO data_t1 VALUES(60, random(), random(), 0);
INSERT INTO data_t1 VALUES(70, random(), random(), 0);
INSERT INTO data_t1 VALUES(80, random(), random(), 0);
}
rbu1 close
return $filename
}
reset_db
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b INT, c INT);
CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c);
INSERT INTO t1 VALUES(1, 2, 3);
}
create_rbu rbu1.db
do_test 1.1.0 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=1 rbu1.db
rbu step
} SQLITE_OK
do_catchsql_test 1.1.1 { SELECT * FROM t1 } {0 {1 2 3}}
do_test 1.2.0 {
for {set ii 0} {$ii < 10} {incr ii} {
rbu step
}
rbu step
} SQLITE_OK
do_catchsql_test 1.2.1 { SELECT * FROM t1 } {0 {1 2 3}}
do_test 1.2.2 {
db eval {PRAGMA journal_mode}
} {delete}
do_test 1.3.0 {
while {[file exists test.db-wal]==0} {
rbu step
}
} {}
do_catchsql_test 1.3.1 { SELECT * FROM t1 } {1 {database is locked}}
do_test 1.3.2 {
db eval {PRAGMA journal_mode}
} {delete}
do_test 1.4.0 {
rbu step
} SQLITE_OK
do_catchsql_test 1.4.1 { SELECT * FROM t1 } {1 {database is locked}}
do_test 1.4.2 {
db eval {PRAGMA journal_mode}
} {delete}
rbu close
do_test 1.5.0 {
file exists test.db-wal
} {1}
do_test 1.5.1 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=1 rbu1.db
file exists test.db-wal
} 1
do_catchsql_test 1.5.2 { SELECT * FROM t1 } {1 {database is locked}}
do_test 1.5.2 {
db eval {PRAGMA journal_mode}
} {delete}
do_test 1.6.0 {
rbu step
} SQLITE_OK
do_catchsql_test 1.6.1 { SELECT * FROM t1 } {1 {database is locked}}
do_test 1.6.2 {
db eval {PRAGMA journal_mode}
} {delete}
do_test 1.7.0 {
while {[rbu step]=="SQLITE_OK"} {}
rbu close
} SQLITE_DONE
do_catchsql_test 1.7.2 { SELECT count(*) FROM t1 } {0 9}
do_test 1.7.2 {
db eval {PRAGMA journal_mode}
} {delete}
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a PRIMARY KEY, b INT, c INT);
CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c);
INSERT INTO t1 VALUES(1, 2, 3);
}
create_rbu rbu1.db
do_test 2.1.0 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=0 rbu1.db
rbu step
} SQLITE_OK
do_catchsql_test 2.1.1 { SELECT * FROM t1 } {0 {1 2 3}}
do_test 2.2.0 {
for {set ii 0} {$ii < 10} {incr ii} {
rbu step
}
rbu step
} SQLITE_OK
do_catchsql_test 2.2.1 { SELECT * FROM t1 } {0 {1 2 3}}
do_test 2.3.0 {
while {[file exists test.db-wal]==0} {
rbu step
}
} {}
do_test 2.3.1 {
llength [db eval {SELECT * FROM t1}]
} {27}
do_test 2.3.2 {
db eval {PRAGMA journal_mode}
} {wal}
do_test 2.4.0 {
rbu step
} SQLITE_OK
do_test 2.4.1 {
llength [db eval {SELECT * FROM t1}]
} {27}
do_test 2.4.2 {
db eval {PRAGMA journal_mode}
} {wal}
rbu close
do_test 2.5.0 {
db eval {PRAGMA journal_mode}
} {wal}
do_execsql_test 2.5.1 {
DELETE FROM t1;
} {}
create_rbu rbu1.db
do_test 3.1.0 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=0 rbu1.db
rbu step
} SQLITE_ERROR
do_test 3.1.1 {
set rc [catch {rbu close} msg]
lappend rc $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}
db eval {PRAGMA journal_mode=DELETE}
create_rbu rbu1.db
do_test 3.2.0 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=0 rbu1.db
rbu step
} SQLITE_OK
do_test 3.3.1 {
set rc [catch {rbu close} msg]
lappend rc $msg
} {0 SQLITE_OK}
db close
create_rbu rbu1.db
do_test 3.4.0 {
sqlite3rbu rbu file:test.db?rbu_exclusive_checkpoint=0 rbu1.db
rbu step
} SQLITE_OK
rbu close
finish_test
-54
View File
@@ -1,54 +0,0 @@
# 2022 November 07
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rburename
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
}
forcedelete test.db-vacuum
proc my_rename {old new} {
lappend ::my_rename_calls [list [file tail $old] [file tail $new]]
file rename $old $new
}
do_test 1.1 {
sqlite3rbu_vacuum rbu test.db
rbu rename_handler my_rename
while {[rbu step]=="SQLITE_OK"} {}
rbu close
} SQLITE_DONE
do_test 1.2 {
set ::my_rename_calls
} {{test.db-oal test.db-wal}}
proc my_rename {old new} {
error "something went wrong"
}
do_test 1.3 {
sqlite3rbu_vacuum rbu test.db
rbu rename_handler my_rename
while {[rbu step]=="SQLITE_OK"} {}
list [catch { rbu close } msg] $msg
} {1 SQLITE_IOERR}
finish_test
+5 -10
View File
@@ -198,11 +198,7 @@ if {$::tcl_platform(platform)=="unix"} {
} {SQLITE_OK}
do_test 5.$tn.2 { file exists test.db-vacuum } 1
# The result pattern might be 00xxx or 0oxxx depending on which
# version of TCL is being used. So make perm2 into a regexp that
# will match either
regsub {^00} $perm {0.} perm2
do_test 5.$tn.3 { file attributes test.db-vacuum -permissions} /$perm2/
do_test 5.$tn.3 { file attributes test.db-vacuum -permissions} $perm
rbu close
}
}
@@ -227,11 +223,10 @@ do_test 6.1 {
rbu close
} {SQLITE_OK}
do_test 6.2 {
execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
execsql { PRAGMA wal_checkpoint }
execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
} {1}
do_execsql_test 6.2 {
SELECT 1 FROM sqlite_master LIMIT 1;
PRAGMA wal_checkpoint;
} {1 0 4 4}
do_test 6.3 {
sqlite3rbu_vacuum rbu test.db test.db2
+55 -133
View File
@@ -110,13 +110,6 @@
# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
#endif
/*
** Name of the URI option that causes RBU to take an exclusive lock as
** part of the incremental checkpoint operation.
*/
#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint"
/*
** The rbu_state table is used to save the state of a partially applied
** update so that it can be resumed later. The table consists of integer
@@ -393,8 +386,6 @@ struct sqlite3rbu {
int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
i64 nPhaseOneStep;
void *pRenameArg;
int (*xRename)(void*, const char*, const char*);
/* The following state variables are used as part of the incremental
** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
@@ -1203,9 +1194,7 @@ static void rbuTableType(
assert( p->rc==SQLITE_OK );
p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg,
sqlite3_mprintf(
"SELECT "
" (sql COLLATE nocase BETWEEN 'CREATE VIRTUAL' AND 'CREATE VIRTUAM'),"
" rootpage"
"SELECT (sql LIKE 'create virtual%%'), rootpage"
" FROM sqlite_schema"
" WHERE name=%Q", zTab
));
@@ -1565,7 +1554,7 @@ static char *rbuVacuumTableStart(
** the caller has to use an OFFSET clause to extract only the required
** rows from the sourct table, just as it does for an RBU update operation.
*/
static char *rbuVacuumIndexStart(
char *rbuVacuumIndexStart(
sqlite3rbu *p, /* RBU handle */
RbuObjIter *pIter /* RBU iterator object */
){
@@ -2738,7 +2727,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
break;
case RBU_STATE_OALSZ:
pRet->iOalSz = sqlite3_column_int64(pStmt, 1);
pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
break;
case RBU_STATE_PHASEONESTEP:
@@ -2765,25 +2754,19 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
/*
** Open the database handle and attach the RBU database as "rbu". If an
** error occurs, leave an error code and message in the RBU handle.
**
** If argument dbMain is not NULL, then it is a database handle already
** open on the target database. Use this handle instead of opening a new
** one.
*/
static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
assert( dbMain==0 || rbuIsVacuum(p)==0 );
/* Open the RBU database */
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
p->dbMain = dbMain;
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
if( p->zState==0 ){
const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile);
p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
}
}
@@ -3143,31 +3126,15 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){
/*
** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
** successful, or an SQLite error code otherwise.
** Take an EXCLUSIVE lock on the database file.
*/
static int rbuLockDatabase(sqlite3 *db){
int rc = SQLITE_OK;
sqlite3_file *fd = 0;
sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
if( fd->pMethods ){
rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
if( rc==SQLITE_OK ){
rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
}
static void rbuLockDatabase(sqlite3rbu *p){
sqlite3_file *pReal = p->pTargetFd->pReal;
assert( p->rc==SQLITE_OK );
p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
if( p->rc==SQLITE_OK ){
p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
}
return rc;
}
/*
** Return true if the database handle passed as the only argument
** was opened with the rbu_exclusive_checkpoint=1 URI parameter
** specified. Or false otherwise.
*/
static int rbuExclusiveCheckpoint(sqlite3 *db){
const char *zUri = sqlite3_db_filename(db, 0);
return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
}
#if defined(_WIN32_WCE)
@@ -3225,38 +3192,49 @@ static void rbuMoveOalFile(sqlite3rbu *p){
** In order to ensure that there are no database readers, an EXCLUSIVE
** lock is obtained here before the *-oal is moved to *-wal.
*/
sqlite3 *dbMain = 0;
rbuFileSuffix3(zBase, zWal);
rbuFileSuffix3(zBase, zOal);
/* Re-open the databases. */
rbuObjIterFinalize(&p->objiter);
sqlite3_close(p->dbRbu);
sqlite3_close(p->dbMain);
p->dbMain = 0;
p->dbRbu = 0;
dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
if( dbMain ){
assert( p->rc==SQLITE_OK );
p->rc = rbuLockDatabase(dbMain);
}
rbuLockDatabase(p);
if( p->rc==SQLITE_OK ){
p->rc = p->xRename(p->pRenameArg, zOal, zWal);
}
rbuFileSuffix3(zBase, zWal);
rbuFileSuffix3(zBase, zOal);
if( p->rc!=SQLITE_OK
|| rbuIsVacuum(p)
|| rbuExclusiveCheckpoint(dbMain)==0
){
sqlite3_close(dbMain);
dbMain = 0;
}
/* Re-open the databases. */
rbuObjIterFinalize(&p->objiter);
sqlite3_close(p->dbRbu);
sqlite3_close(p->dbMain);
p->dbMain = 0;
p->dbRbu = 0;
if( p->rc==SQLITE_OK ){
rbuOpenDatabase(p, dbMain, 0);
rbuSetupCheckpoint(p, 0);
#if defined(_WIN32_WCE)
{
LPWSTR zWideOal;
LPWSTR zWideWal;
zWideOal = rbuWinUtf8ToUnicode(zOal);
if( zWideOal ){
zWideWal = rbuWinUtf8ToUnicode(zWal);
if( zWideWal ){
if( MoveFileW(zWideOal, zWideWal) ){
p->rc = SQLITE_OK;
}else{
p->rc = SQLITE_IOERR;
}
sqlite3_free(zWideWal);
}else{
p->rc = SQLITE_IOERR_NOMEM;
}
sqlite3_free(zWideOal);
}else{
p->rc = SQLITE_IOERR_NOMEM;
}
}
#else
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
#endif
if( p->rc==SQLITE_OK ){
rbuOpenDatabase(p, 0);
rbuSetupCheckpoint(p, 0);
}
}
}
@@ -3982,7 +3960,6 @@ static sqlite3rbu *openRbuHandle(
/* Create the custom VFS. */
memset(p, 0, sizeof(sqlite3rbu));
sqlite3rbu_rename_handler(p, 0, 0);
rbuCreateVfs(p);
/* Open the target, RBU and state databases */
@@ -4008,9 +3985,9 @@ static sqlite3rbu *openRbuHandle(
** If this is the case, it will have been checkpointed and deleted
** when the handle was closed and a second attempt to open the
** database may succeed. */
rbuOpenDatabase(p, 0, &bRetry);
rbuOpenDatabase(p, &bRetry);
if( bRetry ){
rbuOpenDatabase(p, 0, 0);
rbuOpenDatabase(p, 0);
}
}
@@ -4105,14 +4082,6 @@ static sqlite3rbu *openRbuHandle(
}else if( p->eStage==RBU_STAGE_MOVE ){
/* no-op */
}else if( p->eStage==RBU_STAGE_CKPT ){
if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){
/* If the rbu_exclusive_checkpoint=1 URI parameter was specified
** and an incremental checkpoint is being resumed, attempt an
** exclusive lock on the db file. If this fails, so be it. */
p->eStage = RBU_STAGE_DONE;
rbuLockDatabase(p->dbMain);
p->eStage = RBU_STAGE_CKPT;
}
rbuSetupCheckpoint(p, pState);
}else if( p->eStage==RBU_STAGE_DONE ){
p->rc = SQLITE_DONE;
@@ -4150,6 +4119,7 @@ sqlite3rbu *sqlite3rbu_open(
const char *zState
){
if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
/* TODO: Check that zTarget and zRbu are non-NULL */
return openRbuHandle(zTarget, zRbu, zState);
}
@@ -4374,54 +4344,6 @@ int sqlite3rbu_savestate(sqlite3rbu *p){
return rc;
}
/*
** Default xRename callback for RBU.
*/
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
int rc = SQLITE_OK;
#if defined(_WIN32_WCE)
{
LPWSTR zWideOld;
LPWSTR zWideNew;
zWideOld = rbuWinUtf8ToUnicode(zOld);
if( zWideOld ){
zWideNew = rbuWinUtf8ToUnicode(zNew);
if( zWideNew ){
if( MoveFileW(zWideOld, zWideNew) ){
rc = SQLITE_OK;
}else{
rc = SQLITE_IOERR;
}
sqlite3_free(zWideNew);
}else{
rc = SQLITE_IOERR_NOMEM;
}
sqlite3_free(zWideOld);
}else{
rc = SQLITE_IOERR_NOMEM;
}
}
#else
rc = rename(zOld, zNew) ? SQLITE_IOERR : SQLITE_OK;
#endif
return rc;
}
void sqlite3rbu_rename_handler(
sqlite3rbu *pRbu,
void *pArg,
int (*xRename)(void *pArg, const char *zOld, const char *zNew)
){
if( xRename ){
pRbu->xRename = xRename;
pRbu->pRenameArg = pArg;
}else{
pRbu->xRename = xDefaultRename;
pRbu->pRenameArg = 0;
}
}
/**************************************************************************
** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour
** of a standard VFS in the following ways:
-28
View File
@@ -544,34 +544,6 @@ SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo);
SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
/*
** As part of applying an RBU update or performing an RBU vacuum operation,
** the system must at one point move the *-oal file to the equivalent *-wal
** path. Normally, it does this by invoking POSIX function rename(2) directly.
** Except on WINCE platforms, where it uses win32 API MoveFileW(). This
** function may be used to register a callback that the RBU module will invoke
** instead of one of these APIs.
**
** If a callback is registered with an RBU handle, it invokes it instead
** of rename(2) when it needs to move a file within the file-system. The
** first argument passed to the xRename() callback is a copy of the second
** argument (pArg) passed to this function. The second is the full path
** to the file to move and the third the full path to which it should be
** moved. The callback function should return SQLITE_OK to indicate
** success. If an error occurs, it should return an SQLite error code.
** In this case the RBU operation will be abandoned and the error returned
** to the RBU user.
**
** Passing a NULL pointer in place of the xRename argument to this function
** restores the default behaviour.
*/
SQLITE_API void sqlite3rbu_rename_handler(
sqlite3rbu *pRbu,
void *pArg,
int (*xRename)(void *pArg, const char *zOld, const char *zNew)
);
/*
** Create an RBU VFS named zName that accesses the underlying file-system
** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
+3 -54
View File
@@ -26,14 +26,6 @@
# endif
#endif
#include <assert.h>
#include <string.h>
typedef struct TestRbu TestRbu;
struct TestRbu {
sqlite3rbu *pRbu;
Tcl_Interp *interp;
Tcl_Obj *xRename;
};
/* From main.c */
extern const char *sqlite3ErrName(int);
@@ -63,20 +55,6 @@ void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
Tcl_DecrRefCount(pScript);
}
static int xRenameCallback(void *pArg, const char *zOld, const char *zNew){
int rc = SQLITE_OK;
TestRbu *pTest = (TestRbu*)pArg;
Tcl_Obj *pEval = Tcl_DuplicateObj(pTest->xRename);
Tcl_IncrRefCount(pEval);
Tcl_ListObjAppendElement(pTest->interp, pEval, Tcl_NewStringObj(zOld, -1));
Tcl_ListObjAppendElement(pTest->interp, pEval, Tcl_NewStringObj(zNew, -1));
rc = Tcl_EvalObjEx(pTest->interp, pEval, TCL_GLOBAL_ONLY);
Tcl_DecrRefCount(pEval);
return rc ? SQLITE_IOERR : SQLITE_OK;
}
static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
ClientData clientData,
@@ -85,8 +63,7 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
Tcl_Obj *CONST objv[]
){
int ret = TCL_OK;
TestRbu *pTest = (TestRbu*)clientData;
sqlite3rbu *pRbu = pTest->pRbu;
sqlite3rbu *pRbu = (sqlite3rbu*)clientData;
struct RbuCmd {
const char *zName;
int nArg;
@@ -105,7 +82,6 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
{"temp_size_limit", 3, "LIMIT"}, /* 10 */
{"temp_size", 2, ""}, /* 11 */
{"dbRbu_eval", 3, "SQL"}, /* 12 */
{"rename_handler", 3, "SCRIPT"},/* 13 */
{0,0,0}
};
int iCmd;
@@ -151,8 +127,6 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
}
ret = TCL_ERROR;
}
if( pTest->xRename ) Tcl_DecrRefCount(pTest->xRename);
ckfree(pTest);
break;
}
@@ -240,19 +214,6 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
break;
}
case 13: /* rename_handler */ {
Tcl_Obj *pScript = objv[2];
assert( !sqlite3_stricmp(aCmd[13].zName, "rename_handler") );
if( Tcl_GetCharLength(pScript)==0 ){
sqlite3rbu_rename_handler(pRbu, 0, 0);
}else{
pTest->xRename = Tcl_DuplicateObj(pScript);
Tcl_IncrRefCount(pTest->xRename);
sqlite3rbu_rename_handler(pRbu, pTest, xRenameCallback);
}
break;
}
default: /* seems unlikely */
assert( !"cannot happen" );
break;
@@ -261,18 +222,6 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
return ret;
}
static void createRbuWrapper(
Tcl_Interp *interp,
const char *zCmd,
sqlite3rbu *pRbu
){
TestRbu *pTest = (TestRbu*)ckalloc(sizeof(TestRbu));
memset(pTest, 0, sizeof(TestRbu));
pTest->pRbu = pRbu;
pTest->interp = interp;
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pTest, 0);
}
/*
** Tclcmd: sqlite3rbu CMD <target-db> <rbu-db> ?<state-db>?
*/
@@ -298,7 +247,7 @@ static int SQLITE_TCLAPI test_sqlite3rbu(
if( objc==5 ) zStateDb = Tcl_GetString(objv[4]);
pRbu = sqlite3rbu_open(zTarget, zRbu, zStateDb);
createRbuWrapper(interp, zCmd, pRbu);
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
@@ -327,7 +276,7 @@ static int SQLITE_TCLAPI test_sqlite3rbu_vacuum(
if( zStateDb && zStateDb[0]=='\0' ) zStateDb = 0;
pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
createRbuWrapper(interp, zCmd, pRbu);
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
-277
View File
@@ -1,277 +0,0 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recover1
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
compare_result $db1 $db2 "PRAGMA page_size"
compare_result $db1 $db2 "PRAGMA auto_vacuum"
compare_result $db1 $db2 "PRAGMA encoding"
compare_result $db1 $db2 "PRAGMA user_version"
compare_result $db1 $db2 "PRAGMA application_id"
}
proc do_recover_test {tn} {
forcedelete test.db2
forcedelete rstate.db
uplevel [list do_test $tn.1 {
set R [sqlite3_recover_init db main test.db2]
$R config testdb rstate.db
$R run
$R finish
} {}]
sqlite3 db2 test.db2
uplevel [list do_test $tn.2 [list compare_dbs db db2] {}]
db2 close
forcedelete test.db2
forcedelete rstate.db
uplevel [list do_test $tn.3 {
set ::sqlhook [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config testdb rstate.db
$R config rowids 1
$R run
$R finish
} {}]
sqlite3 db2 test.db2
execsql [join $::sqlhook ";"] db2
db2 close
sqlite3 db2 test.db2
uplevel [list do_test $tn.4 [list compare_dbs db db2] {}]
db2 close
}
proc my_sql_hook {sql} {
lappend ::sqlhook $sql
return 0
}
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10
)
INSERT INTO t1 SELECT i*2, hex(randomblob(250)) FROM s;
INSERT INTO t2 SELECT * FROM t1;
}
do_recover_test 1
do_execsql_test 2.0 {
ALTER TABLE t1 ADD COLUMN c DEFAULT 'xyz'
}
do_recover_test 2
do_execsql_test 3.0 {
CREATE INDEX i1 ON t1(c);
}
do_recover_test 3
do_execsql_test 4.0 {
CREATE VIEW v1 AS SELECT * FROM t2;
}
do_recover_test 4
do_execsql_test 5.0 {
CREATE UNIQUE INDEX i2 ON t1(c, b);
}
do_recover_test 5
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INT,
c TEXT,
d INT GENERATED ALWAYS AS (a*abs(b)) VIRTUAL,
e TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED,
f TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED
);
INSERT INTO t1 VALUES(1, 2, 'hello world');
}
do_recover_test 6
do_execsql_test 7.0 {
CREATE TABLE t2(i, j GENERATED ALWAYS AS (i+1) STORED, k);
INSERT INTO t2 VALUES(10, 'ten');
}
do_execsql_test 7.1 {
SELECT * FROM t2
} {10 11 ten}
do_recover_test 7.2
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.0 {
CREATE TABLE x1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<2
)
INSERT INTO x1(b, c) SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s;
CREATE INDEX x1b ON x1(b);
CREATE INDEX x1cb ON x1(c, b);
DELETE FROM x1 WHERE a>50;
ANALYZE;
}
do_recover_test 8
#-------------------------------------------------------------------------
reset_db
ifcapable fts5 {
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE ft5 USING fts5(a, b);
INSERT INTO ft5 VALUES('hello', 'world');
}
do_recover_test 9
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.1 {
CREATE TABLE x1(a PRIMARY KEY, str TEXT) WITHOUT ROWID;
INSERT INTO x1 VALUES(1, '
\nhello\012world(\n0)(\n1)
');
INSERT INTO x1 VALUES(2, '
\nhello
');
}
do_execsql_test 10.2 "
INSERT INTO x1 VALUES(3, '\012hello there\015world');
INSERT INTO x1 VALUES(4, '\015hello there\015world');
"
do_recover_test 10
#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.1 {
PRAGMA page_size = 4096;
PRAGMA encoding='utf16';
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
INSERT INTO u1 VALUES('edvin marton', 'bond');
INSERT INTO u1 VALUES(1, 4.0);
}
do_execsql_test 11.1a {
PRAGMA auto_vacuum;
} {2}
do_recover_test 11
do_test 12.1 {
set R [sqlite3_recover_init db "" test.db2]
$R config lostandfound ""
$R config invalid xyz
} {12}
do_test 12.2 {
$R run
$R run
} {0}
do_test 12.3 {
$R finish
} {}
#-------------------------------------------------------------------------
reset_db
file_control_reservebytes db 16
do_execsql_test 12.1 {
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
CREATE UNIQUE INDEX i1 ON u1(u, v);
INSERT INTO u1 VALUES(1, 2), (3, 4);
CREATE TABLE u2(u, v);
CREATE UNIQUE INDEX i2 ON u1(u, v);
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
}
do_recover_test 12
#-------------------------------------------------------------------------
reset_db
sqlite3 db ""
do_recover_test 13
do_execsql_test 14.1 {
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 45;
PRAGMA application_id = 22;
CREATE TABLE u1(u, v);
CREATE UNIQUE INDEX i1 ON u1(u, v);
INSERT INTO u1 VALUES(1, 2), (3, 4);
CREATE TABLE u2(u, v);
CREATE UNIQUE INDEX i2 ON u1(u, v);
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000)));
INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000)));
}
do_recover_test 14
#-------------------------------------------------------------------------
reset_db
execsql {
PRAGMA journal_mode=OFF;
PRAGMA mmap_size=10;
}
do_execsql_test 15.1 {
CREATE TABLE t1(x);
} {}
do_recover_test 15
finish_test
-14
View File
@@ -1,14 +0,0 @@
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
if {[info commands sqlite3_recover_init]==""} {
finish_test
return -code return
}
-50
View File
@@ -1,50 +0,0 @@
# 2019 April 23
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_ROWIDS option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverclobber
proc recover {db output} {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
}
forcedelete test.db2
do_execsql_test 1.0 {
ATTACH 'test.db2' AS aux;
CREATE TABLE aux.x1(x, one);
INSERT INTO x1 VALUES(1, 'one'), (2, 'two'), (3, 'three');
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
DETACH aux;
}
breakpoint
do_test 1.1 {
recover db test.db2
} {}
do_execsql_test 1.2 {
ATTACH 'test.db2' AS aux;
SELECT * FROM aux.t1;
} {1 1 2 2 3 3 4 4}
do_catchsql_test 1.3 {
SELECT * FROM aux.x1;
} {1 {no such table: aux.x1}}
finish_test
-67
View File
@@ -1,67 +0,0 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt
database_may_be_corrupt
do_execsql_test 1.0 {
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(100)), randomblob(200));
CREATE INDEX i1 ON t1(b, c);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(100)), randomblob(200));
ANALYZE;
PRAGMA writable_schema = 1;
DELETE FROM sqlite_schema WHERE name='t2';
}
do_test 1.1 {
expr [file size test.db]>3072
} {1}
proc toggle_bit {blob bit} {
set byte [expr {$bit / 8}]
set bit [expr {$bit & 0x0F}]
binary scan $blob a${byte}ca* A x B
set x [expr {$x ^ (1 << $bit)}]
binary format a*ca* $A $x $B
}
db_save_and_close
for {set ii 0} {$ii < 10000} {incr ii} {
db_restore_and_reopen
db func toggle_bit toggle_bit
set bitsperpage [expr 512*8]
set pg [expr {($ii / $bitsperpage)+1}]
set byte [expr {$ii % $bitsperpage}]
db eval {
UPDATE sqlite_dbpage SET data = toggle_bit(data, $byte) WHERE pgno=$pg
}
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
do_test 1.2.$ii {
$R finish
} {}
}
finish_test
-289
View File
@@ -1,289 +0,0 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recovercorrupt2
do_execsql_test 1.0 {
PRAGMA page_size = 512;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(100)), randomblob(200));
CREATE INDEX i1 ON t1(b, c);
CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(100)), randomblob(200));
ANALYZE;
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET sql = 'CREATE INDEX i1 ON o(world)' WHERE name='i1';
DELETE FROM sqlite_schema WHERE name='sqlite_stat4';
}
do_test 1.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 1.2 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c)}
{CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID}
{CREATE TABLE sqlite_stat1(tbl,idx,stat)}
}
db2 close
do_execsql_test 1.3 {
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET sql = 'CREATE TABLE t2 syntax error!' WHERE name='t2';
}
do_test 1.4 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 1.5 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c)}
{CREATE TABLE sqlite_stat1(tbl,idx,stat)}
}
db2 close
#-------------------------------------------------------------------------
#
reset_db
do_test 2.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 8192 pagesize 4096 filename x3.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 63 00 0d 00 00 00 01 0f d8 00 0f d8 00 00 ..c.............
| 4048: 00 00 00 00 00 00 00 00 26 01 06 17 11 11 01 39 ........&......9
| 4064: 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 54 45 tablet1t1.CREATE
| 4080: 20 54 41 42 4c 45 20 74 31 28 61 2c 62 2c 63 29 TABLE t1(a,b,c)
| page 2 offset 4096
| 0: 0d 00 00 00 01 0f ce 00 0f ce 00 00 00 00 00 00 ................
| 4032: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ..............(.
| 4048: ff ff ff ff ff ff ff 28 04 27 25 23 61 61 61 61 .........'%#aaaa
| 4064: 61 61 61 61 61 61 61 61 61 62 62 62 62 62 62 62 aaaaaaaaabbbbbbb
| 4080: 62 62 62 62 62 63 63 63 63 63 63 63 63 63 63 63 bbbbbccccccccccc
| end x3.db
}]} {}
do_test 2.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
sqlite3 db2 test.db2
do_execsql_test -db db2 2.2 {
SELECT sql FROM sqlite_schema
} {
{CREATE TABLE t1(a,b,c)}
}
do_execsql_test -db db2 2.3 {
SELECT * FROM t1
} {}
db2 close
#-------------------------------------------------------------------------
#
reset_db
do_test 3.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 4096 pagesize 1024 filename corrupt032.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 04 00 01 01 08 40 20 20 00 00 00 02 00 00 00 03 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................
| 96: 00 2e 24 80 0d 00 00 00 01 03 d4 00 03 d4 00 00 ..$.............
| 976: 00 00 00 00 22 01 06 17 11 11 01 31 74 61 62 6c ...........1tabl
| 992: 65 74 31 74 31 02 43 52 45 41 54 45 20 54 41 42 et1t1.CREATE TAB
| 1008: 4c 45 20 74 31 28 78 29 00 00 00 00 00 00 00 00 LE t1(x)........
| page 2 offset 1024
| 0: 0d 00 00 00 01 02 06 00 02 06 00 00 00 00 00 00 ................
| 512: 00 00 00 00 00 00 8b 60 01 03 97 46 00 00 00 00 .......`...F....
| 1008: 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 ................
| end corrupt032.txt.db
}]} {}
do_test 3.1 {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} {}
#-------------------------------------------------------------------------
#
reset_db
do_test 4.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 4096 pagesize 4096 filename crash-00f2d3627f1b43.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 00 01 01 02 00 40 20 20 01 00 ff 00 42 01 10 01 .....@ ....B...
| 32: ef 00 00 87 00 ff ff ff f0 01 01 10 ff ff 00 00 ................
| end crash-00f2d3627f1b43.db
}]} {}
do_test 4.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {1 {unable to open database file}}
#-------------------------------------------------------------------------
#
reset_db
do_test 5.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 16384 pagesize 4096 filename crash-7b75760a4c5f15.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 ................
| 96: 00 00 00 00 0d 00 00 00 03 0f 4e 00 0f bc 0f 90 ..........N.....
| 112: 0f 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .N..............
| 3904: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 03 ..............@.
| 3920: 06 17 11 11 01 6d 74 61 62 6c 65 74 32 74 32 04 .....mtablet2t2.
| 3936: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 CREATE TABLE t2(
| 3952: 78 2c 79 2c 7a 20 50 52 49 4d 41 52 59 20 4b 45 x,y,z PRIMARY KE
| 3968: 59 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 Y) WITHOUT ROWID
| 3984: 2a 02 06 17 13 11 01 3f 69 6e 64 65 78 74 31 61 *......?indext1a
| 4000: 74 31 03 43 52 45 41 54 45 20 49 4e 44 45 58 20 t1.CREATE INDEX
| 4016: 74 31 61 20 4f 4e 20 74 31 28 61 29 42 01 06 17 t1a ON t1(a)B...
| 4032: 11 11 01 71 74 61 62 6c 65 74 31 74 31 02 43 52 ...qtablet1t1.CR
| 4048: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 61 20 EATE TABLE t1(a
| 4064: 49 4e 54 2c 62 20 54 45 58 54 2c 63 20 42 4c 4f INT,b TEXT,c BLO
| 4080: 42 2c 64 20 52 45 41 4c 29 20 53 54 52 49 43 54 B,d REAL) STRICT
| page 2 offset 4096
| 0: 0d 00 00 00 14 0c ae 00 0f df 0f bd 0f 9a 0f 76 ...............v
| 16: 0f 51 0f 2b 0f 04 0e dc 0e b3 0e 89 0e 5e 0e 32 .Q.+.........^.2
| 32: 0e 05 0d 1a 0d a8 0d 78 0d 47 0d 15 0c e2 00 00 .......x.G......
| 3232: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 14 ..............2.
| 3248: 05 06 3f 34 07 15 f4 c9 23 af e2 b3 b6 61 62 63 ..?4....#....abc
| 3264: 30 32 30 78 79 7a 01 00 00 00 00 00 00 00 00 00 020xyz..........
| 3280: 00 00 00 00 00 00 00 00 00 00 c3 b0 96 7e fb 4e .............~.N
| 3296: c5 4c 31 13 05 06 1f 32 07 dd f2 2a a5 7e b2 4d .L1....2...*.~.M
| 3312: 82 61 62 63 30 31 39 78 79 7a 01 00 00 00 00 00 .abc019xyz......
| 3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 a3 d6 ................
| 3344: e9 f1 c2 fd f3 30 12 05 06 1f 30 07 8f 8f f5 c4 .....0....0.....
| 3360: 35 b6 7f 8d 61 62 63 30 31 38 00 00 00 00 00 00 5...abc018......
| 3376: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 ...............C
| 3392: b2 13 1f 9d 56 8a 47 21 b1 05 06 1f 2e 07 7f 46 ....V.G!.......F
| 3408: 91 03 3f 97 fb f7 61 62 63 30 00 00 00 00 00 00 ..?...abc0......
| 3440: c3 bb d8 96 86 c2 e8 2b 2e 10 05 06 1f 2c 07 6d .......+.....,.m
| 3456: 85 7b ce d0 32 d2 54 61 62 63 30 00 00 00 00 00 ....2.Tabc0.....
| 3488: 43 a1 eb 44 14 dc 03 7b 2d 0f 05 06 1f 2a 07 d9 C..D....-....*..
| 3504: ab ec bf 34 51 70 f3 61 62 63 30 31 35 78 79 7a ...4Qp.abc015xyz
| 3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 ................
| 3536: b6 3d f4 46 b1 6a af 2c 0e 05 06 1f 28 07 36 75 .=.F.j.,....(.6u
| 3552: e9 a2 bd 05 04 ea 61 62 63 30 31 34 78 79 7a 00 ......abc014xyz.
| 3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 c3 ab 23 ...............#
| 3584: a7 6a 34 ca f8 2b 0d 05 06 1f 26 07 48 45 ab e0 .j4..+....&.HE..
| 3600: 8c 7c ff 0c 61 62 63 30 31 33 78 79 7a 00 00 00 .|..abc013xyz...
| 3616: 00 00 00 00 0d d0 00 00 00 00 43 b8 d3 93 f4 92 ..........C.....
| 3632: 5b 7a 2a 0c 05 06 1f 24 07 be 6d 1e db 61 5d 80 [z*....$..m..a].
| 3648: 9f 61 62 63 30 31 32 78 79 7a 00 00 00 00 00 00 .abc012xyz......
| 3664: 00 00 00 00 00 00 43 b5 a1 a4 af 7b c6 60 29 0b ......C......`).
| 3680: 05 06 1f 22 07 6e a2 a3 64 68 d4 a6 bd 61 62 63 .....n..dh...abc
| 3696: 30 31 31 78 79 7a 00 00 00 00 00 00 00 00 00 00 011xyz..........
| 3712: 00 c3 c4 1e ff 0f fc e6 ff 28 0a 05 06 1f 20 07 .........(.... .
| 3728: 50 f9 4a bb a5 7a 1e ca 61 62 63 30 31 30 78 79 P.J..z..abc010xy
| 3744: 7a 00 00 00 00 00 00 00 00 00 00 c3 a7 90 ed d9 z...............
| 3760: 5c 2c d5 27 09 05 06 1f 1e 07 90 8e 1d d9 1c 3a .,.'...........:
| 3776: e8 c1 61 62 63 30 30 39 78 79 7a 00 00 00 00 00 ..abc009xyz.....
| 3792: 00 00 00 00 43 a7 97 87 cf b0 ff 79 26 08 05 06 ....C......y&...
| 3808: 1f 1c 07 86 65 f6 7c 50 7a 2c 76 61 62 63 30 30 ....e.|Pz,vabc00
| 3824: 38 78 79 7a 00 00 00 00 00 00 00 00 c3 b0 e3 4c 8xyz...........L
| 3840: 4f d3 41 b5 25 07 05 06 1f 1a 07 8b 20 e5 68 11 O.A.%....... .h.
| 3856: 13 55 87 61 62 63 30 30 37 78 79 7a 00 00 00 00 .U.abc007xyz....
| 3872: 00 00 00 c3 b6 a3 74 f1 9c 33 f8 24 06 05 06 1f ......t..3.$....
| 3888: 18 07 97 3c bc 34 49 94 54 ab 61 62 63 30 30 36 ...<.4I.T.abc006
| 3904: 78 79 7a 00 00 00 00 00 00 c3 88 00 c2 ca 4c 4d xyz...........LM
| 3920: d3 23 05 05 06 1f 16 07 59 37 11 10 e9 e5 3d d5 .#......Y7....=.
| 3936: 61 62 63 30 30 35 78 79 7a 00 00 00 00 00 c3 c0 abc005xyz.......
| 3952: 15 12 67 ed 4b 79 22 04 05 06 1f 14 07 93 39 01 ..g.Ky........9.
| 3968: 7f b8 c7 99 58 61 62 63 30 30 34 78 79 7a 00 00 ....Xabc004xyz..
| 3984: 09 c0 43 bf e0 e7 6d 70 fd 61 21 03 05 06 1f 12 ..C...mp.a!.....
| 4000: 07 b6 df 8d 8b 27 08 22 5a 61 62 63 30 30 33 78 .....'..Zabc003x
| 4016: 79 7a 00 00 00 c3 c7 ea 0f dc dd 32 22 20 02 05 yz.........2. ..
| 4032: 06 1f 10 07 2f a6 da 71 df 66 b3 b5 61 62 63 30 ..../..q.f..abc0
| 4048: 30 32 78 79 7a 00 00 c3 ce d9 8d e9 ec 20 45 1f 02xyz........ E.
| 4064: 01 05 06 1f 0e 07 5a 47 53 20 3b 48 8f c0 61 62 ......ZGS ;H..ab
| 4080: 63 30 30 31 78 79 7a 00 c3 c9 e6 81 f8 d9 24 04 c001xyz.......$.
| page 3 offset 8192
| 0: 0a 00 00 00 14 0e fd 00 0f f3 0f e6 0f d9 0f cc ................
| 16: 0f bf 0f b2 0f a5 0f 98 0f 8b 0f 7e 0f 71 0f 64 ...........~.q.d
| 32: 0f 57 0f 4a 0f 3d 0f 30 0f 24 00 00 00 00 00 00 .W.J.=.0.$......
| 3824: 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 03 06 ................
| 3840: 01 7f 46 91 03 3f 97 fb f7 11 0c 03 06 01 6e a2 ..F..?........n.
| 3856: a3 64 68 d4 a6 bd 0b 0c 03 06 01 6d 85 7b ce d0 .dh........m....
| 3872: 32 d2 54 10 0b 03 06 09 5a 47 53 20 3b 48 8f c0 2.T.....ZGS ;H..
| 3888: 0c 03 06 01 59 37 11 10 e9 e5 3d d5 05 0c 03 06 ....Y7....=.....
| 3904: 01 50 f9 4a bb a5 7a 1e ca 0a 0c 03 06 01 48 45 .P.J..z.......HE
| 3920: ab e0 8c 7c ff 0c 0d 0c 03 06 01 36 75 e9 a2 bd ...|.......6u...
| 3936: 05 04 ea 0e 0c 03 06 01 2f a6 da 71 df 66 b3 b5 ......../..q.f..
| 3952: 02 0c 03 06 01 15 f4 c9 23 af e2 b3 b6 14 0c 03 ........#.......
| 3968: 06 01 dd f2 2a a5 7e b2 4d 82 13 0c 03 06 01 d9 ....*.~.M.......
| 3984: ab ec bf 34 51 70 f3 0f 0c 03 06 01 be 6d 1e db ...4Qp.......m..
| 4000: 61 5d 80 9f 0c 0c 03 06 01 b6 df 8d 8b 27 08 22 a]...........'..
| 4016: 5a 03 0c 03 06 01 97 3c bc 34 49 94 54 ab 06 0c Z......<.4I.T...
| 4032: 03 06 01 93 39 01 7f b8 c7 99 58 04 0c 03 06 01 ....9.....X.....
| 4048: 90 8e 1d d9 1c 3a e8 c1 09 0c 03 06 01 8f 8f f5 .....:..........
| 4064: c4 35 b6 7f 8d 12 0c 03 06 01 8b 20 e5 68 11 13 .5......... .h..
| 4080: 55 87 07 0c 03 06 01 86 65 f6 7c 50 7a 2b 06 08 U.......e.|Pz+..
| page 4 offset 12288
| 0: 0a 00 00 00 14 0f 62 00 0f 7a 0f a1 0f c9 0f d9 ......b..z......
| 16: 0f 81 0f d1 0f f1 0f f9 0f e1 0f 89 0e 6a 0f c1 .............j..
| 32: 0f 91 0f 99 0f b9 0f 72 0f 62 0f e9 0f b1 0f a9 .......r.b......
| 3936: 00 00 07 04 01 01 01 11 0e 9e 07 04 01 01 01 0b ................
| 3952: 31 16 07 04 01 01 01 10 37 36 06 04 09 01 01 ab 1.......76......
| 3968: 58 07 04 01 01 01 05 1c 28 07 04 01 01 01 0a 10 X.......(.......
| 3984: cf 07 04 01 01 01 0d b2 e3 07 04 01 01 01 0e d3 ................
| 4000: f2 07 04 01 01 01 02 41 ad 07 04 01 01 01 14 3e .......A.......>
| 4016: 22 07 04 01 01 01 13 27 45 07 04 01 01 01 0f ad .......'E.......
| 4032: dd 07 04 01 01 01 0c 2e a1 07 04 01 01 01 03 df ................
| 4048: e1 07 04 01 01 01 06 59 a7 07 04 01 01 01 04 27 .......Y.......'
| 4064: bd 07 04 01 01 01 09 d0 e0 07 04 01 01 01 12 39 ...............9
| 4080: 4f 07 04 01 01 01 07 c4 11 06 04 00 00 00 00 00 O...............
| end crash-7b75760a4c5f15.db
}]} {}
do_test 5.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
finish_test
-84
View File
@@ -1,84 +0,0 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverfault
#--------------------------------------------------------------------------
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
#--------------------------------------------------------------------------
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, hex(randomblob(1000)), randomblob(2000));
CREATE INDEX i1 ON t1(b, c);
ANALYZE;
}
faultsim_save_and_close
do_faultsim_test 1 -faults oom* -prep {
catch { db2 close }
faultsim_restore_and_reopen
} -body {
set R [sqlite3_recover_init db main test.db2]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 test.db2
compare_dbs db db2
db2 close
}
}
faultsim_restore_and_reopen
do_execsql_test 2.0 {
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(2, hex(randomblob(1000)), hex(randomblob(2000)));
PRAGMA writable_schema = 1;
DELETE FROM sqlite_schema WHERE name='t2';
}
faultsim_save_and_close
do_faultsim_test 2 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
}
finish_test
-102
View File
@@ -1,102 +0,0 @@
# 2022 August 28
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverfault2
#--------------------------------------------------------------------------
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
#--------------------------------------------------------------------------
do_execsql_test 1.0 "
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(2, '\012hello\015world\012today\n');
"
faultsim_save_and_close
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_faultsim_test 1 -faults oom* -prep {
catch { db2 close }
faultsim_restore_and_reopen
set ::lSql [list]
} -body {
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 ""
db2 eval [join $::lSql ";"]
compare_dbs db db2
db2 close
}
}
ifcapable utf16 {
reset_db
do_execsql_test 2.0 "
PRAGMA encoding='utf-16';
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(2, '\012hello\015world\012today\n');
"
faultsim_save_and_close
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_faultsim_test 2 -faults oom-t* -prep {
catch { db2 close }
faultsim_restore_and_reopen
set ::lSql [list]
} -body {
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R run
$R finish
} -test {
faultsim_test_result {0 {}} {1 {}}
if {$testrc==0} {
sqlite3 db2 ""
db2 eval [join $::lSql ";"]
compare_dbs db db2
db2 close
}
}
}
finish_test
-189
View File
@@ -1,189 +0,0 @@
# 2019 April 23
#
# 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.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverold
proc compare_result {db1 db2 sql} {
set r1 [$db1 eval $sql]
set r2 [$db2 eval $sql]
if {$r1 != $r2} {
puts "sql: $sql"
puts "r1: $r1"
puts "r2: $r2"
error "mismatch for $sql"
}
return ""
}
proc compare_dbs {db1 db2} {
compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1"
foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] {
compare_result $db1 $db2 "SELECT * FROM $tbl"
}
}
proc do_recover_test {tn {tsql {}} {res {}}} {
forcedelete test.db2
forcedelete rstate.db
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R run
$R finish
sqlite3 db2 test.db2
if {$tsql==""} {
uplevel [list do_test $tn.1 [list compare_dbs db db2] {}]
} else {
uplevel [list do_execsql_test -db db2 $tn.1 $tsql $res]
}
db2 close
forcedelete test.db2
forcedelete rstate.db
set ::sqlhook [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config lostandfound lost_and_found
$R run
$R finish
sqlite3 db2 test.db2
db2 eval [join $::sqlhook ";"]
db cache flush
if {$tsql==""} {
compare_dbs db db2
uplevel [list do_test $tn.sql [list compare_dbs db db2] {}]
} else {
uplevel [list do_execsql_test -db db2 $tn.sql $tsql $res]
}
db2 close
}
proc my_sql_hook {sql} {
lappend ::sqlhook $sql
return 0
}
set doc {
hello
world
}
do_execsql_test 1.1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 4, X'1234567800');
INSERT INTO t1 VALUES(2, 'test', 8.1);
INSERT INTO t1 VALUES(3, $doc, 8.4);
}
do_recover_test 1.1.2
do_execsql_test 1.2.1 "
DELETE FROM t1;
INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13);
"
do_recover_test 1.2.2
do_execsql_test 1.3.1 "
CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t2 VALUES(NULL, 1, 2);
INSERT INTO t2 VALUES(NULL, 3, 4);
INSERT INTO t2 VALUES(NULL, 5, 6);
CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
INSERT INTO t3 VALUES(NULL, 1, 2);
INSERT INTO t3 VALUES(NULL, 3, 4);
INSERT INTO t3 VALUES(NULL, 5, 6);
DELETE FROM t2;
"
do_recover_test 1.3.2
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1.0 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
}
do_recover_test 2.1.1
do_execsql_test 2.2.0 {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE name='t1';
}
do_recover_test 2.2.1 {
SELECT name FROM sqlite_master
} {lost_and_found}
do_execsql_test 2.3.0 {
CREATE TABLE lost_and_found(a, b, c);
}
do_recover_test 2.3.1 {
SELECT name FROM sqlite_master
} {lost_and_found lost_and_found_0}
do_execsql_test 2.4.0 {
CREATE TABLE lost_and_found_0(a, b, c);
}
do_recover_test 2.4.1 {
SELECT name FROM sqlite_master;
SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
2 2 3 {} 2 3 1
2 2 3 {} 5 6 4
2 2 3 {} 8 9 7
}
do_execsql_test 2.5 {
CREATE TABLE x1(a, b, c);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
)
INSERT INTO x1 SELECT i, i, hex(randomblob(500)) FROM s;
DROP TABLE x1;
}
do_recover_test 2.5.1 {
SELECT name FROM sqlite_master;
SELECT * FROM lost_and_found_1;
} {lost_and_found lost_and_found_0 lost_and_found_1
2 2 3 {} 2 3 1
2 2 3 {} 5 6 4
2 2 3 {} 8 9 7
}
ifcapable !secure_delete {
do_test 2.6 {
forcedelete test.db2
set R [sqlite3_recover_init db main test.db2]
$R config lostandfound lost_and_found
$R config freelistcorrupt 1
$R run
$R finish
sqlite3 db2 test.db2
execsql { SELECT count(*) FROM lost_and_found_1; } db2
} {103}
db2 close
}
#-------------------------------------------------------------------------
breakpoint
reset_db
do_recover_test 3.0
finish_test
-100
View File
@@ -1,100 +0,0 @@
# 2022 October 14
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
source [file join [file dirname [info script]] recover_common.tcl]
db close
sqlite3_test_control_pending_byte 0x1000000
set testprefix recoverpgsz
foreach {pgsz bOverflow} {
512 0 1024 0 2048 0 4096 0 8192 0 16384 0 32768 0 65536 0
512 1 1024 1 2048 1 4096 1 8192 1 16384 1 32768 1 65536 1
} {
reset_db
execsql "PRAGMA page_size = $pgsz"
execsql "PRAGMA auto_vacuum = 0"
do_execsql_test 1.$pgsz.$bOverflow.1 {
CREATE TABLE t1(a, b, c);
CREATE INDEX i1 ON t1(b, a, c);
INSERT INTO t1(a, b) VALUES(1, 2), (3, 4), (5, 6);
DELETE FROM t1 WHERE a=3;
}
if {$bOverflow} {
do_execsql_test 1.$pgsz.$bOverflow.1a {
UPDATE t1 SET c = randomblob(100000);
}
}
db close
set fd [open test.db]
fconfigure $fd -encoding binary -translation binary
seek $fd $pgsz
set pg1 [read $fd $pgsz]
set pg2 [read $fd $pgsz]
close $fd
set fd2 [open test.db2 w]
fconfigure $fd2 -encoding binary -translation binary
seek $fd2 $pgsz
puts -nonewline $fd2 $pg1
close $fd2
sqlite3 db2 test.db2
do_test 1.$pgsz.$bOverflow.2 {
set R [sqlite3_recover_init db2 main test.db3]
$R run
$R finish
} {}
sqlite3 db3 test.db3
do_test 1.$pgsz.$bOverflow.3 {
db3 eval { SELECT * FROM sqlite_schema }
db3 eval { PRAGMA page_size }
} $pgsz
db2 close
db3 close
forcedelete test.db3
forcedelete test.db2
set fd2 [open test.db2 w]
fconfigure $fd2 -encoding binary -translation binary
seek $fd2 $pgsz
puts -nonewline $fd2 $pg2
close $fd2
sqlite3 db2 test.db2
do_test 1.$pgsz.$bOverflow.4 {
set R [sqlite3_recover_init db2 main test.db3]
$R run
$R finish
} {}
sqlite3 db3 test.db3
do_test 1.$pgsz.$bOverflow.5 {
db3 eval { SELECT * FROM sqlite_schema }
db3 eval { PRAGMA page_size }
} $pgsz
db2 close
db3 close
}
finish_test
-50
View File
@@ -1,50 +0,0 @@
# 2022 September 07
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_ROWIDS option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverrowid
proc recover {db bRowids output} {
forcedelete $output
set R [sqlite3_recover_init db main test.db2]
$R config rowids $bRowids
$R run
$R finish
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
DELETE FROM t1 WHERE a IN (1, 3);
}
do_test 1.1 {
recover db 0 test.db2
sqlite3 db2 test.db2
execsql { SELECT rowid, a, b FROM t1 ORDER BY rowid} db2
} {1 2 2 2 4 4}
do_test 1.2 {
db2 close
recover db 1 test.db2
sqlite3 db2 test.db2
execsql { SELECT rowid, a, b FROM t1 ORDER BY rowid} db2
} {2 2 2 4 4 4}
db2 close
finish_test
-87
View File
@@ -1,87 +0,0 @@
# 2022 September 25
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the SQLITE_RECOVER_SLOWINDEXES option.
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoverslowidx
do_execsql_test 1.0 {
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);
}
proc my_sql_hook {sql} {
lappend ::lSql $sql
return 0
}
do_test 1.1 {
set lSql [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
while {[$R step]==0} { }
$R finish
} {}
do_test 1.2 {
set lSql
} [list {*}{
{BEGIN}
{PRAGMA writable_schema = on}
{PRAGMA encoding = 'UTF-8'}
{PRAGMA page_size = '1024'}
{PRAGMA auto_vacuum = '0'}
{PRAGMA user_version = '0'}
{PRAGMA application_id = '0'}
{CREATE TABLE t1(a, b)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (1, 1, 1)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (2, 2, 2)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (3, 3, 3)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (4, 4, 4)}
{CREATE INDEX i1 ON t1(a)}
{PRAGMA writable_schema = off}
{COMMIT}
}]
do_test 1.3 {
set lSql [list]
set R [sqlite3_recover_init_sql db main my_sql_hook]
$R config slowindexes 1
while {[$R step]==0} { }
$R finish
} {}
do_test 1.4 {
set lSql
} [list {*}{
{BEGIN}
{PRAGMA writable_schema = on}
{PRAGMA encoding = 'UTF-8'}
{PRAGMA page_size = '1024'}
{PRAGMA auto_vacuum = '0'}
{PRAGMA user_version = '0'}
{PRAGMA application_id = '0'}
{CREATE TABLE t1(a, b)}
{CREATE INDEX i1 ON t1(a)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (1, 1, 1)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (2, 2, 2)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (3, 3, 3)}
{INSERT OR IGNORE INTO 't1'(_rowid_, 'a', 'b') VALUES (4, 4, 4)}
{PRAGMA writable_schema = off}
{COMMIT}
}]
finish_test
-52
View File
@@ -1,52 +0,0 @@
# 2022 September 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
source [file join [file dirname [info script]] recover_common.tcl]
set testprefix recoversql
do_execsql_test 1.0 {
CREATE TABLE "x.1" (x, y);
INSERT INTO "x.1" VALUES(1, 1), (2, 2), (3, 3);
CREATE INDEX "i.1" ON "x.1"(y, x);
}
proc sql_hook {sql} {
incr ::iSqlHook
if {$::iSqlHook==$::sql_hook_cnt} { return 4 }
return 0
}
do_test 1.1 {
set ::sql_hook_cnt -1
set ::iSqlHook 0
set R [sqlite3_recover_init_sql db main sql_hook]
$R run
$R finish
} {}
set nSqlCall $iSqlHook
for {set ii 1} {$ii<$nSqlCall} {incr ii} {
set iSqlHook 0
set sql_hook_cnt $ii
do_test 1.$ii.a {
set R [sqlite3_recover_init_sql db main sql_hook]
$R run
} {1}
do_test 1.$ii.b {
list [catch { $R finish } msg] $msg
} {1 {callback returned an error - 4}}
}
finish_test
File diff suppressed because it is too large Load Diff
-249
View File
@@ -1,249 +0,0 @@
/*
** 2022-08-27
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains the public interface to the "recover" extension -
** an SQLite extension designed to recover data from corrupted database
** files.
*/
/*
** OVERVIEW:
**
** To use the API to recover data from a corrupted database, an
** application:
**
** 1) Creates an sqlite3_recover handle by calling either
** sqlite3_recover_init() or sqlite3_recover_init_sql().
**
** 2) Configures the new handle using one or more calls to
** sqlite3_recover_config().
**
** 3) Executes the recovery by repeatedly calling sqlite3_recover_step() on
** the handle until it returns something other than SQLITE_OK. If it
** returns SQLITE_DONE, then the recovery operation completed without
** error. If it returns some other non-SQLITE_OK value, then an error
** has occurred.
**
** 4) Retrieves any error code and English language error message using the
** sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs,
** respectively.
**
** 5) Destroys the sqlite3_recover handle and frees all resources
** using sqlite3_recover_finish().
**
** The application may abandon the recovery operation at any point
** before it is finished by passing the sqlite3_recover handle to
** sqlite3_recover_finish(). This is not an error, but the final state
** of the output database, or the results of running the partial script
** delivered to the SQL callback, are undefined.
*/
#ifndef _SQLITE_RECOVER_H
#define _SQLITE_RECOVER_H
#include "sqlite3.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
** An instance of the sqlite3_recover object represents a recovery
** operation in progress.
**
** Constructors:
**
** sqlite3_recover_init()
** sqlite3_recover_init_sql()
**
** Destructor:
**
** sqlite3_recover_finish()
**
** Methods:
**
** sqlite3_recover_config()
** sqlite3_recover_errcode()
** sqlite3_recover_errmsg()
** sqlite3_recover_run()
** sqlite3_recover_step()
*/
typedef struct sqlite3_recover sqlite3_recover;
/*
** These two APIs attempt to create and return a new sqlite3_recover object.
** In both cases the first two arguments identify the (possibly
** corrupt) database to recover data from. The first argument is an open
** database handle and the second the name of a database attached to that
** handle (i.e. "main", "temp" or the name of an attached database).
**
** If sqlite3_recover_init() is used to create the new sqlite3_recover
** handle, then data is recovered into a new database, identified by
** string parameter zUri. zUri may be an absolute or relative file path,
** or may be an SQLite URI. If the identified database file already exists,
** it is overwritten.
**
** If sqlite3_recover_init_sql() is invoked, then any recovered data will
** be returned to the user as a series of SQL statements. Executing these
** SQL statements results in the same database as would have been created
** had sqlite3_recover_init() been used. For each SQL statement in the
** output, the callback function passed as the third argument (xSql) is
** invoked once. The first parameter is a passed a copy of the fourth argument
** to this function (pCtx) as its first parameter, and a pointer to a
** nul-terminated buffer containing the SQL statement formated as UTF-8 as
** the second. If the xSql callback returns any value other than SQLITE_OK,
** then processing is immediately abandoned and the value returned used as
** the recover handle error code (see below).
**
** If an out-of-memory error occurs, NULL may be returned instead of
** a valid handle. In all other cases, it is the responsibility of the
** application to avoid resource leaks by ensuring that
** sqlite3_recover_finish() is called on all allocated handles.
*/
sqlite3_recover *sqlite3_recover_init(
sqlite3* db,
const char *zDb,
const char *zUri
);
sqlite3_recover *sqlite3_recover_init_sql(
sqlite3* db,
const char *zDb,
int (*xSql)(void*, const char*),
void *pCtx
);
/*
** Configure an sqlite3_recover object that has just been created using
** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function
** may only be called before the first call to sqlite3_recover_step()
** or sqlite3_recover_run() on the object.
**
** The second argument passed to this function must be one of the
** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument
** depend on the specific SQLITE_RECOVER_* symbol in use.
**
** SQLITE_OK is returned if the configuration operation was successful,
** or an SQLite error code otherwise.
*/
int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
/*
** SQLITE_RECOVER_LOST_AND_FOUND:
** The pArg argument points to a string buffer containing the name
** of a "lost-and-found" table in the output database, or NULL. If
** the argument is non-NULL and the database contains seemingly
** valid pages that cannot be associated with any table in the
** recovered part of the schema, data is extracted from these
** pages to add to the lost-and-found table.
**
** SQLITE_RECOVER_FREELIST_CORRUPT:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is set
** (argument is 1) and a lost-and-found table has been configured using
** SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is
** corrupt and an attempt is made to recover records from pages that
** appear to be linked into the freelist. Otherwise, pages on the freelist
** are ignored. Setting this option can recover more data from the
** database, but often ends up "recovering" deleted records. The default
** value is 0 (clear).
**
** SQLITE_RECOVER_ROWIDS:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is set
** (argument is 1), then an attempt is made to recover rowid values
** that are not also INTEGER PRIMARY KEY values. If this option is
** clear, then new rowids are assigned to all recovered rows. The
** default value is 1 (set).
**
** SQLITE_RECOVER_SLOWINDEXES:
** The pArg value must actually be a pointer to a value of type
** int containing value 0 or 1 cast as a (void*). If this option is clear
** (argument is 0), then when creating an output database, the recover
** module creates and populates non-UNIQUE indexes right at the end of the
** recovery operation - after all recoverable data has been inserted
** into the new database. This is faster overall, but means that the
** final call to sqlite3_recover_step() for a recovery operation may
** be need to create a large number of indexes, which may be very slow.
**
** Or, if this option is set (argument is 1), then non-UNIQUE indexes
** are created in the output database before it is populated with
** recovered data. This is slower overall, but avoids the slow call
** to sqlite3_recover_step() at the end of the recovery operation.
**
** The default option value is 0.
*/
#define SQLITE_RECOVER_LOST_AND_FOUND 1
#define SQLITE_RECOVER_FREELIST_CORRUPT 2
#define SQLITE_RECOVER_ROWIDS 3
#define SQLITE_RECOVER_SLOWINDEXES 4
/*
** Perform a unit of work towards the recovery operation. This function
** must normally be called multiple times to complete database recovery.
**
** If no error occurs but the recovery operation is not completed, this
** function returns SQLITE_OK. If recovery has been completed successfully
** then SQLITE_DONE is returned. If an error has occurred, then an SQLite
** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not
** considered an error if some or all of the data cannot be recovered
** due to database corruption.
**
** Once sqlite3_recover_step() has returned a value other than SQLITE_OK,
** all further such calls on the same recover handle are no-ops that return
** the same non-SQLITE_OK value.
*/
int sqlite3_recover_step(sqlite3_recover*);
/*
** Run the recovery operation to completion. Return SQLITE_OK if successful,
** or an SQLite error code otherwise. Calling this function is the same
** as executing:
**
** while( SQLITE_OK==sqlite3_recover_step(p) );
** return sqlite3_recover_errcode(p);
*/
int sqlite3_recover_run(sqlite3_recover*);
/*
** If an error has been encountered during a prior call to
** sqlite3_recover_step(), then this function attempts to return a
** pointer to a buffer containing an English language explanation of
** the error. If no error message is available, or if an out-of memory
** error occurs while attempting to allocate a buffer in which to format
** the error message, NULL is returned.
**
** The returned buffer remains valid until the sqlite3_recover handle is
** destroyed using sqlite3_recover_finish().
*/
const char *sqlite3_recover_errmsg(sqlite3_recover*);
/*
** If this function is called on an sqlite3_recover handle after
** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK.
*/
int sqlite3_recover_errcode(sqlite3_recover*);
/*
** Clean up a recovery object created by a call to sqlite3_recover_init().
** The results of using a recovery object with any API after it has been
** passed to this function are undefined.
**
** This function returns the same value as sqlite3_recover_errcode().
*/
int sqlite3_recover_finish(sqlite3_recover*);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* ifndef _SQLITE_RECOVER_H */
-311
View File
@@ -1,311 +0,0 @@
/*
** 2022-08-27
**
** 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.
**
*************************************************************************
**
*/
#include "sqlite3recover.h"
#include "sqliteInt.h"
#include <tcl.h>
#include <assert.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
typedef struct TestRecover TestRecover;
struct TestRecover {
sqlite3_recover *p;
Tcl_Interp *interp;
Tcl_Obj *pScript;
};
static int xSqlCallback(void *pSqlArg, const char *zSql){
TestRecover *p = (TestRecover*)pSqlArg;
Tcl_Obj *pEval = 0;
int res = 0;
pEval = Tcl_DuplicateObj(p->pScript);
Tcl_IncrRefCount(pEval);
res = Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj(zSql, -1));
if( res==TCL_OK ){
res = Tcl_EvalObjEx(p->interp, pEval, 0);
}
Tcl_DecrRefCount(pEval);
if( res ){
Tcl_BackgroundError(p->interp);
return TCL_ERROR;
}else{
Tcl_Obj *pObj = Tcl_GetObjResult(p->interp);
if( Tcl_GetCharLength(pObj)==0 ){
res = 0;
}else if( Tcl_GetIntFromObj(p->interp, pObj, &res) ){
Tcl_BackgroundError(p->interp);
return TCL_ERROR;
}
}
return res;
}
static int getDbPointer(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
Tcl_CmdInfo info;
if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0);
return TCL_ERROR;
}
*pDb = *(sqlite3 **)info.objClientData;
return TCL_OK;
}
/*
** Implementation of the command created by [sqlite3_recover_init]:
**
** $cmd config OP ARG
** $cmd run
** $cmd errmsg
** $cmd errcode
** $cmd finalize
*/
static int testRecoverCmd(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
static struct RecoverSub {
const char *zSub;
int nArg;
const char *zMsg;
} aSub[] = {
{ "config", 2, "ARG" }, /* 0 */
{ "run", 0, "" }, /* 1 */
{ "errmsg", 0, "" }, /* 2 */
{ "errcode", 0, "" }, /* 3 */
{ "finish", 0, "" }, /* 4 */
{ "step", 0, "" }, /* 5 */
{ 0 }
};
int rc = TCL_OK;
int iSub = 0;
TestRecover *pTest = (TestRecover*)clientData;
if( objc<2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
return TCL_ERROR;
}
rc = Tcl_GetIndexFromObjStruct(interp,
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
);
if( rc!=TCL_OK ) return rc;
if( (objc-2)!=aSub[iSub].nArg ){
Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg);
return TCL_ERROR;
}
switch( iSub ){
case 0: assert( sqlite3_stricmp("config", aSub[iSub].zSub)==0 ); {
const char *aOp[] = {
"testdb", /* 0 */
"lostandfound", /* 1 */
"freelistcorrupt", /* 2 */
"rowids", /* 3 */
"slowindexes", /* 4 */
"invalid", /* 5 */
0
};
int iOp = 0;
int res = 0;
if( Tcl_GetIndexFromObj(interp, objv[2], aOp, "option", 0, &iOp) ){
return TCL_ERROR;
}
switch( iOp ){
case 0:
res = sqlite3_recover_config(pTest->p,
789, (void*)Tcl_GetString(objv[3]) /* MAGIC NUMBER! */
);
break;
case 1: {
const char *zStr = Tcl_GetString(objv[3]);
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_LOST_AND_FOUND, (void*)(zStr[0] ? zStr : 0)
);
break;
}
case 2: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_FREELIST_CORRUPT, (void*)&iVal
);
break;
}
case 3: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_ROWIDS, (void*)&iVal
);
break;
}
case 4: {
int iVal = 0;
if( Tcl_GetBooleanFromObj(interp, objv[3], &iVal) ) return TCL_ERROR;
res = sqlite3_recover_config(pTest->p,
SQLITE_RECOVER_SLOWINDEXES, (void*)&iVal
);
break;
}
case 5: {
res = sqlite3_recover_config(pTest->p, 12345, 0);
break;
}
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
case 1: assert( sqlite3_stricmp("run", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_run(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
case 2: assert( sqlite3_stricmp("errmsg", aSub[iSub].zSub)==0 ); {
const char *zErr = sqlite3_recover_errmsg(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
break;
}
case 3: assert( sqlite3_stricmp("errcode", aSub[iSub].zSub)==0 ); {
int errCode = sqlite3_recover_errcode(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(errCode));
break;
}
case 4: assert( sqlite3_stricmp("finish", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_errcode(pTest->p);
int res2;
if( res!=SQLITE_OK ){
const char *zErr = sqlite3_recover_errmsg(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
}
res2 = sqlite3_recover_finish(pTest->p);
assert( res2==res );
if( res ) return TCL_ERROR;
break;
}
case 5: assert( sqlite3_stricmp("step", aSub[iSub].zSub)==0 ); {
int res = sqlite3_recover_step(pTest->p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
break;
}
}
return TCL_OK;
}
/*
** sqlite3_recover_init DB DBNAME URI
*/
static int test_sqlite3_recover_init(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
static int iTestRecoverCmd = 1;
TestRecover *pNew = 0;
sqlite3 *db = 0;
const char *zDb = 0;
const char *zUri = 0;
char zCmd[128];
int bSql = clientData ? 1 : 0;
if( objc!=4 ){
const char *zErr = (bSql ? "DB DBNAME SCRIPT" : "DB DBNAME URI");
Tcl_WrongNumArgs(interp, 1, objv, zErr);
return TCL_ERROR;
}
if( getDbPointer(interp, objv[1], &db) ) return TCL_ERROR;
zDb = Tcl_GetString(objv[2]);
if( zDb[0]=='\0' ) zDb = 0;
pNew = ckalloc(sizeof(TestRecover));
if( bSql==0 ){
zUri = Tcl_GetString(objv[3]);
pNew->p = sqlite3_recover_init(db, zDb, zUri);
}else{
pNew->interp = interp;
pNew->pScript = objv[3];
Tcl_IncrRefCount(pNew->pScript);
pNew->p = sqlite3_recover_init_sql(db, zDb, xSqlCallback, (void*)pNew);
}
sprintf(zCmd, "sqlite_recover%d", iTestRecoverCmd++);
Tcl_CreateObjCommand(interp, zCmd, testRecoverCmd, (void*)pNew, 0);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zCmd, -1));
return TCL_OK;
}
/*
** Declaration for public API function in file dbdata.c. This may be called
** with NULL as the final two arguments to register the sqlite_dbptr and
** sqlite_dbdata virtual tables with a database handle.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*);
/*
** sqlite3_recover_init DB DBNAME URI
*/
static int test_sqlite3_dbdata_init(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db = 0;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, objv[1], &db) ) return TCL_ERROR;
sqlite3_dbdata_init(db, 0, 0);
Tcl_ResetResult(interp);
return TCL_OK;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int TestRecover_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
struct Cmd {
const char *zCmd;
Tcl_ObjCmdProc *xProc;
void *pArg;
} aCmd[] = {
{ "sqlite3_recover_init", test_sqlite3_recover_init, 0 },
{ "sqlite3_recover_init_sql", test_sqlite3_recover_init, (void*)1 },
{ "sqlite3_dbdata_init", test_sqlite3_dbdata_init, (void*)1 },
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){
struct Cmd *p = &aCmd[i];
Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, p->pArg, 0);
}
#endif
return TCL_OK;
}
+2 -13
View File
@@ -44,19 +44,8 @@ SQLITE_EXTENSION_INIT1
# include <stdio.h>
# include <stdlib.h>
# include <assert.h>
# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
# endif
# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
# define ALWAYS(X) (1)
# define NEVER(X) (0)
# elif !defined(NDEBUG)
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
# else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
# endif
# define ALWAYS(X) 1
# define NEVER(X) 0
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
+1
View File
@@ -4,6 +4,7 @@
*/
#define TCLSH_INIT_PROC sqlite3_checker_init_proc
#define SQLITE_ENABLE_DBPAGE_VTAB 1
#define SQLITE_ENABLE_JSON1 1
#undef SQLITE_THREADSAFE
#define SQLITE_THREADSAFE 0
#undef SQLITE_ENABLE_COLUMN_METADATA
+11 -11
View File
@@ -26,7 +26,11 @@
# define GEODEBUG(X)
#endif
/* Character class routines */
#ifndef JSON_NULL /* The following stuff repeats things found in json1 */
/*
** Versions of isspace(), isalnum() and isdigit() to which it is safe
** to pass signed char values.
*/
#ifdef sqlite3Isdigit
/* Use the SQLite core versions if this routine is part of the
** SQLite amalgamation */
@@ -41,7 +45,6 @@
# define safe_isxdigit(x) isxdigit((unsigned char)(x))
#endif
#ifndef JSON_NULL /* The following stuff repeats things found in json1 */
/*
** Growing our own isspace() routine this way is twice as fast as
** the library isspace() function.
@@ -64,7 +67,7 @@ static const char geopolyIsSpace[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#define fast_isspace(x) (geopolyIsSpace[(unsigned char)x])
#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x])
#endif /* JSON NULL - back to original code */
/* Compiler and version */
@@ -153,7 +156,7 @@ static void geopolySwab32(unsigned char *a){
/* Skip whitespace. Return the next non-whitespace character. */
static char geopolySkipSpace(GeoParse *p){
while( fast_isspace(p->z[0]) ) p->z++;
while( safe_isspace(p->z[0]) ) p->z++;
return p->z[0];
}
@@ -302,14 +305,13 @@ static GeoPoly *geopolyFuncParam(
){
GeoPoly *p = 0;
int nByte;
testcase( pCtx==0 );
if( sqlite3_value_type(pVal)==SQLITE_BLOB
&& (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
){
const unsigned char *a = sqlite3_value_blob(pVal);
int nVertex;
if( a==0 ){
if( pCtx ) sqlite3_result_error_nomem(pCtx);
sqlite3_result_error_nomem(pCtx);
return 0;
}
nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
@@ -1136,11 +1138,11 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
}else{
/* Remove a segment */
if( pActive==pThisEvent->pSeg ){
pActive = ALWAYS(pActive) ? pActive->pNext : 0;
pActive = pActive->pNext;
}else{
for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
if( pSeg->pNext==pThisEvent->pSeg ){
pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0;
pSeg->pNext = pSeg->pNext->pNext;
break;
}
}
@@ -1384,7 +1386,6 @@ static int geopolyFilter(
RtreeCoord bbox[4];
RtreeConstraint *p;
assert( argc==1 );
assert( argv[0]!=0 );
geopolyBBox(0, argv[0], bbox, &rc);
if( rc ){
goto geopoly_filter_end;
@@ -1612,7 +1613,6 @@ static int geopolyUpdate(
|| !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
|| oldRowid!=newRowid) /* Rowid change */
){
assert( aData[2]!=0 );
geopolyBBox(0, aData[2], cell.aCoord, &rc);
if( rc ){
if( rc==SQLITE_ERROR ){
@@ -1695,7 +1695,7 @@ static int geopolyUpdate(
sqlite3_free(p);
nChange = 1;
}
for(jj=1; jj<nData-2; jj++){
for(jj=1; jj<pRtree->nAux; jj++){
nChange++;
sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
}

Some files were not shown because too many files have changed in this diff Show More