mirror of
https://github.com/status-im/sqlcipher.git
synced 2025-02-23 01:08:09 +00:00
Merge sqlite-release(3.20.1) into prerelease-integration
This commit is contained in:
commit
be789e94dd
55
Makefile.in
55
Makefile.in
@ -200,7 +200,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.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 \
|
||||
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
|
||||
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
|
||||
update.lo util.lo vacuum.lo \
|
||||
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
|
||||
@ -370,7 +370,8 @@ SRC += \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.h \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.c
|
||||
SRC += \
|
||||
$(TOP)/ext/misc/json1.c
|
||||
$(TOP)/ext/misc/json1.c \
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
|
||||
# Generated source code files
|
||||
#
|
||||
@ -450,9 +451,11 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/nextchar.c \
|
||||
$(TOP)/ext/misc/percentile.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
$(TOP)/ext/misc/remember.c \
|
||||
$(TOP)/ext/misc/series.c \
|
||||
$(TOP)/ext/misc/spellfix.c \
|
||||
$(TOP)/ext/misc/totype.c \
|
||||
$(TOP)/ext/misc/unionvtab.c \
|
||||
$(TOP)/ext/misc/wholenumber.c
|
||||
|
||||
# Source code to the library files needed by the test fixture
|
||||
@ -502,7 +505,8 @@ TESTSRC2 = \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.c \
|
||||
$(TOP)/ext/fts3/fts3_write.c \
|
||||
$(TOP)/ext/async/sqlite3async.c \
|
||||
$(TOP)/ext/session/sqlite3session.c
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
|
||||
# Header files used by all library source files.
|
||||
#
|
||||
@ -570,7 +574,8 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata1.db \
|
||||
$(TOP)/test/fuzzdata2.db \
|
||||
$(TOP)/test/fuzzdata3.db \
|
||||
$(TOP)/test/fuzzdata4.db
|
||||
$(TOP)/test/fuzzdata4.db \
|
||||
$(TOP)/test/fuzzdata5.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
@ -582,8 +587,12 @@ SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
|
||||
# SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
|
||||
DBFUZZ_OPT =
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
@ -632,8 +641,15 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
|
||||
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
|
||||
|
||||
fuzzcheck$(TEXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
|
||||
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
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
|
||||
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
|
||||
@ -1055,6 +1071,9 @@ sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
|
||||
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
|
||||
|
||||
# FTS5 things
|
||||
#
|
||||
FTS5_SRC = \
|
||||
@ -1104,6 +1123,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlcipher.la
|
||||
TESTFIXTURE_SRC1 = sqlite3.c
|
||||
@ -1136,6 +1156,11 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
#
|
||||
tcltest: ./testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes
|
||||
#
|
||||
quicktest: ./testfixture$(TEXE)
|
||||
@ -1144,8 +1169,7 @@ quicktest: ./testfixture$(TEXE)
|
||||
# This is the common case. Run many tests that do not take too long,
|
||||
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
|
||||
#
|
||||
test: $(TESTPROGS) sourcetest fastfuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
|
||||
test: fastfuzztest sourcetest $(TESTPROGS) tcltest
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
@ -1172,6 +1196,10 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
||||
|
||||
dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
|
||||
$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
|
||||
$(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
|
||||
|
||||
showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
|
||||
|
||||
@ -1196,8 +1224,13 @@ 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.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS)
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c
|
||||
$(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS)
|
||||
|
||||
KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
|
||||
kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
|
||||
$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
|
||||
|
92
Makefile.msc
92
Makefile.msc
@ -21,7 +21,14 @@ USE_AMALGAMATION = 1
|
||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||
#
|
||||
!IFNDEF USE_FULLWARN
|
||||
USE_FULLWARN = 0
|
||||
USE_FULLWARN = 1
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable treating warnings as errors (-WX, etc) when
|
||||
# compiling.
|
||||
#
|
||||
!IFNDEF USE_FATAL_WARN
|
||||
USE_FATAL_WARN = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable full runtime error checks (-RTC1, etc). This
|
||||
@ -493,6 +500,12 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
||||
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Check if warnings should be treated as errors when compiling.
|
||||
#
|
||||
!IF $(USE_FATAL_WARN)!=0
|
||||
TCC = $(TCC) -WX
|
||||
!ENDIF
|
||||
|
||||
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
|
||||
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
||||
|
||||
@ -733,6 +746,10 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!IF $(DYNAMIC_SHELL)==0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
@ -1284,7 +1301,8 @@ SRC07 = \
|
||||
$(TOP)\ext\rtree\rtree.c \
|
||||
$(TOP)\ext\session\sqlite3session.c \
|
||||
$(TOP)\ext\rbu\sqlite3rbu.c \
|
||||
$(TOP)\ext\misc\json1.c
|
||||
$(TOP)\ext\misc\json1.c \
|
||||
$(TOP)\ext\misc\stmt.c
|
||||
|
||||
# Extension header files, part 1.
|
||||
#
|
||||
@ -1403,9 +1421,11 @@ TESTEXT = \
|
||||
$(TOP)\ext\misc\nextchar.c \
|
||||
$(TOP)\ext\misc\percentile.c \
|
||||
$(TOP)\ext\misc\regexp.c \
|
||||
$(TOP)\ext\misc\remember.c \
|
||||
$(TOP)\ext\misc\series.c \
|
||||
$(TOP)\ext\misc\spellfix.c \
|
||||
$(TOP)\ext\misc\totype.c \
|
||||
$(TOP)\ext\misc\unionvtab.c \
|
||||
$(TOP)\ext\misc\wholenumber.c
|
||||
|
||||
# Source code to the library files needed by the test fixture
|
||||
@ -1486,14 +1506,15 @@ FUZZDATA = \
|
||||
$(TOP)\test\fuzzdata1.db \
|
||||
$(TOP)\test\fuzzdata2.db \
|
||||
$(TOP)\test\fuzzdata3.db \
|
||||
$(TOP)\test\fuzzdata4.db
|
||||
$(TOP)\test\fuzzdata4.db \
|
||||
$(TOP)\test\fuzzdata5.db
|
||||
# <</mark>>
|
||||
|
||||
# Additional compiler options for the shell. These are only effective
|
||||
# when the shell is not being dynamically linked.
|
||||
#
|
||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
@ -1501,7 +1522,13 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
|
||||
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
||||
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
|
||||
|
||||
# Standard options to testfixture.
|
||||
#
|
||||
@ -1544,7 +1571,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
sqlite3.def: libsqlite3.lib
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all libsqlite3.lib \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
# <</block2>>
|
||||
|
||||
@ -1571,8 +1598,14 @@ sourcetest: srcck1.exe sqlite3.c
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
@ -2065,6 +2098,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
|
||||
@ -2157,6 +2191,10 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
|
||||
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
|
||||
|
||||
@ -2164,48 +2202,59 @@ testloadext.dll: testloadext.lo
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
|
||||
|
||||
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
|
||||
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
|
||||
$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C)
|
||||
|
||||
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
|
||||
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LSMDIR=$(TOP)\ext\lsm1
|
||||
!INCLUDE $(LSMDIR)\Makefile.msc
|
||||
|
||||
moreclean: clean
|
||||
del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL
|
||||
# <</mark>>
|
||||
@ -2225,9 +2274,10 @@ clean:
|
||||
-rmdir /Q/S tsrc 2>NUL
|
||||
del /Q .target_source 2>NUL
|
||||
del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
|
||||
del /Q lsm.dll lsmtest.exe 2>NUL
|
||||
del /Q testloadext.dll 2>NUL
|
||||
del /Q testfixture.exe test.db 2>NUL
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
|
||||
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
|
||||
del /Q changeset.exe 2>NUL
|
||||
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
|
||||
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
|
||||
|
@ -21,7 +21,14 @@ TOP = .
|
||||
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
|
||||
#
|
||||
!IFNDEF USE_FULLWARN
|
||||
USE_FULLWARN = 0
|
||||
USE_FULLWARN = 1
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable treating warnings as errors (-WX, etc) when
|
||||
# compiling.
|
||||
#
|
||||
!IFNDEF USE_FATAL_WARN
|
||||
USE_FATAL_WARN = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable full runtime error checks (-RTC1, etc). This
|
||||
@ -454,6 +461,12 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
|
||||
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Check if warnings should be treated as errors when compiling.
|
||||
#
|
||||
!IF $(USE_FATAL_WARN)!=0
|
||||
TCC = $(TCC) -WX
|
||||
!ENDIF
|
||||
|
||||
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -fp:precise
|
||||
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
|
||||
|
||||
@ -632,6 +645,10 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!IF $(DYNAMIC_SHELL)==0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
@ -910,7 +927,7 @@ LIBRESOBJS =
|
||||
# when the shell is not being dynamically linked.
|
||||
#
|
||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
|
||||
!ENDIF
|
||||
|
||||
|
||||
@ -937,7 +954,7 @@ Replace.exe:
|
||||
sqlite3.def: Replace.exe $(LIBOBJ)
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all $(LIBOBJ) \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||
|
@ -55,9 +55,9 @@ AS_IF([ test x"$enable_editline" != xno ],[
|
||||
LIBS=""
|
||||
AC_SEARCH_LIBS([readline],[edit],[
|
||||
AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
|
||||
READLINE_LIBS=$LIBS
|
||||
READLINE_LIBS="$LIBS -ltinfo"
|
||||
enable_readline=no
|
||||
])
|
||||
],[],[-ltinfo])
|
||||
AS_UNSET(ac_cv_search_readline)
|
||||
LIBS=$sLIBS
|
||||
])
|
||||
|
40
configure
vendored
40
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlcipher 3.15.2.
|
||||
# Generated by GNU Autoconf 2.69 for sqlcipher 3.20.1.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@ -587,8 +587,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlcipher'
|
||||
PACKAGE_TARNAME='sqlcipher'
|
||||
PACKAGE_VERSION='3.15.2'
|
||||
PACKAGE_STRING='sqlcipher 3.15.2'
|
||||
PACKAGE_VERSION='3.20.1'
|
||||
PACKAGE_STRING='sqlcipher 3.20.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1334,7 +1334,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 sqlcipher 3.15.2 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlcipher 3.20.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1399,7 +1399,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlcipher 3.15.2:";;
|
||||
short | recursive ) echo "Configuration of sqlcipher 3.20.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1533,7 +1533,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlcipher configure 3.15.2
|
||||
sqlcipher configure 3.20.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -1952,7 +1952,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 sqlcipher $as_me 3.15.2, which was
|
||||
It was created by sqlcipher $as_me 3.20.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -12774,7 +12774,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@ -12878,7 +12878,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS5... " >&6; }
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@ -12895,7 +12895,7 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS3... " >&6; }
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
@ -12913,7 +12913,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
# Check whether --enable-fts4 was given.
|
||||
if test "${enable_fts4+set}" = set; then :
|
||||
@ -12923,7 +12923,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@ -12989,7 +12989,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
|
||||
$as_echo_n "checking for library containing log... " >&6; }
|
||||
if ${ac_cv_search_log+:} false; then :
|
||||
@ -13058,7 +13058,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@ -13071,7 +13071,7 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@ -13084,12 +13084,12 @@ else
|
||||
fi
|
||||
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
|
||||
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
|
||||
for option in $CFLAGS $CPPFLAGS
|
||||
do
|
||||
case $option in
|
||||
@ -13673,7 +13673,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 sqlcipher $as_me 3.15.2, which was
|
||||
This file was extended by sqlcipher $as_me 3.20.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -13739,7 +13739,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="\\
|
||||
sqlcipher config.status 3.15.2
|
||||
sqlcipher config.status 3.20.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
22
configure.ac
22
configure.ac
@ -607,7 +607,7 @@ AC_SEARCH_LIBS(fdatasync, [rt])
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]),
|
||||
[use_debug=$enableval],[use_debug=no])
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1"
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
fi
|
||||
@ -643,7 +643,7 @@ AC_ARG_ENABLE(memsys5,
|
||||
[enable_memsys5=yes],[enable_memsys5=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS5])
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@ -653,7 +653,7 @@ AC_ARG_ENABLE(memsys3,
|
||||
[enable_memsys3=yes],[enable_memsys3=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS3])
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@ -665,20 +665,20 @@ AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
|
||||
[Enable the FTS3 extension]),
|
||||
[enable_fts3=yes],[enable_fts3=no])
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
fi
|
||||
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
|
||||
[Enable the FTS4 extension]),
|
||||
[enable_fts4=yes],[enable_fts4=no])
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
|
||||
[Enable the FTS5 extension]),
|
||||
[enable_fts5=yes],[enable_fts5=no])
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
fi
|
||||
|
||||
@ -688,7 +688,7 @@ AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
|
||||
[Enable the JSON1 extension]),
|
||||
[enable_json1=yes],[enable_json1=no])
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@ -697,7 +697,7 @@ AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
|
||||
[Enable the RTREE extension]),
|
||||
[enable_rtree=yes],[enable_rtree=no])
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
fi
|
||||
|
||||
#########
|
||||
@ -706,12 +706,12 @@ AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
|
||||
[Enable the SESSION extension]),
|
||||
[enable_session=yes],[enable_session=no])
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
|
||||
#########
|
||||
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
|
||||
# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
|
||||
for option in $CFLAGS $CPPFLAGS
|
||||
do
|
||||
case $option in
|
||||
|
@ -23,6 +23,26 @@ or embedded controllers.</p>
|
||||
<p>This document is an introduction to the Lemon
|
||||
parser generator.</p>
|
||||
|
||||
<h2>Security Note</h2>
|
||||
|
||||
<p>The language parser code created by Lemon is very robust and
|
||||
is well-suited for use in internet-facing applications that need to
|
||||
safely process maliciously crafted inputs.
|
||||
|
||||
<p>The "lemon.exe" command-line tool itself works great when given a valid
|
||||
input grammar file and almost always gives helpful
|
||||
error messages for malformed inputs. However, it is possible for
|
||||
a malicious user to craft a grammar file that will cause
|
||||
lemon.exe to crash.
|
||||
We do not see this as a problem, as lemon.exe is not intended to be used
|
||||
with hostile inputs.
|
||||
To summarize:</p>
|
||||
|
||||
<ul>
|
||||
<li>Parser code generated by lemon → Robust and secure
|
||||
<li>The "lemon.exe" command line tool itself → Not so much
|
||||
</ul>
|
||||
|
||||
<h2>Theory of Operation</h2>
|
||||
|
||||
<p>The main goal of Lemon is to translate a context free grammar (CFG)
|
||||
|
8
ext/README.md
Normal file
8
ext/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
## Loadable Extensions
|
||||
|
||||
Various [loadable extensions](https://www.sqlite.org/loadext.html) for
|
||||
SQLite are found in subfolders.
|
||||
|
||||
Most subfolders are dedicated to a single loadable extension (for
|
||||
example FTS5, or RTREE). But the misc/ subfolder contains a collection
|
||||
of smaller single-file extensions.
|
@ -1,2 +0,0 @@
|
||||
Version loadable extensions to SQLite are found in subfolders
|
||||
of this folder.
|
367
ext/fts3/fts3.c
367
ext/fts3/fts3.c
@ -349,8 +349,9 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
|
||||
** Return the number of bytes read, or 0 on error.
|
||||
** The value is stored in *v.
|
||||
*/
|
||||
int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
|
||||
const char *pStart = p;
|
||||
int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
|
||||
const unsigned char *p = (const unsigned char*)pBuf;
|
||||
const unsigned char *pStart = p;
|
||||
u32 a;
|
||||
u64 b;
|
||||
int shift;
|
||||
@ -371,8 +372,8 @@ int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
|
||||
}
|
||||
|
||||
/*
|
||||
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a
|
||||
** 32-bit integer before it is returned.
|
||||
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to
|
||||
** a non-negative 32-bit integer before it is returned.
|
||||
*/
|
||||
int sqlite3Fts3GetVarint32(const char *p, int *pi){
|
||||
u32 a;
|
||||
@ -388,7 +389,9 @@ int sqlite3Fts3GetVarint32(const char *p, int *pi){
|
||||
GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
|
||||
GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
|
||||
a = (a & 0x0FFFFFFF );
|
||||
*pi = (int)(a | ((u32)(*p & 0x0F) << 28));
|
||||
*pi = (int)(a | ((u32)(*p & 0x07) << 28));
|
||||
assert( 0==(a & 0x80000000) );
|
||||
assert( *pi>=0 );
|
||||
return 5;
|
||||
}
|
||||
|
||||
@ -492,6 +495,7 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
|
||||
assert( p->pSegments==0 );
|
||||
|
||||
/* Free any prepared statements held */
|
||||
sqlite3_finalize(p->pSeekStmt);
|
||||
for(i=0; i<SizeofArray(p->aStmt); i++){
|
||||
sqlite3_finalize(p->aStmt[i]);
|
||||
}
|
||||
@ -1217,65 +1221,66 @@ static int fts3InitVtab(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( iOpt==SizeofArray(aFts4Opt) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
break;
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
break;
|
||||
|
||||
case 1: /* PREFIX */
|
||||
sqlite3_free(zPrefix);
|
||||
zPrefix = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 1: /* PREFIX */
|
||||
sqlite3_free(zPrefix);
|
||||
zPrefix = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 2: /* COMPRESS */
|
||||
sqlite3_free(zCompress);
|
||||
zCompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 2: /* COMPRESS */
|
||||
sqlite3_free(zCompress);
|
||||
zCompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 3: /* UNCOMPRESS */
|
||||
sqlite3_free(zUncompress);
|
||||
zUncompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 3: /* UNCOMPRESS */
|
||||
sqlite3_free(zUncompress);
|
||||
zUncompress = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 4: /* ORDER */
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
break;
|
||||
case 4: /* ORDER */
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
break;
|
||||
|
||||
case 5: /* CONTENT */
|
||||
sqlite3_free(zContent);
|
||||
zContent = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 5: /* CONTENT */
|
||||
sqlite3_free(zContent);
|
||||
zContent = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 6: /* LANGUAGEID */
|
||||
assert( iOpt==6 );
|
||||
sqlite3_free(zLanguageid);
|
||||
zLanguageid = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
case 6: /* LANGUAGEID */
|
||||
assert( iOpt==6 );
|
||||
sqlite3_free(zLanguageid);
|
||||
zLanguageid = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
case 7: /* NOTINDEXED */
|
||||
azNotindexed[nNotindexed++] = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
}
|
||||
case 7: /* NOTINDEXED */
|
||||
azNotindexed[nNotindexed++] = zVal;
|
||||
zVal = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( iOpt==SizeofArray(aFts4Opt) );
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
sqlite3_free(zVal);
|
||||
}
|
||||
@ -1363,9 +1368,9 @@ static int fts3InitVtab(
|
||||
p->pTokenizer = pTokenizer;
|
||||
p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
|
||||
p->bHasDocsize = (isFts4 && bNoDocsize==0);
|
||||
p->bHasStat = isFts4;
|
||||
p->bFts4 = isFts4;
|
||||
p->bDescIdx = bDescIdx;
|
||||
p->bHasStat = (u8)isFts4;
|
||||
p->bFts4 = (u8)isFts4;
|
||||
p->bDescIdx = (u8)bDescIdx;
|
||||
p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */
|
||||
p->zContentTbl = zContent;
|
||||
p->zLanguageid = zLanguageid;
|
||||
@ -1396,7 +1401,9 @@ static int fts3InitVtab(
|
||||
char *z;
|
||||
int n = 0;
|
||||
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
|
||||
memcpy(zCsr, z, n);
|
||||
if( n>0 ){
|
||||
memcpy(zCsr, z, n);
|
||||
}
|
||||
zCsr[n] = '\0';
|
||||
sqlite3Fts3Dequote(zCsr);
|
||||
p->azColumn[iCol] = zCsr;
|
||||
@ -1680,6 +1687,39 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Finalize the statement handle at pCsr->pStmt.
|
||||
**
|
||||
** Or, if that statement handle is one created by fts3CursorSeekStmt(),
|
||||
** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
|
||||
** pointer there instead of finalizing it.
|
||||
*/
|
||||
static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
|
||||
if( pCsr->bSeekStmt ){
|
||||
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
||||
if( p->pSeekStmt==0 ){
|
||||
p->pSeekStmt = pCsr->pStmt;
|
||||
sqlite3_reset(pCsr->pStmt);
|
||||
pCsr->pStmt = 0;
|
||||
}
|
||||
pCsr->bSeekStmt = 0;
|
||||
}
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Free all resources currently held by the cursor passed as the only
|
||||
** argument.
|
||||
*/
|
||||
static void fts3ClearCursor(Fts3Cursor *pCsr){
|
||||
fts3CursorFinalizeStmt(pCsr);
|
||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
|
||||
}
|
||||
|
||||
/*
|
||||
** Close the cursor. For additional information see the documentation
|
||||
** on the xClose method of the virtual table interface.
|
||||
@ -1687,11 +1727,7 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
fts3ClearCursor(pCsr);
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
sqlite3_free(pCsr);
|
||||
return SQLITE_OK;
|
||||
@ -1705,20 +1741,23 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
**
|
||||
** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
|
||||
** it. If an error occurs, return an SQLite error code.
|
||||
**
|
||||
** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
|
||||
*/
|
||||
static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
||||
static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->pStmt==0 ){
|
||||
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
||||
char *zSql;
|
||||
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
||||
if( !zSql ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( p->pSeekStmt ){
|
||||
pCsr->pStmt = p->pSeekStmt;
|
||||
p->pSeekStmt = 0;
|
||||
}else{
|
||||
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
||||
if( !zSql ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_prepare_v3(p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
|
||||
}
|
||||
*ppStmt = pCsr->pStmt;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1730,9 +1769,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
||||
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->isRequireSeek ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
rc = fts3CursorSeekStmt(pCsr, &pStmt);
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
|
||||
pCsr->isRequireSeek = 0;
|
||||
@ -1821,7 +1858,8 @@ static int fts3ScanInteriorNode(
|
||||
isFirstTerm = 0;
|
||||
zCsr += fts3GetVarint32(zCsr, &nSuffix);
|
||||
|
||||
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
|
||||
assert( nPrefix>=0 && nSuffix>=0 );
|
||||
if( &zCsr[nSuffix]>zEnd ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
goto finish_scan;
|
||||
}
|
||||
@ -2631,7 +2669,7 @@ int sqlite3Fts3FirstFilter(
|
||||
fts3ColumnlistCopy(0, &p);
|
||||
}
|
||||
|
||||
while( p<pEnd && *p==0x01 ){
|
||||
while( p<pEnd ){
|
||||
sqlite3_int64 iCol;
|
||||
p++;
|
||||
p += sqlite3Fts3GetVarint(p, &iCol);
|
||||
@ -3190,11 +3228,7 @@ static int fts3FilterMethod(
|
||||
assert( iIdx==nVal );
|
||||
|
||||
/* In case the cursor has been used before, clear it now. */
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
|
||||
fts3ClearCursor(pCsr);
|
||||
|
||||
/* Set the lower and upper bounds on docids to return */
|
||||
pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
|
||||
@ -3252,13 +3286,13 @@ static int fts3FilterMethod(
|
||||
);
|
||||
}
|
||||
if( zSql ){
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
rc = sqlite3_prepare_v3(p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0);
|
||||
sqlite3_free(zSql);
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}else if( eSearch==FTS3_DOCID_SEARCH ){
|
||||
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
|
||||
}
|
||||
@ -3273,7 +3307,12 @@ static int fts3FilterMethod(
|
||||
** routine to find out if it has reached the end of a result set.
|
||||
*/
|
||||
static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){
|
||||
return ((Fts3Cursor *)pCursor)->isEof;
|
||||
Fts3Cursor *pCsr = (Fts3Cursor*)pCursor;
|
||||
if( pCsr->isEof ){
|
||||
fts3ClearCursor(pCsr);
|
||||
pCsr->isEof = 1;
|
||||
}
|
||||
return pCsr->isEof;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3311,33 +3350,37 @@ static int fts3ColumnMethod(
|
||||
/* The column value supplied by SQLite must be in range. */
|
||||
assert( iCol>=0 && iCol<=p->nColumn+2 );
|
||||
|
||||
if( iCol==p->nColumn+1 ){
|
||||
/* This call is a request for the "docid" column. Since "docid" is an
|
||||
** alias for "rowid", use the xRowid() method to obtain the value.
|
||||
*/
|
||||
sqlite3_result_int64(pCtx, pCsr->iPrevId);
|
||||
}else if( iCol==p->nColumn ){
|
||||
/* The extra column whose name is the same as the table.
|
||||
** Return a blob which is a pointer to the cursor. */
|
||||
sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
|
||||
}else if( iCol==p->nColumn+2 && pCsr->pExpr ){
|
||||
sqlite3_result_int64(pCtx, pCsr->iLangid);
|
||||
}else{
|
||||
/* The requested column is either a user column (one that contains
|
||||
** indexed data), or the language-id column. */
|
||||
rc = fts3CursorSeek(0, pCsr);
|
||||
switch( iCol-p->nColumn ){
|
||||
case 0:
|
||||
/* The special 'table-name' column */
|
||||
sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
|
||||
break;
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( iCol==p->nColumn+2 ){
|
||||
int iLangid = 0;
|
||||
if( p->zLanguageid ){
|
||||
iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
|
||||
}
|
||||
sqlite3_result_int(pCtx, iLangid);
|
||||
}else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
|
||||
case 1:
|
||||
/* The docid column */
|
||||
sqlite3_result_int64(pCtx, pCsr->iPrevId);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if( pCsr->pExpr ){
|
||||
sqlite3_result_int64(pCtx, pCsr->iLangid);
|
||||
break;
|
||||
}else if( p->zLanguageid==0 ){
|
||||
sqlite3_result_int(pCtx, 0);
|
||||
break;
|
||||
}else{
|
||||
iCol = p->nColumn;
|
||||
/* fall-through */
|
||||
}
|
||||
|
||||
default:
|
||||
/* A user column. Or, if this is a full-table scan, possibly the
|
||||
** language-id column. Seek the cursor. */
|
||||
rc = fts3CursorSeek(0, pCsr);
|
||||
if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){
|
||||
sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
@ -3386,8 +3429,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
|
||||
|
||||
Fts3Table *p = (Fts3Table*)pVtab;
|
||||
int rc = sqlite3Fts3PendingTermsFlush(p);
|
||||
int rc;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
|
||||
|
||||
rc = sqlite3Fts3PendingTermsFlush(p);
|
||||
if( rc==SQLITE_OK
|
||||
&& p->nLeafAdd>(nMinMerge/16)
|
||||
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
|
||||
@ -3402,6 +3447,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
|
||||
}
|
||||
sqlite3Fts3SegmentsClose(p);
|
||||
sqlite3_set_last_insert_rowid(p->db, iLastRowid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3414,17 +3460,11 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
static int fts3SetHasStat(Fts3Table *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->bHasStat==2 ){
|
||||
const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
|
||||
char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
|
||||
if( zSql ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
char *zTbl = sqlite3_mprintf("%s_stat", p->zName);
|
||||
if( zTbl ){
|
||||
int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0);
|
||||
sqlite3_free(zTbl);
|
||||
p->bHasStat = (res==SQLITE_OK);
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@ -3531,18 +3571,17 @@ static int fts3FunctionArg(
|
||||
sqlite3_value *pVal, /* argv[0] passed to function */
|
||||
Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
|
||||
){
|
||||
Fts3Cursor *pRet;
|
||||
if( sqlite3_value_type(pVal)!=SQLITE_BLOB
|
||||
|| sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
|
||||
){
|
||||
int rc;
|
||||
*ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");
|
||||
if( (*ppCsr)!=0 ){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
|
||||
sqlite3_result_error(pContext, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
return SQLITE_ERROR;
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
|
||||
*ppCsr = pRet;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3929,7 +3968,7 @@ int sqlite3Fts3Init(sqlite3 *db){
|
||||
#endif
|
||||
|
||||
/* Create the virtual table wrapper around the hash-table and overload
|
||||
** the two scalar functions. If this is successful, register the
|
||||
** the four scalar functions. If this is successful, register the
|
||||
** module with sqlite.
|
||||
*/
|
||||
if( SQLITE_OK==rc
|
||||
@ -4512,7 +4551,7 @@ static int fts3EvalIncrPhraseNext(
|
||||
** one incremental token. In which case the bIncr flag is set. */
|
||||
assert( p->bIncr==1 );
|
||||
|
||||
if( p->nToken==1 && p->bIncr ){
|
||||
if( p->nToken==1 ){
|
||||
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
|
||||
&pDL->iDocid, &pDL->pList, &pDL->nList
|
||||
);
|
||||
@ -4745,6 +4784,7 @@ static void fts3EvalTokenCosts(
|
||||
** the number of overflow pages consumed by a record B bytes in size.
|
||||
*/
|
||||
static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->nRowAvg==0 ){
|
||||
/* The average document size, which is required to calculate the cost
|
||||
** of each doclist, has not yet been determined. Read the required
|
||||
@ -4757,7 +4797,6 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
** data stored in all rows of each column of the table, from left
|
||||
** to right.
|
||||
*/
|
||||
int rc;
|
||||
Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_int64 nDoc = 0;
|
||||
@ -4784,11 +4823,10 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
|
||||
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
|
||||
assert( pCsr->nRowAvg>0 );
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
|
||||
*pnPage = pCsr->nRowAvg;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5138,7 +5176,8 @@ static void fts3EvalNextRow(
|
||||
pExpr->iDocid = pLeft->iDocid;
|
||||
pExpr->bEof = (pLeft->bEof || pRight->bEof);
|
||||
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
|
||||
if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
|
||||
assert( pRight->eType==FTSQUERY_PHRASE );
|
||||
if( pRight->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
@ -5167,7 +5206,7 @@ static void fts3EvalNextRow(
|
||||
|
||||
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
}else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
|
||||
}else if( pLeft->bEof || iCmp>0 ){
|
||||
fts3EvalNextRow(pCsr, pRight, pRc);
|
||||
}else{
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
@ -5259,7 +5298,6 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
|
||||
*/
|
||||
if( *pRc==SQLITE_OK
|
||||
&& pExpr->eType==FTSQUERY_NEAR
|
||||
&& pExpr->bEof==0
|
||||
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
|
||||
){
|
||||
Fts3Expr *p;
|
||||
@ -5268,42 +5306,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
|
||||
|
||||
/* Allocate temporary working space. */
|
||||
for(p=pExpr; p->pLeft; p=p->pLeft){
|
||||
assert( p->pRight->pPhrase->doclist.nList>0 );
|
||||
nTmp += p->pRight->pPhrase->doclist.nList;
|
||||
}
|
||||
nTmp += p->pPhrase->doclist.nList;
|
||||
if( nTmp==0 ){
|
||||
aTmp = sqlite3_malloc(nTmp*2);
|
||||
if( !aTmp ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
res = 0;
|
||||
}else{
|
||||
aTmp = sqlite3_malloc(nTmp*2);
|
||||
if( !aTmp ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
res = 0;
|
||||
}else{
|
||||
char *aPoslist = p->pPhrase->doclist.pList;
|
||||
int nToken = p->pPhrase->nToken;
|
||||
char *aPoslist = p->pPhrase->doclist.pList;
|
||||
int nToken = p->pPhrase->nToken;
|
||||
|
||||
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
|
||||
Fts3Phrase *pPhrase = p->pRight->pPhrase;
|
||||
int nNear = p->nNear;
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
|
||||
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
|
||||
nToken = pExpr->pRight->pPhrase->nToken;
|
||||
for(p=pExpr->pLeft; p && res; p=p->pLeft){
|
||||
int nNear;
|
||||
Fts3Phrase *pPhrase;
|
||||
assert( p->pParent && p->pParent->pLeft==p );
|
||||
nNear = p->pParent->nNear;
|
||||
pPhrase = (
|
||||
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
|
||||
);
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
|
||||
Fts3Phrase *pPhrase = p->pRight->pPhrase;
|
||||
int nNear = p->nNear;
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
|
||||
sqlite3_free(aTmp);
|
||||
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
|
||||
nToken = pExpr->pRight->pPhrase->nToken;
|
||||
for(p=pExpr->pLeft; p && res; p=p->pLeft){
|
||||
int nNear;
|
||||
Fts3Phrase *pPhrase;
|
||||
assert( p->pParent && p->pParent->pLeft==p );
|
||||
nNear = p->pParent->nNear;
|
||||
pPhrase = (
|
||||
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
|
||||
);
|
||||
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_free(aTmp);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -230,6 +230,7 @@ struct Fts3Table {
|
||||
** statements is run and reset within a single virtual table API call.
|
||||
*/
|
||||
sqlite3_stmt *aStmt[40];
|
||||
sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
|
||||
|
||||
char *zReadExprlist;
|
||||
char *zWriteExprlist;
|
||||
@ -299,6 +300,7 @@ struct Fts3Cursor {
|
||||
i16 eSearch; /* Search strategy (see below) */
|
||||
u8 isEof; /* True if at End Of Results */
|
||||
u8 isRequireSeek; /* True if must seek pStmt to %_content row */
|
||||
u8 bSeekStmt; /* True if pStmt is a seek */
|
||||
sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
|
||||
Fts3Expr *pExpr; /* Parsed MATCH query string */
|
||||
int iLangid; /* Language being queried for */
|
||||
|
@ -136,16 +136,16 @@ static int unicodeAddExceptions(
|
||||
){
|
||||
const unsigned char *z = (const unsigned char *)zIn;
|
||||
const unsigned char *zTerm = &z[nIn];
|
||||
int iCode;
|
||||
unsigned int iCode;
|
||||
int nEntry = 0;
|
||||
|
||||
assert( bAlnum==0 || bAlnum==1 );
|
||||
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
|
||||
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
|
||||
){
|
||||
nEntry++;
|
||||
}
|
||||
@ -162,13 +162,13 @@ static int unicodeAddExceptions(
|
||||
z = (const unsigned char *)zIn;
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic(iCode)==0
|
||||
if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
|
||||
&& sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
|
||||
){
|
||||
int i, j;
|
||||
for(i=0; i<nNew && aNew[i]<iCode; i++);
|
||||
for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
|
||||
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
|
||||
aNew[i] = iCode;
|
||||
aNew[i] = (int)iCode;
|
||||
nNew++;
|
||||
}
|
||||
}
|
||||
@ -318,7 +318,7 @@ static int unicodeNext(
|
||||
){
|
||||
unicode_cursor *pCsr = (unicode_cursor *)pC;
|
||||
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
|
||||
int iCode = 0;
|
||||
unsigned int iCode = 0;
|
||||
char *zOut;
|
||||
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
|
||||
const unsigned char *zStart = z;
|
||||
@ -330,7 +330,7 @@ static int unicodeNext(
|
||||
** the input. */
|
||||
while( z<zTerm ){
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
if( unicodeIsAlnum(p, iCode) ) break;
|
||||
if( unicodeIsAlnum(p, (int)iCode) ) break;
|
||||
zStart = z;
|
||||
}
|
||||
if( zStart>=zTerm ) return SQLITE_DONE;
|
||||
@ -350,7 +350,7 @@ static int unicodeNext(
|
||||
|
||||
/* Write the folded case of the last character read to the output */
|
||||
zEnd = z;
|
||||
iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
|
||||
iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
|
||||
if( iOut ){
|
||||
WRITE_UTF8(zOut, iOut);
|
||||
}
|
||||
@ -358,8 +358,8 @@ static int unicodeNext(
|
||||
/* If the cursor is not at EOF, read the next character */
|
||||
if( z>=zTerm ) break;
|
||||
READ_UTF8(z, zTerm, iCode);
|
||||
}while( unicodeIsAlnum(p, iCode)
|
||||
|| sqlite3FtsUnicodeIsdiacritic(iCode)
|
||||
}while( unicodeIsAlnum(p, (int)iCode)
|
||||
|| sqlite3FtsUnicodeIsdiacritic((int)iCode)
|
||||
);
|
||||
|
||||
/* Set the output variables and return. */
|
||||
|
@ -127,9 +127,9 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
|
||||
};
|
||||
|
||||
if( c<128 ){
|
||||
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
|
||||
}else if( c<(1<<22) ){
|
||||
if( (unsigned int)c<128 ){
|
||||
return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
|
||||
}else if( (unsigned int)c<(1<<22) ){
|
||||
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
@ -322,16 +322,17 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
|
||||
int ret = c;
|
||||
|
||||
assert( c>=0 );
|
||||
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
|
||||
|
||||
if( c<128 ){
|
||||
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
|
||||
}else if( c<65536 ){
|
||||
const struct TableEntry *p;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
int iLo = 0;
|
||||
int iRes = -1;
|
||||
|
||||
assert( c>aEntry[0].iCode );
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
int cmp = (c - aEntry[iTest].iCode);
|
||||
@ -342,14 +343,12 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
assert( iRes<0 || c>=aEntry[iRes].iCode );
|
||||
|
||||
if( iRes>=0 ){
|
||||
const struct TableEntry *p = &aEntry[iRes];
|
||||
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
|
||||
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
|
||||
assert( ret>0 );
|
||||
}
|
||||
assert( iRes>=0 && c>=aEntry[iRes].iCode );
|
||||
p = &aEntry[iRes];
|
||||
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
|
||||
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
|
||||
assert( ret>0 );
|
||||
}
|
||||
|
||||
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
|
||||
|
@ -407,7 +407,8 @@ static int fts3SqlStmt(
|
||||
if( !zSql ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL);
|
||||
rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
|
||||
&pStmt, NULL);
|
||||
sqlite3_free(zSql);
|
||||
assert( rc==SQLITE_OK || pStmt==0 );
|
||||
p->aStmt[eStmt] = pStmt;
|
||||
@ -4956,11 +4957,14 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
|
||||
** Convert the text beginning at *pz into an integer and return
|
||||
** its value. Advance *pz to point to the first character past
|
||||
** the integer.
|
||||
**
|
||||
** This function used for parameters to merge= and incrmerge=
|
||||
** commands.
|
||||
*/
|
||||
static int fts3Getint(const char **pz){
|
||||
const char *z = *pz;
|
||||
int i = 0;
|
||||
while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
|
||||
while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
|
||||
*pz = z;
|
||||
return i;
|
||||
}
|
||||
|
16
ext/fts3/tool/fts3cov.sh
Normal file
16
ext/fts3/tool/fts3cov.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
srcdir=`dirname $(dirname $(dirname $(dirname $0)))`
|
||||
./testfixture $srcdir/test/fts3.test --output=fts3cov-out.txt
|
||||
|
||||
echo ""
|
||||
|
||||
for f in `ls $srcdir/ext/fts3/*.c`
|
||||
do
|
||||
f=`basename $f`
|
||||
echo -ne "$f: "
|
||||
gcov -b $f | grep Taken | sed 's/Taken at least once://'
|
||||
done
|
||||
|
@ -227,7 +227,7 @@ proc print_isalnum {zFunc lRange} {
|
||||
an_print_ascii_bitmap $lRange
|
||||
puts {
|
||||
if( (unsigned int)c<128 ){
|
||||
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
|
||||
return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
|
||||
}else if( (unsigned int)c<(1<<22) ){
|
||||
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
|
||||
int iRes = 0;
|
||||
|
@ -30,7 +30,9 @@ typedef short i16;
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
#ifndef ArraySize
|
||||
# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
#endif
|
||||
|
||||
#define testcase(x)
|
||||
#define ALWAYS(x) 1
|
||||
@ -444,9 +446,9 @@ int sqlite3Fts5IndexBeginWrite(
|
||||
|
||||
/*
|
||||
** Flush any data stored in the in-memory hash tables to the database.
|
||||
** If the bCommit flag is true, also close any open blob handles.
|
||||
** Also close any open blob handles.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p);
|
||||
|
||||
/*
|
||||
** Discard any data stored in the in-memory hash tables. Do not write it
|
||||
@ -616,7 +618,7 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
|
||||
int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
|
||||
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
|
||||
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageRollback(Fts5Storage *p);
|
||||
|
||||
int sqlite3Fts5StorageConfigValue(
|
||||
@ -652,6 +654,7 @@ struct Fts5Token {
|
||||
/* Parse a MATCH expression. */
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig,
|
||||
int iCol, /* Column on LHS of MATCH operator */
|
||||
const char *zExpr,
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
@ -736,7 +739,7 @@ void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
|
||||
void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
|
||||
|
||||
void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
|
||||
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
|
||||
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*);
|
||||
Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
|
||||
void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
|
||||
void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
|
||||
|
@ -67,9 +67,11 @@ void sqlite3Fts5BufferAppendBlob(
|
||||
const u8 *pData
|
||||
){
|
||||
assert_nc( *pRc || nData>=0 );
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
pBuf->n += nData;
|
||||
if( nData ){
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
pBuf->n += nData;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -246,8 +248,8 @@ void *sqlite3Fts5MallocZero(int *pRc, int nByte){
|
||||
void *pRet = 0;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
pRet = sqlite3_malloc(nByte);
|
||||
if( pRet==0 && nByte>0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
if( pRet==0 ){
|
||||
if( nByte>0 ) *pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pRet, 0, nByte);
|
||||
}
|
||||
|
@ -213,6 +213,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); }
|
||||
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig, /* FTS5 Configuration */
|
||||
int iCol,
|
||||
const char *zExpr, /* Expression text */
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
@ -237,6 +238,18 @@ int sqlite3Fts5ExprNew(
|
||||
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
|
||||
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
|
||||
|
||||
/* If the LHS of the MATCH expression was a user column, apply the
|
||||
** implicit column-filter. */
|
||||
if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
|
||||
int n = sizeof(Fts5Colset);
|
||||
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
|
||||
if( pColset ){
|
||||
pColset->nCol = 1;
|
||||
pColset->aiCol[0] = iCol;
|
||||
sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
|
||||
}
|
||||
}
|
||||
|
||||
assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
|
||||
if( sParse.rc==SQLITE_OK ){
|
||||
*ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
|
||||
@ -746,48 +759,61 @@ static int fts5ExprNearTest(
|
||||
** Initialize all term iterators in the pNear object. If any term is found
|
||||
** to match no documents at all, return immediately without initializing any
|
||||
** further iterators.
|
||||
**
|
||||
** If an error occurs, return an SQLite error code. Otherwise, return
|
||||
** SQLITE_OK. It is not considered an error if some term matches zero
|
||||
** documents.
|
||||
*/
|
||||
static int fts5ExprNearInitAll(
|
||||
Fts5Expr *pExpr,
|
||||
Fts5ExprNode *pNode
|
||||
){
|
||||
Fts5ExprNearset *pNear = pNode->pNear;
|
||||
int i, j;
|
||||
int rc = SQLITE_OK;
|
||||
int bEof = 1;
|
||||
int i;
|
||||
|
||||
assert( pNode->bNomatch==0 );
|
||||
for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
|
||||
for(i=0; i<pNear->nPhrase; i++){
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
|
||||
for(j=0; j<pPhrase->nTerm; j++){
|
||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
|
||||
Fts5ExprTerm *p;
|
||||
if( pPhrase->nTerm==0 ){
|
||||
pNode->bEof = 1;
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
int j;
|
||||
for(j=0; j<pPhrase->nTerm; j++){
|
||||
Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
|
||||
Fts5ExprTerm *p;
|
||||
int bHit = 0;
|
||||
|
||||
for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){
|
||||
if( p->pIter ){
|
||||
sqlite3Fts5IterClose(p->pIter);
|
||||
p->pIter = 0;
|
||||
for(p=pTerm; p; p=p->pSynonym){
|
||||
int rc;
|
||||
if( p->pIter ){
|
||||
sqlite3Fts5IterClose(p->pIter);
|
||||
p->pIter = 0;
|
||||
}
|
||||
rc = sqlite3Fts5IndexQuery(
|
||||
pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
|
||||
(pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
|
||||
(pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
|
||||
pNear->pColset,
|
||||
&p->pIter
|
||||
);
|
||||
assert( (rc==SQLITE_OK)==(p->pIter!=0) );
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( 0==sqlite3Fts5IterEof(p->pIter) ){
|
||||
bHit = 1;
|
||||
}
|
||||
}
|
||||
rc = sqlite3Fts5IndexQuery(
|
||||
pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
|
||||
(pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
|
||||
(pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
|
||||
pNear->pColset,
|
||||
&p->pIter
|
||||
);
|
||||
assert( rc==SQLITE_OK || p->pIter==0 );
|
||||
if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
|
||||
bEof = 0;
|
||||
|
||||
if( bHit==0 ){
|
||||
pNode->bEof = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if( bEof ) break;
|
||||
}
|
||||
if( bEof ) break;
|
||||
}
|
||||
|
||||
pNode->bEof = bEof;
|
||||
return rc;
|
||||
pNode->bEof = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1097,7 +1123,10 @@ static int fts5ExprNodeNext_OR(
|
||||
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
|
||||
){
|
||||
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1128,7 +1157,10 @@ static int fts5ExprNodeTest_AND(
|
||||
if( cmp>0 ){
|
||||
/* Advance pChild until it points to iLast or laster */
|
||||
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( rc!=SQLITE_OK ){
|
||||
pAnd->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
|
||||
@ -1167,6 +1199,8 @@ static int fts5ExprNodeNext_AND(
|
||||
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_AND(pExpr, pNode);
|
||||
}else{
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -1209,6 +1243,9 @@ static int fts5ExprNodeNext_NOT(
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1331,7 +1368,10 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
|
||||
|
||||
/* If not at EOF but the current rowid occurs earlier than iFirst in
|
||||
** the iteration order, move to document iFirst or later. */
|
||||
if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
|
||||
if( rc==SQLITE_OK
|
||||
&& 0==pRoot->bEof
|
||||
&& fts5RowidCmp(p, pRoot->iRowid, iFirst)<0
|
||||
){
|
||||
rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
|
||||
}
|
||||
|
||||
@ -1585,7 +1625,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
|
||||
rc = fts5ParseStringFromToken(pToken, &z);
|
||||
if( rc==SQLITE_OK ){
|
||||
int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
|
||||
int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
|
||||
int n;
|
||||
sqlite3Fts5Dequote(z);
|
||||
n = (int)strlen(z);
|
||||
@ -1859,25 +1899,110 @@ Fts5Colset *sqlite3Fts5ParseColset(
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** If argument pOrig is NULL, or if (*pRc) is set to anything other than
|
||||
** SQLITE_OK when this function is called, NULL is returned.
|
||||
**
|
||||
** Otherwise, a copy of (*pOrig) is made into memory obtained from
|
||||
** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
|
||||
** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
|
||||
*/
|
||||
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
|
||||
Fts5Colset *pRet;
|
||||
if( pOrig ){
|
||||
int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
|
||||
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
|
||||
if( pRet ){
|
||||
memcpy(pRet, pOrig, nByte);
|
||||
}
|
||||
}else{
|
||||
pRet = 0;
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Remove from colset pColset any columns that are not also in colset pMerge.
|
||||
*/
|
||||
static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
|
||||
int iIn = 0; /* Next input in pColset */
|
||||
int iMerge = 0; /* Next input in pMerge */
|
||||
int iOut = 0; /* Next output slot in pColset */
|
||||
|
||||
while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
|
||||
int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
|
||||
if( iDiff==0 ){
|
||||
pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
|
||||
iMerge++;
|
||||
iIn++;
|
||||
}else if( iDiff>0 ){
|
||||
iMerge++;
|
||||
}else{
|
||||
iIn++;
|
||||
}
|
||||
}
|
||||
pColset->nCol = iOut;
|
||||
}
|
||||
|
||||
/*
|
||||
** Recursively apply colset pColset to expression node pNode and all of
|
||||
** its decendents. If (*ppFree) is not NULL, it contains a spare copy
|
||||
** of pColset. This function may use the spare copy and set (*ppFree) to
|
||||
** zero, or it may create copies of pColset using fts5CloneColset().
|
||||
*/
|
||||
static void fts5ParseSetColset(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNode *pNode,
|
||||
Fts5Colset *pColset,
|
||||
Fts5Colset **ppFree
|
||||
){
|
||||
if( pParse->rc==SQLITE_OK ){
|
||||
assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
|
||||
|| pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
|
||||
|| pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
|
||||
);
|
||||
if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
|
||||
Fts5ExprNearset *pNear = pNode->pNear;
|
||||
if( pNear->pColset ){
|
||||
fts5MergeColset(pNear->pColset, pColset);
|
||||
if( pNear->pColset->nCol==0 ){
|
||||
pNode->eType = FTS5_EOF;
|
||||
pNode->xNext = 0;
|
||||
}
|
||||
}else if( *ppFree ){
|
||||
pNear->pColset = pColset;
|
||||
*ppFree = 0;
|
||||
}else{
|
||||
pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
|
||||
}
|
||||
}else{
|
||||
int i;
|
||||
assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
|
||||
for(i=0; i<pNode->nChild; i++){
|
||||
fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply colset pColset to expression node pExpr and all of its descendents.
|
||||
*/
|
||||
void sqlite3Fts5ParseSetColset(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNearset *pNear,
|
||||
Fts5ExprNode *pExpr,
|
||||
Fts5Colset *pColset
|
||||
){
|
||||
Fts5Colset *pFree = pColset;
|
||||
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: column queries are not supported (detail=none)"
|
||||
);
|
||||
sqlite3_free(pColset);
|
||||
return;
|
||||
}
|
||||
|
||||
if( pNear ){
|
||||
pNear->pColset = pColset;
|
||||
}else{
|
||||
sqlite3_free(pColset);
|
||||
fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
|
||||
}
|
||||
sqlite3_free(pFree);
|
||||
}
|
||||
|
||||
static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
|
||||
@ -2331,7 +2456,7 @@ static void fts5ExprFunction(
|
||||
|
||||
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zText;
|
||||
|
@ -36,9 +36,10 @@ struct Fts5Hash {
|
||||
|
||||
/*
|
||||
** Each entry in the hash table is represented by an object of the
|
||||
** following type. Each object, its key (zKey[]) and its current data
|
||||
** are stored in a single memory allocation. The position list data
|
||||
** immediately follows the key data in memory.
|
||||
** following type. Each object, its key (a nul-terminated string) and
|
||||
** its current data are stored in a single memory allocation. The
|
||||
** key immediately follows the object in memory. The position list
|
||||
** data immediately follows the key data in memory.
|
||||
**
|
||||
** The data that follows the key is in a similar, but not identical format
|
||||
** to the doclist data stored in the database. It is:
|
||||
@ -62,20 +63,20 @@ struct Fts5HashEntry {
|
||||
int nAlloc; /* Total size of allocation */
|
||||
int iSzPoslist; /* Offset of space for 4-byte poslist size */
|
||||
int nData; /* Total bytes of data (incl. structure) */
|
||||
int nKey; /* Length of zKey[] in bytes */
|
||||
int nKey; /* Length of key in bytes */
|
||||
u8 bDel; /* Set delete-flag @ iSzPoslist */
|
||||
u8 bContent; /* Set content-flag (detail=none mode) */
|
||||
i16 iCol; /* Column of last value written */
|
||||
int iPos; /* Position of last value written */
|
||||
i64 iRowid; /* Rowid of last value written */
|
||||
char zKey[8]; /* Nul-terminated entry key */
|
||||
};
|
||||
|
||||
/*
|
||||
** Size of Fts5HashEntry without the zKey[] array.
|
||||
** Eqivalent to:
|
||||
**
|
||||
** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
|
||||
*/
|
||||
#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8)
|
||||
|
||||
#define fts5EntryKey(p) ( ((char *)(&(p)[1])) )
|
||||
|
||||
|
||||
/*
|
||||
@ -170,10 +171,11 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||||
|
||||
for(i=0; i<pHash->nSlot; i++){
|
||||
while( apOld[i] ){
|
||||
int iHash;
|
||||
unsigned int iHash;
|
||||
Fts5HashEntry *p = apOld[i];
|
||||
apOld[i] = p->pHashNext;
|
||||
iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
|
||||
iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p),
|
||||
(int)strlen(fts5EntryKey(p)));
|
||||
p->pHashNext = apNew[iHash];
|
||||
apNew[iHash] = p;
|
||||
}
|
||||
@ -244,9 +246,10 @@ int sqlite3Fts5HashWrite(
|
||||
/* Attempt to locate an existing hash entry */
|
||||
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
|
||||
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
|
||||
if( p->zKey[0]==bByte
|
||||
char *zKey = fts5EntryKey(p);
|
||||
if( zKey[0]==bByte
|
||||
&& p->nKey==nToken
|
||||
&& memcmp(&p->zKey[1], pToken, nToken)==0
|
||||
&& memcmp(&zKey[1], pToken, nToken)==0
|
||||
){
|
||||
break;
|
||||
}
|
||||
@ -255,7 +258,8 @@ int sqlite3Fts5HashWrite(
|
||||
/* If an existing hash entry cannot be found, create a new one. */
|
||||
if( p==0 ){
|
||||
/* Figure out how much space to allocate */
|
||||
int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
|
||||
char *zKey;
|
||||
int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
|
||||
if( nByte<128 ) nByte = 128;
|
||||
|
||||
/* Grow the Fts5Hash.aSlot[] array if necessary. */
|
||||
@ -268,14 +272,15 @@ int sqlite3Fts5HashWrite(
|
||||
/* Allocate new Fts5HashEntry and add it to the hash table. */
|
||||
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
memset(p, 0, FTS5_HASHENTRYSIZE);
|
||||
memset(p, 0, sizeof(Fts5HashEntry));
|
||||
p->nAlloc = nByte;
|
||||
p->zKey[0] = bByte;
|
||||
memcpy(&p->zKey[1], pToken, nToken);
|
||||
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
|
||||
zKey = fts5EntryKey(p);
|
||||
zKey[0] = bByte;
|
||||
memcpy(&zKey[1], pToken, nToken);
|
||||
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) );
|
||||
p->nKey = nToken;
|
||||
p->zKey[nToken+1] = '\0';
|
||||
p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
|
||||
zKey[nToken+1] = '\0';
|
||||
p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry);
|
||||
p->pHashNext = pHash->aSlot[iHash];
|
||||
pHash->aSlot[iHash] = p;
|
||||
pHash->nEntry++;
|
||||
@ -393,9 +398,11 @@ static Fts5HashEntry *fts5HashEntryMerge(
|
||||
p1 = 0;
|
||||
}else{
|
||||
int i = 0;
|
||||
while( p1->zKey[i]==p2->zKey[i] ) i++;
|
||||
char *zKey1 = fts5EntryKey(p1);
|
||||
char *zKey2 = fts5EntryKey(p2);
|
||||
while( zKey1[i]==zKey2[i] ) i++;
|
||||
|
||||
if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){
|
||||
if( ((u8)zKey1[i])>((u8)zKey2[i]) ){
|
||||
/* p2 is smaller */
|
||||
*ppOut = p2;
|
||||
ppOut = &p2->pScanNext;
|
||||
@ -438,7 +445,7 @@ static int fts5HashEntrySort(
|
||||
for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
|
||||
Fts5HashEntry *pIter;
|
||||
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
|
||||
if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){
|
||||
if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
|
||||
Fts5HashEntry *pEntry = pIter;
|
||||
pEntry->pScanNext = 0;
|
||||
for(i=0; ap[i]; i++){
|
||||
@ -471,16 +478,18 @@ int sqlite3Fts5HashQuery(
|
||||
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||||
){
|
||||
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
|
||||
char *zKey = 0;
|
||||
Fts5HashEntry *p;
|
||||
|
||||
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
|
||||
if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break;
|
||||
zKey = fts5EntryKey(p);
|
||||
if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
|
||||
}
|
||||
|
||||
if( p ){
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
}else{
|
||||
*ppDoclist = 0;
|
||||
*pnDoclist = 0;
|
||||
@ -513,11 +522,12 @@ void sqlite3Fts5HashScanEntry(
|
||||
){
|
||||
Fts5HashEntry *p;
|
||||
if( (p = pHash->pScan) ){
|
||||
int nTerm = (int)strlen(p->zKey);
|
||||
char *zKey = fts5EntryKey(p);
|
||||
int nTerm = (int)strlen(zKey);
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*pzTerm = p->zKey;
|
||||
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
|
||||
*pzTerm = zKey;
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
}else{
|
||||
*pzTerm = 0;
|
||||
*ppDoclist = 0;
|
||||
|
@ -628,7 +628,6 @@ static void fts5CloseReader(Fts5Index *p){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Retrieve a record from the %_data table.
|
||||
**
|
||||
@ -729,7 +728,8 @@ static int fts5IndexPrepareStmt(
|
||||
){
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( zSql ){
|
||||
p->rc = sqlite3_prepare_v2(p->pConfig->db, zSql, -1, ppStmt, 0);
|
||||
p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
|
||||
SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
|
||||
}else{
|
||||
p->rc = SQLITE_NOMEM;
|
||||
}
|
||||
@ -778,7 +778,8 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p->pDeleter, 0);
|
||||
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
|
||||
SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
@ -2039,7 +2040,7 @@ static void fts5SegIterNext(
|
||||
else if( pLeaf->nn>pLeaf->szLeaf ){
|
||||
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
|
||||
&pLeaf->p[pLeaf->szLeaf], iOff
|
||||
);
|
||||
);
|
||||
pIter->iLeafOffset = iOff;
|
||||
pIter->iEndofDoclist = iOff;
|
||||
bNewTerm = 1;
|
||||
@ -2073,6 +2074,7 @@ static void fts5SegIterNext(
|
||||
*/
|
||||
int nSz;
|
||||
assert( p->rc==SQLITE_OK );
|
||||
assert( pIter->iLeafOffset<=pIter->pLeaf->nn );
|
||||
fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
|
||||
pIter->bDel = (nSz & 0x0001);
|
||||
pIter->nPos = nSz>>1;
|
||||
@ -2878,7 +2880,8 @@ static void fts5MultiIterNext2(
|
||||
){
|
||||
assert( pIter->bSkipEmpty );
|
||||
if( p->rc==SQLITE_OK ){
|
||||
do {
|
||||
*pbNewTerm = 0;
|
||||
do{
|
||||
int iFirst = pIter->aFirst[1].iFirst;
|
||||
Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
|
||||
int bNewTerm = 0;
|
||||
@ -2891,8 +2894,6 @@ static void fts5MultiIterNext2(
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
*pbNewTerm = 1;
|
||||
}else{
|
||||
*pbNewTerm = 0;
|
||||
}
|
||||
fts5AssertMultiIterSetup(p, pIter);
|
||||
|
||||
@ -3067,7 +3068,7 @@ static void fts5ChunkIterate(
|
||||
break;
|
||||
}else{
|
||||
pgno++;
|
||||
pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
|
||||
pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
|
||||
if( pData==0 ) break;
|
||||
pChunk = &pData->p[4];
|
||||
nChunk = MIN(nRem, pData->szLeaf - 4);
|
||||
@ -3158,23 +3159,23 @@ static int fts5IndexExtractCol(
|
||||
return p - (*pa);
|
||||
}
|
||||
|
||||
static int fts5IndexExtractColset (
|
||||
static void fts5IndexExtractColset(
|
||||
int *pRc,
|
||||
Fts5Colset *pColset, /* Colset to filter on */
|
||||
const u8 *pPos, int nPos, /* Position list */
|
||||
Fts5Buffer *pBuf /* Output buffer */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
|
||||
fts5BufferZero(pBuf);
|
||||
for(i=0; i<pColset->nCol; i++){
|
||||
const u8 *pSub = pPos;
|
||||
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
||||
if( nSub ){
|
||||
fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
|
||||
if( *pRc==SQLITE_OK ){
|
||||
int i;
|
||||
fts5BufferZero(pBuf);
|
||||
for(i=0; i<pColset->nCol; i++){
|
||||
const u8 *pSub = pPos;
|
||||
int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
|
||||
if( nSub ){
|
||||
fts5BufferAppendBlob(pRc, pBuf, nSub, pSub);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3298,8 +3299,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||
pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
|
||||
pIter->base.pData = a;
|
||||
}else{
|
||||
int *pRc = &pIter->pIndex->rc;
|
||||
fts5BufferZero(&pIter->poslist);
|
||||
fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
|
||||
fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist);
|
||||
pIter->base.pData = pIter->poslist.p;
|
||||
pIter->base.nData = pIter->poslist.n;
|
||||
}
|
||||
@ -3844,9 +3846,6 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
|
||||
Fts5PageWriter *pPage = &pWriter->writer;
|
||||
i64 iRowid;
|
||||
|
||||
static int nCall = 0;
|
||||
nCall++;
|
||||
|
||||
assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
|
||||
|
||||
/* Set the szLeaf header field. */
|
||||
@ -4195,6 +4194,7 @@ static void fts5IndexMergeLevel(
|
||||
int bOldest; /* True if the output segment is the oldest */
|
||||
int eDetail = p->pConfig->eDetail;
|
||||
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
|
||||
int bTermWritten = 0; /* True if current term already output */
|
||||
|
||||
assert( iLvl<pStruct->nLevel );
|
||||
assert( pLvl->nMerge<=pLvl->nSeg );
|
||||
@ -4248,18 +4248,22 @@ static void fts5IndexMergeLevel(
|
||||
int nTerm;
|
||||
const u8 *pTerm;
|
||||
|
||||
/* Check for key annihilation. */
|
||||
if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
|
||||
|
||||
pTerm = fts5MultiIterTerm(pIter, &nTerm);
|
||||
if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
|
||||
if( pnRem && writer.nLeafWritten>nRem ){
|
||||
break;
|
||||
}
|
||||
fts5BufferSet(&p->rc, &term, nTerm, pTerm);
|
||||
bTermWritten =0;
|
||||
}
|
||||
|
||||
/* Check for key annihilation. */
|
||||
if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
|
||||
|
||||
if( p->rc==SQLITE_OK && bTermWritten==0 ){
|
||||
/* This is a new term. Append a term to the output segment. */
|
||||
fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
|
||||
fts5BufferSet(&p->rc, &term, nTerm, pTerm);
|
||||
bTermWritten = 1;
|
||||
}
|
||||
|
||||
/* Append the rowid to the output */
|
||||
@ -5091,7 +5095,7 @@ static void fts5SetupPrefixIter(
|
||||
if( pData ){
|
||||
pData->p = (u8*)&pData[1];
|
||||
pData->nn = pData->szLeaf = doclist.n;
|
||||
memcpy(pData->p, doclist.p, doclist.n);
|
||||
if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
|
||||
fts5MultiIterNew2(p, pData, bDesc, ppIter);
|
||||
}
|
||||
fts5BufferFree(&doclist);
|
||||
@ -5130,10 +5134,10 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
|
||||
/*
|
||||
** Commit data to disk.
|
||||
*/
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
if( bCommit ) fts5CloseReader(p);
|
||||
fts5CloseReader(p);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
@ -5330,7 +5334,7 @@ int sqlite3Fts5IndexQuery(
|
||||
|
||||
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
|
||||
int iIdx = 0; /* Index to search */
|
||||
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
|
||||
@ -5379,7 +5383,7 @@ int sqlite3Fts5IndexQuery(
|
||||
}
|
||||
|
||||
if( p->rc ){
|
||||
sqlite3Fts5IterClose(&pRet->base);
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
|
||||
pRet = 0;
|
||||
fts5CloseReader(p);
|
||||
}
|
||||
@ -5829,7 +5833,7 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
** ignore this b-tree entry. Otherwise, load it into memory. */
|
||||
if( iIdxLeaf<pSeg->pgnoFirst ) continue;
|
||||
iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
|
||||
pLeaf = fts5DataRead(p, iRow);
|
||||
pLeaf = fts5LeafRead(p, iRow);
|
||||
if( pLeaf==0 ) break;
|
||||
|
||||
/* Check that the leaf contains at least one term, and that it is equal
|
||||
|
@ -506,6 +506,7 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
Fts5Table *pTab = (Fts5Table*)pVTab;
|
||||
Fts5Config *pConfig = pTab->pConfig;
|
||||
const int nCol = pConfig->nCol;
|
||||
int idxFlags = 0; /* Parameter passed through to xFilter() */
|
||||
int bHasMatch;
|
||||
int iNext;
|
||||
@ -531,24 +532,34 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
|
||||
int aColMap[3];
|
||||
aColMap[0] = -1;
|
||||
aColMap[1] = pConfig->nCol;
|
||||
aColMap[2] = pConfig->nCol+1;
|
||||
aColMap[1] = nCol;
|
||||
aColMap[2] = nCol+1;
|
||||
|
||||
/* Set idxFlags flags for all WHERE clause terms that will be used. */
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
int j;
|
||||
for(j=0; j<ArraySize(aConstraint); j++){
|
||||
struct Constraint *pC = &aConstraint[j];
|
||||
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
|
||||
if( p->usable ){
|
||||
int iCol = p->iColumn;
|
||||
|
||||
if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
|
||||
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
|
||||
){
|
||||
/* A MATCH operator or equivalent */
|
||||
if( p->usable ){
|
||||
idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
|
||||
aConstraint[0].iConsIndex = i;
|
||||
}else{
|
||||
/* As there exists an unusable MATCH constraint this is an
|
||||
** unusable plan. Set a prohibitively high cost. */
|
||||
pInfo->estimatedCost = 1e50;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}else{
|
||||
int j;
|
||||
for(j=1; j<ArraySize(aConstraint); j++){
|
||||
struct Constraint *pC = &aConstraint[j];
|
||||
if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
|
||||
pC->iConsIndex = i;
|
||||
idxFlags |= pC->fts5op;
|
||||
}else if( j==0 ){
|
||||
/* As there exists an unusable MATCH constraint this is an
|
||||
** unusable plan. Set a prohibitively high cost. */
|
||||
pInfo->estimatedCost = 1e50;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -872,7 +883,8 @@ static int fts5PrepareStatement(
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0);
|
||||
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
|
||||
SQLITE_PREPARE_PERSISTENT, &pRet, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
|
||||
}
|
||||
@ -1008,7 +1020,8 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
|
||||
char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
|
||||
if( zSql ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pStmt, 0);
|
||||
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
|
||||
SQLITE_PREPARE_PERSISTENT, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -1123,6 +1136,7 @@ static int fts5FilterMethod(
|
||||
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
|
||||
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
|
||||
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
|
||||
int iCol; /* Column on LHS of MATCH operator */
|
||||
char **pzErrmsg = pConfig->pzErrmsg;
|
||||
|
||||
UNUSED_PARAM(zUnused);
|
||||
@ -1153,6 +1167,8 @@ static int fts5FilterMethod(
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
|
||||
iCol = (idxNum>>16);
|
||||
assert( iCol>=0 && iCol<=pConfig->nCol );
|
||||
assert( iVal==nVal );
|
||||
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
|
||||
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
|
||||
@ -1199,7 +1215,7 @@ static int fts5FilterMethod(
|
||||
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
|
||||
}else{
|
||||
char **pzErr = &pTab->base.zErrMsg;
|
||||
rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bOrderByRank ){
|
||||
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
|
||||
@ -1579,7 +1595,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
|
||||
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
|
||||
fts5TripCursors(pTab);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
|
||||
rc = sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
pTab->pConfig->pzErrmsg = 0;
|
||||
return rc;
|
||||
}
|
||||
@ -2390,7 +2406,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2403,7 +2419,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2593,15 +2609,14 @@ static void fts5ModuleDestroy(void *pCtx){
|
||||
static void fts5Fts5Func(
|
||||
sqlite3_context *pCtx, /* Function call context */
|
||||
int nArg, /* Number of args */
|
||||
sqlite3_value **apUnused /* Function arguments */
|
||||
sqlite3_value **apArg /* Function arguments */
|
||||
){
|
||||
Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
|
||||
char buf[8];
|
||||
UNUSED_PARAM2(nArg, apUnused);
|
||||
assert( nArg==0 );
|
||||
assert( sizeof(buf)>=sizeof(pGlobal) );
|
||||
memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
|
||||
sqlite3_result_blob(pCtx, buf, sizeof(pGlobal), SQLITE_TRANSIENT);
|
||||
fts5_api **ppApi;
|
||||
UNUSED_PARAM(nArg);
|
||||
assert( nArg==1 );
|
||||
ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
|
||||
if( ppApi ) *ppApi = &pGlobal->api;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2666,7 +2681,7 @@ static int fts5Init(sqlite3 *db){
|
||||
if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(
|
||||
db, "fts5", 0, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
|
||||
db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
|
@ -136,7 +136,8 @@ static int fts5StorageGetStmt(
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(pC->db, zSql, -1, &p->aStmt[eStmt], 0);
|
||||
rc = sqlite3_prepare_v3(pC->db, zSql, -1,
|
||||
SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc!=SQLITE_OK && pzErrMsg ){
|
||||
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
|
||||
@ -218,7 +219,7 @@ static void fts5StorageRenameOne(
|
||||
|
||||
int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
|
||||
Fts5Config *pConfig = pStorage->pConfig;
|
||||
int rc = sqlite3Fts5StorageSync(pStorage, 1);
|
||||
int rc = sqlite3Fts5StorageSync(pStorage);
|
||||
|
||||
fts5StorageRenameOne(pConfig, &rc, "data", zName);
|
||||
fts5StorageRenameOne(pConfig, &rc, "idx", zName);
|
||||
@ -545,11 +546,6 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -753,11 +749,6 @@ int sqlite3Fts5StorageIndexInsert(
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1091,13 +1082,18 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
|
||||
/*
|
||||
** Flush any data currently held in-memory to disk.
|
||||
*/
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
|
||||
if( bCommit && p->bTotalsValid ){
|
||||
int rc = fts5StorageSaveTotals(p);
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p){
|
||||
int rc = SQLITE_OK;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
|
||||
if( p->bTotalsValid ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
p->bTotalsValid = 0;
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
return sqlite3Fts5IndexSync(p->pIndex, bCommit);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex);
|
||||
}
|
||||
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sqlite3Fts5StorageRollback(Fts5Storage *p){
|
||||
|
@ -99,16 +99,13 @@ static int SQLITE_TCLAPI f5tDbAndApi(
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
fts5_api *pApi = 0;
|
||||
|
||||
rc = sqlite3_prepare_v2(db, "SELECT fts5()", -1, &pStmt, 0);
|
||||
rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
const void *pPtr = sqlite3_column_blob(pStmt, 0);
|
||||
memcpy((void*)&pApi, pPtr, sizeof(pApi));
|
||||
}
|
||||
sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0);
|
||||
sqlite3_step(pStmt);
|
||||
|
||||
if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
|
@ -73,13 +73,10 @@ static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
|
||||
int rc;
|
||||
|
||||
*ppApi = 0;
|
||||
rc = sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0);
|
||||
rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt)
|
||||
&& sizeof(fts5_api*)==sqlite3_column_bytes(pStmt, 0)
|
||||
){
|
||||
memcpy(ppApi, sqlite3_column_blob(pStmt, 0), sizeof(fts5_api*));
|
||||
}
|
||||
sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr", 0);
|
||||
(void)sqlite3_step(pStmt);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
@ -422,4 +419,3 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_FTS5 */
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
*/
|
||||
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5)
|
||||
|
||||
#include <fts5.h>
|
||||
#include "fts5.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -182,7 +182,7 @@ static int fts5tokConnectMethod(
|
||||
Fts5tokTable *pTab = 0;
|
||||
int rc;
|
||||
char **azDequote = 0;
|
||||
int nDequote;
|
||||
int nDequote = 0;
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(input HIDDEN, token, start, end, position)"
|
||||
|
@ -89,32 +89,6 @@ input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); }
|
||||
%destructor expr { sqlite3Fts5ParseNodeFree($$); }
|
||||
%destructor exprlist { sqlite3Fts5ParseNodeFree($$); }
|
||||
|
||||
expr(A) ::= expr(X) AND expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) OR expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_OR, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_NOT, X, Y, 0);
|
||||
}
|
||||
|
||||
expr(A) ::= LP expr(X) RP. {A = X;}
|
||||
expr(A) ::= exprlist(X). {A = X;}
|
||||
|
||||
exprlist(A) ::= cnearset(X). {A = X;}
|
||||
exprlist(A) ::= exprlist(X) cnearset(Y). {
|
||||
A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y);
|
||||
}
|
||||
|
||||
cnearset(A) ::= nearset(X). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X);
|
||||
}
|
||||
cnearset(A) ::= colset(X) COLON nearset(Y). {
|
||||
sqlite3Fts5ParseSetColset(pParse, Y, X);
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y);
|
||||
}
|
||||
|
||||
%type colset {Fts5Colset*}
|
||||
%destructor colset { sqlite3_free($$); }
|
||||
%type colsetlist {Fts5Colset*}
|
||||
@ -138,6 +112,37 @@ colsetlist(A) ::= STRING(X). {
|
||||
A = sqlite3Fts5ParseColset(pParse, 0, &X);
|
||||
}
|
||||
|
||||
expr(A) ::= expr(X) AND expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) OR expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_OR, X, Y, 0);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT expr(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_NOT, X, Y, 0);
|
||||
}
|
||||
|
||||
expr(A) ::= colset(X) COLON LP expr(Y) RP. {
|
||||
sqlite3Fts5ParseSetColset(pParse, Y, X);
|
||||
A = Y;
|
||||
}
|
||||
expr(A) ::= LP expr(X) RP. {A = X;}
|
||||
expr(A) ::= exprlist(X). {A = X;}
|
||||
|
||||
exprlist(A) ::= cnearset(X). {A = X;}
|
||||
exprlist(A) ::= exprlist(X) cnearset(Y). {
|
||||
A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y);
|
||||
}
|
||||
|
||||
cnearset(A) ::= nearset(X). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X);
|
||||
}
|
||||
cnearset(A) ::= colset(X) COLON nearset(Y). {
|
||||
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y);
|
||||
sqlite3Fts5ParseSetColset(pParse, A, X);
|
||||
}
|
||||
|
||||
|
||||
%type nearset {Fts5ExprNearset*}
|
||||
%type nearphrases {Fts5ExprNearset*}
|
||||
%destructor nearset { sqlite3Fts5ParseNearsetFree($$); }
|
||||
|
@ -441,7 +441,7 @@ db func funk funk
|
||||
do_catchsql_test 16.2 {
|
||||
SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d'
|
||||
} {0 {{} -1e-06 {}}}
|
||||
# {1 {SQL logic error or missing database}}
|
||||
# {1 {SQL logic error}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -561,9 +561,37 @@ do_test 20.1 {
|
||||
execsql { SELECT rowid FROM tmp WHERE tmp MATCH 'y' }
|
||||
} $::ids
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Test that a DROP TABLE may be executed within a transaction that
|
||||
# writes to an FTS5 table.
|
||||
#
|
||||
do_execsql_test 21.0 {
|
||||
CREATE TEMP TABLE t8(a, b);
|
||||
CREATE VIRTUAL TABLE ft USING fts5(x, detail=%DETAIL%);
|
||||
}
|
||||
|
||||
do_execsql_test 21.1 {
|
||||
BEGIN;
|
||||
INSERT INTO ft VALUES('a b c');
|
||||
DROP TABLE t8;
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 22.0 {
|
||||
CREATE VIRTUAL TABLE t9 USING fts5(x, detail=%DETAIL%);
|
||||
INSERT INTO t9(rowid, x) VALUES(2, 'bbb');
|
||||
BEGIN;
|
||||
INSERT INTO t9(rowid, x) VALUES(1, 'aaa');
|
||||
DELETE FROM t9 WHERE rowid = 2;
|
||||
INSERT INTO t9(rowid, x) VALUES(3, 'bbb');
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 22.1 {
|
||||
SELECT rowid FROM t9('a*')
|
||||
} {1}
|
||||
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -294,4 +294,3 @@ do_execsql_test 7.0 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -276,4 +276,3 @@ foreach {tn expr tclexpr} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -231,7 +231,6 @@ foreach {T create} {
|
||||
set res [lsort -integer -increasing $res]
|
||||
}
|
||||
set n [llength $res]
|
||||
if {$T==5} breakpoint
|
||||
do_execsql_test $T.$bAsc.$tn.$n $sql $res
|
||||
}
|
||||
}
|
||||
@ -242,4 +241,3 @@ foreach {T create} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -309,4 +309,3 @@ foreach {tn q cnt} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -178,4 +178,3 @@ do_execsql_test 5.1 {
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -142,4 +142,3 @@ if {[detail_is_full]} {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -167,4 +167,3 @@ do_execsql_test 1.8.2 {
|
||||
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -55,4 +55,3 @@ do_execsql_test 1.2 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -66,4 +66,3 @@ do_execsql_test 2.0 { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -147,4 +147,3 @@ do_execsql_test 3.1 {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -77,7 +77,7 @@ foreach {tn defn} {
|
||||
} {
|
||||
do_test 2.2.$tn {
|
||||
catchsql { INSERT INTO ft1(ft1, rank) VALUES('rank', $defn) }
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -297,4 +297,3 @@ do_catchsql_test 4.4.4 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -89,7 +89,6 @@ do_execsql_test 3.1 {
|
||||
BEGIN;
|
||||
INSERT INTO abc(rowid, a) VALUES(2, 'a');
|
||||
}
|
||||
breakpoint
|
||||
do_execsql_test 3.2 {
|
||||
SELECT rowid FROM abc WHERE abc MATCH 'a';
|
||||
} {1 2}
|
||||
@ -100,4 +99,3 @@ do_execsql_test 3.3 {
|
||||
} {1 2}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -342,4 +342,3 @@ foreach {tn expr} {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -240,7 +240,6 @@ foreach {tn lRow res} {
|
||||
} {
|
||||
execsql { DELETE FROM x1 }
|
||||
foreach row $lRow { execsql { INSERT INTO x1 VALUES($row) } }
|
||||
breakpoint
|
||||
do_execsql_test 8.$tn {
|
||||
SELECT highlight(x1, 0, '[', ']') FROM x1 WHERE x1 MATCH 'a OR (b AND d)';
|
||||
} $res
|
||||
@ -279,4 +278,3 @@ do_execsql_test 9.3 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -112,4 +112,3 @@ db eval {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -61,4 +61,3 @@ do_test 2.1...slow {
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -64,5 +64,3 @@ foreach_detail_mode $::testprefix {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -44,16 +44,43 @@ foreach_detail_mode $::testprefix {
|
||||
9 "-c : a" {1 2 4}
|
||||
10 "-\"c\" : a" {1 2 4}
|
||||
} {
|
||||
breakpoint
|
||||
do_execsql_test 1.$tn {
|
||||
SELECT rowid FROM t1($q)
|
||||
} $res
|
||||
}
|
||||
|
||||
foreach {tn q res} {
|
||||
0 {{a} : (a AND ":")} {}
|
||||
1 "{a b c} : (a AND d)" {2 3}
|
||||
2 "{a b c} : (a AND b:d)" {3}
|
||||
3 "{a b c} : (a AND d:d)" {}
|
||||
4 "{b} : ( {b a} : ( {c b a} : ( {d b c a} : ( d OR c ) ) ) )" {3 4}
|
||||
5 "{a} : ( {b a} : ( {c b a} : ( {d b c a} : ( d OR c ) ) ) )" {2 3}
|
||||
6 "{a} : ( {b a} : ( {c b} : ( {d b c a} : ( d OR c ) ) ) )" {}
|
||||
7 "{a b c} : (b:a AND c:b)" {2}
|
||||
} {
|
||||
do_execsql_test 2.$tn {
|
||||
SELECT rowid FROM t1($q)
|
||||
} $res
|
||||
}
|
||||
|
||||
foreach {tn w res} {
|
||||
0 "a MATCH 'a'" {1}
|
||||
1 "b MATCH 'a'" {2}
|
||||
2 "b MATCH '{a b c} : a'" {2}
|
||||
3 "b MATCH 'a OR b'" {1 2}
|
||||
4 "b MATCH 'a OR a:b'" {2}
|
||||
5 "b MATCH 'a OR b:b'" {1 2}
|
||||
} {
|
||||
do_execsql_test 3.$tn "
|
||||
SELECT rowid FROM t1 WHERE $w
|
||||
" $res
|
||||
}
|
||||
|
||||
do_catchsql_test 4.1 {
|
||||
SELECT * FROM t1 WHERE rowid MATCH 'a'
|
||||
} {1 {unable to use function MATCH in the requested context}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -143,7 +143,6 @@ do_execsql_test 4.1.1 {
|
||||
INSERT INTO t5 VALUES('2 4 6 8');
|
||||
}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 4.1.2 {
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ foreach {tn val} {
|
||||
} {
|
||||
do_catchsql_test 3.$tn {
|
||||
INSERT INTO t1(t1, rank) VALUES('rank', $val);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -110,7 +110,6 @@ do_catchsql_test 5.1 {
|
||||
CREATE VIRTUAL TABLE xx USING fts5(x, tokenize="porter 'ascii");
|
||||
} {1 {parse error in tokenize directive}}
|
||||
|
||||
breakpoint
|
||||
do_catchsql_test 5.2 {
|
||||
CREATE VIRTUAL TABLE xx USING fts5(x, [y[]);
|
||||
} {0 {}}
|
||||
@ -169,33 +168,33 @@ do_execsql_test 9.0 {
|
||||
} {}
|
||||
do_catchsql_test 9.1.1 {
|
||||
INSERT INTO abc(abc, rank) VALUES('pgsz', -5);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.1.2 {
|
||||
INSERT INTO abc(abc, rank) VALUES('pgsz', 50000000);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.1.3 {
|
||||
INSERT INTO abc(abc, rank) VALUES('pgsz', 66.67);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
|
||||
do_catchsql_test 9.2.1 {
|
||||
INSERT INTO abc(abc, rank) VALUES('automerge', -5);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.2.2 {
|
||||
INSERT INTO abc(abc, rank) VALUES('automerge', 50000000);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.2.3 {
|
||||
INSERT INTO abc(abc, rank) VALUES('automerge', 66.67);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_execsql_test 9.2.4 {
|
||||
INSERT INTO abc(abc, rank) VALUES('automerge', 1);
|
||||
} {}
|
||||
|
||||
do_catchsql_test 9.3.1 {
|
||||
INSERT INTO abc(abc, rank) VALUES('crisismerge', -5);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.3.2 {
|
||||
INSERT INTO abc(abc, rank) VALUES('crisismerge', 66.67);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_execsql_test 9.3.3 {
|
||||
INSERT INTO abc(abc, rank) VALUES('crisismerge', 1);
|
||||
} {}
|
||||
@ -205,14 +204,14 @@ do_execsql_test 9.3.4 {
|
||||
|
||||
do_catchsql_test 9.4.1 {
|
||||
INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
|
||||
do_catchsql_test 9.5.1 {
|
||||
INSERT INTO abc(abc, rank) VALUES('hashsize', 'not an integer');
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.5.2 {
|
||||
INSERT INTO abc(abc, rank) VALUES('hashsize', -500000);
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
do_catchsql_test 9.5.3 {
|
||||
INSERT INTO abc(abc, rank) VALUES('hashsize', 500000);
|
||||
} {0 {}}
|
||||
@ -245,7 +244,7 @@ foreach {tn opt} {
|
||||
|
||||
do_catchsql_test 12.1 {
|
||||
INSERT INTO t1(t1, rank) VALUES('rank', NULL);;
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {1 {SQL logic error}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# errors in the 'usermerge' option
|
||||
@ -260,8 +259,7 @@ foreach {tn val} {
|
||||
4 1
|
||||
} {
|
||||
set sql "INSERT INTO tt(tt, rank) VALUES('usermerge', $val)"
|
||||
do_catchsql_test 13.$tn $sql {1 {SQL logic error or missing database}}
|
||||
do_catchsql_test 13.$tn $sql {1 {SQL logic error}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -66,5 +66,3 @@ do_execsql_test 2.1 {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -255,4 +255,3 @@ do_execsql_test 6.2 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -96,4 +96,3 @@ do_catchsql_test 3.1 {
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -269,4 +269,3 @@ do_catchsql_test 6.2 {
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
@ -409,4 +409,3 @@ do_catchsql_test 9.2.2 {
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
53
ext/fts5/test/fts5delete.test
Normal file
53
ext/fts5/test/fts5delete.test
Normal file
@ -0,0 +1,53 @@
|
||||
# 2017 May 12
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5delete
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
fts5_aux_test_functions db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<5000
|
||||
)
|
||||
INSERT INTO t1(rowid, x) SELECT i, (i/2)*2 FROM s;
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
execsql BEGIN
|
||||
for {set i 1} {$i<=5000} {incr i} {
|
||||
if {$i % 2} {
|
||||
execsql { INSERT INTO t1 VALUES($i) }
|
||||
} else {
|
||||
execsql { DELETE FROM t1 WHERE rowid = $i }
|
||||
}
|
||||
}
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test 1.2 {
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('usermerge', 2); }
|
||||
for {set i 0} {$i < 5} {incr i} {
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
|
||||
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
}
|
||||
} {}
|
||||
|
||||
finish_test
|
@ -241,4 +241,3 @@ do_execsql_test 5.3 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -63,5 +63,3 @@ foreach_detail_mode $::testprefix {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -66,7 +66,6 @@ proc do_dlidx_test1 {tn spc1 spc2 nEntry iFirst nStep} {
|
||||
}
|
||||
execsql COMMIT
|
||||
|
||||
breakpoint
|
||||
do_test $tn.1 {
|
||||
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
} {}
|
||||
@ -124,7 +123,6 @@ proc do_dlidx_test2 {tn nEntry iFirst nStep} {
|
||||
do_execsql_test $tn.1 {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a'
|
||||
} {1}
|
||||
breakpoint
|
||||
do_execsql_test $tn.2 {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a' ORDER BY rowid DESC
|
||||
} {1}
|
||||
@ -197,4 +195,3 @@ foreach v $vocab {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -44,4 +44,3 @@ do_execsql_test 1.2 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -81,6 +81,3 @@ do_execsql_test 3.3 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
|
@ -351,4 +351,3 @@ do_faultsim_test 9.1 -faults oom-* -prep {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -137,4 +137,3 @@ do_faultsim_test 5.0 -faults oom-* -prep {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -110,4 +110,3 @@ do_faultsim_test 3.2 -faults oom-* -prep {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -395,4 +395,3 @@ do_faultsim_test 14.1 -faults oom-t* -prep {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -105,7 +105,6 @@ do_faultsim_test 3.2 -faults oom-t* -body {
|
||||
faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}}
|
||||
}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 3.3.0 {
|
||||
SELECT * FROM tv2;
|
||||
} {
|
||||
@ -130,4 +129,3 @@ do_faultsim_test 3.3 -faults oom-t* -body {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -280,7 +280,6 @@ do_faultsim_test 5.4 -faults oom* -prep {
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
catch { db close }
|
||||
breakpoint
|
||||
do_faultsim_test 6 -faults oom* -prep {
|
||||
sqlite_orig db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
@ -292,4 +291,3 @@ do_faultsim_test 6 -faults oom* -prep {
|
||||
db close
|
||||
}
|
||||
finish_test
|
||||
|
||||
|
@ -116,4 +116,3 @@ do_faultsim_test 2.2 -faults oom-* -body {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -82,4 +82,3 @@ do_faultsim_test 4 -faults oom-* -prep {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -153,4 +153,3 @@ do_faultsim_test 6 -faults oom-* -body {
|
||||
} ;# foreach_detail_mode...
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -61,4 +61,3 @@ do_faultsim_test 2 -faults oom* -prep {
|
||||
faultsim_test_result {0 {1 2}}
|
||||
}
|
||||
finish_test
|
||||
|
||||
|
@ -78,6 +78,57 @@ do_faultsim_test 2.4 -faults oom* -body {
|
||||
faultsim_test_result {0 {{3 2} {2 3}}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(z);
|
||||
}
|
||||
|
||||
do_faultsim_test 3.1 -faults oom* -body {
|
||||
execsql {
|
||||
SELECT rowid FROM x1('c') WHERE rowid>1;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
INSERT INTO x1 VALUES('a b c');
|
||||
INSERT INTO x1 VALUES('b c d');
|
||||
INSERT INTO x1 VALUES('c d e');
|
||||
INSERT INTO x1 VALUES('d e f');
|
||||
}
|
||||
do_faultsim_test 3.3 -faults oom* -body {
|
||||
execsql {
|
||||
SELECT rowid FROM x1('c') WHERE rowid>1;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {2 3}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test OOM injection with nested colsets.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, d);
|
||||
INSERT INTO t1 VALUES('a', 'b', 'c', 'd'); -- 1
|
||||
INSERT INTO t1 VALUES('d', 'a', 'b', 'c'); -- 2
|
||||
INSERT INTO t1 VALUES('c', 'd', 'a', 'b'); -- 3
|
||||
INSERT INTO t1 VALUES('b', 'c', 'd', 'a'); -- 4
|
||||
}
|
||||
do_faultsim_test 4.1 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1('{a b c} : (b:a AND c:b)'); }
|
||||
} -test {
|
||||
faultsim_test_result {0 2}
|
||||
}
|
||||
|
||||
do_faultsim_test 4.2 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1('{a b c} : (a AND d)') }
|
||||
} -test {
|
||||
faultsim_test_result {0 {2 3}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
87
ext/fts5/test/fts5faultD.test
Normal file
87
ext/fts5/test/fts5faultD.test
Normal file
@ -0,0 +1,87 @@
|
||||
# 2016 February 2
|
||||
#
|
||||
# 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 is focused on OOM errors.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultA
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
foreach_detail_mode $testprefix {
|
||||
if {"%DETAIL%"=="none"} continue
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%);
|
||||
INSERT INTO o1(o1, rank) VALUES('pgsz', 32);
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s;
|
||||
}
|
||||
|
||||
do_faultsim_test 1 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('a') }
|
||||
} -test {
|
||||
faultsim_test_result {0 180} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 2 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 3 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 4 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('b:b OR a:a') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 5 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('c:b') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
@ -40,4 +40,3 @@ do_test 1.1 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -90,4 +90,3 @@ do_catchsql_test 4.1 {
|
||||
} {1 {fts5: syntax error near "`"}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -121,7 +121,6 @@ foreach_detail_mode $testprefix {
|
||||
}
|
||||
|
||||
execsql { CREATE VIRTUAL TABLE t2 USING fts5(x, detail=%DETAIL%) }
|
||||
breakpoint
|
||||
execsql {
|
||||
INSERT INTO t2 VALUES($small || ' ' || $big);
|
||||
}
|
||||
@ -130,4 +129,3 @@ breakpoint
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -210,4 +210,3 @@ foreach {tn pgsz} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
72
ext/fts5/test/fts5lastrowid.test
Normal file
72
ext/fts5/test/fts5lastrowid.test
Normal file
@ -0,0 +1,72 @@
|
||||
# 2017 Feb 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests of the last_insert_rowid functionality with fts5.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5lastrowid
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(str);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
SELECT last_insert_rowid();
|
||||
} {3}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {6}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO t1(rowid, str) VALUES(-22, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
} {-22}
|
||||
|
||||
do_execsql_test 1.4 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(rowid, str) VALUES(45, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(46, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(222, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {222 222}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
CREATE TABLE x1(x);
|
||||
INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo');
|
||||
INSERT INTO t1 SELECT x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {226}
|
||||
|
||||
do_execsql_test 1.6 {
|
||||
INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {14}
|
||||
|
||||
|
||||
finish_test
|
43
ext/fts5/test/fts5leftjoin.test
Normal file
43
ext/fts5/test/fts5leftjoin.test
Normal file
@ -0,0 +1,43 @@
|
||||
# 2014 June 17
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5leftjoin
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE vt USING fts5(x);
|
||||
INSERT INTO vt VALUES('abc');
|
||||
INSERT INTO vt VALUES('xyz');
|
||||
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES(1), (2);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT * FROM t1 LEFT JOIN (
|
||||
SELECT rowid AS rrr, * FROM vt WHERE vt MATCH 'abc'
|
||||
) ON t1.a = rrr
|
||||
} {1 1 abc 2 {} {}}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT * FROM t1 LEFT JOIN vt ON (vt MATCH 'abc')
|
||||
} {1 abc 2 abc}
|
||||
|
||||
finish_test
|
@ -472,7 +472,7 @@ do_execsql_test 12.1 {
|
||||
#
|
||||
reset_db
|
||||
proc xyz {} {}
|
||||
db func fts5 -argcount 0 xyz
|
||||
db func fts5 -argcount 1 xyz
|
||||
do_test 13.1 {
|
||||
list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
@ -492,4 +492,3 @@ do_catchsql_test 14.2 {
|
||||
} {1 {unrecognized matchinfo flag: d}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -241,4 +241,3 @@ do_execsql_test 6.3 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -55,4 +55,3 @@ do_execsql_test 1.2 {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -45,4 +45,3 @@ do_multiclient_test tn {
|
||||
};# do_multiclient_test
|
||||
};# foreach_detail_mode
|
||||
finish_test
|
||||
|
||||
|
@ -68,4 +68,3 @@ do_near_test 1.25 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 4) } 0
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -178,4 +178,3 @@ do_execsql_test 4.3.1 {
|
||||
do_test 4.2.2 { fts5_level_segs ttt } {3}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -106,4 +106,3 @@ foreach {tn nStep} {
|
||||
do_test 2.$tn.6 { fts5_segcount t1 } 1
|
||||
}
|
||||
finish_test
|
||||
|
||||
|
@ -116,4 +116,3 @@ do_execsql_test 2.0 {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -30,7 +30,7 @@ do_eqp_test 1.1 {
|
||||
SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
|
||||
} {
|
||||
0 0 0 {SCAN TABLE t1}
|
||||
0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 1:}
|
||||
0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
@ -43,7 +43,7 @@ do_eqp_test 1.2 {
|
||||
do_eqp_test 1.3 {
|
||||
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
|
||||
} {
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 1:}
|
||||
0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
|
||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||
}
|
||||
|
||||
@ -64,4 +64,3 @@ do_eqp_test 1.5 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -11803,4 +11803,3 @@ foreach {in out} $test_vocab {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -67,4 +67,3 @@ foreach {in out} $test_vocab {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file containst tests focused on prefix indexes.
|
||||
# This file contains tests focused on prefix indexes.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
@ -341,5 +341,3 @@ foreach {tn create} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -79,5 +79,3 @@ for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -90,6 +90,7 @@ do_test 2.7 {
|
||||
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
|
||||
} {1 3 2}
|
||||
|
||||
db2 close
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# At one point there was a problem with queries such as:
|
||||
@ -151,4 +152,3 @@ do_execsql_test 4.1 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -64,4 +64,3 @@ do_catchsql_test 2.2 {
|
||||
INSERT INTO nc(nc) VALUES('rebuild');
|
||||
} {1 {'rebuild' may not be used with a contentless fts5 table}}
|
||||
finish_test
|
||||
|
||||
|
@ -149,4 +149,3 @@ do_test 4.3 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -216,4 +216,3 @@ do_execsql_test 6.2 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -411,7 +411,6 @@ do_catchsql_test 19.2 {
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
breakpoint
|
||||
do_execsql_test 20.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
|
||||
|
@ -332,7 +332,41 @@ do_execsql_test 16.0 {
|
||||
DELETE FROM t2;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 17.0 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(x, y);
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
COMMIT;
|
||||
}
|
||||
do_execsql_test 17.1 { SELECT * FROM t2('y:a*') WHERE rowid BETWEEN 10 AND 20 }
|
||||
do_execsql_test 17.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
SELECT * FROM t2('y:a*') WHERE rowid BETWEEN 10 AND 20 ;
|
||||
}
|
||||
do_execsql_test 17.3 {
|
||||
COMMIT
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 17.4 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(x, y);
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb');
|
||||
SELECT * FROM t2('y:a*') WHERE rowid>66;
|
||||
}
|
||||
do_execsql_test 17.5 { SELECT * FROM t2('x:b* OR y:a*') }
|
||||
do_execsql_test 17.5 { COMMIT ; SELECT * FROM t2('x:b* OR y:a*') }
|
||||
do_execsql_test 17.6 {
|
||||
SELECT * FROM t2('x:b* OR y:a*') WHERE rowid>55
|
||||
}
|
||||
|
||||
#db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -116,4 +116,3 @@ do_execsql_test 4.6 {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -152,7 +152,7 @@ foreach {tn expr res} {
|
||||
1 {abc} {"abc"}
|
||||
2 {one} {"one"|"i"|"1"}
|
||||
3 {3} {"3"|"iii"|"three"}
|
||||
4 {3*} {"3"|"iii"|"three" *}
|
||||
4 {3*} {"3" *}
|
||||
} {
|
||||
do_execsql_test 4.1.$tn {
|
||||
SELECT fts5_expr($expr, 'tokenize=tclnum')
|
||||
@ -421,4 +421,3 @@ do_execsql_test 7.1.2 {
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -161,4 +161,3 @@ foreach {tn expr} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user