Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f0c6bc3a5 | |||
| bddcb53614 | |||
| fd971c8b83 | |||
| 332faddd99 | |||
| 7c4805fa5c | |||
| 852841cc14 | |||
| 528e4e4bbf | |||
| 335ce3575f | |||
| 4c454ff90b | |||
| 7ba5f0e768 | |||
| e278a9bacd | |||
| b585dbf8db | |||
| cfcd9d34b9 | |||
| 44bbccc05a | |||
| 0a1c5dc414 | |||
| 0ee56139e9 | |||
| af12f8e2c9 | |||
| aa90aad86b | |||
| b4b69facc0 | |||
| a12baadd15 | |||
| 11584e6779 | |||
| 6af090cc05 | |||
| e1e878687d | |||
| e83dba9e4d | |||
| 26a8ddbcdb | |||
| 087794b136 | |||
| ad9b696471 | |||
| f42e5d8917 | |||
| 411c20ad62 | |||
| 6b0cfe5343 | |||
| 6f3283a427 | |||
| bab38cbc9a | |||
| 538ed8e376 | |||
| b4c4601adf | |||
| 60dd40a62c | |||
| 2ac63b9812 | |||
| bf431367f3 | |||
| 730859568d | |||
| c9bcad12ea | |||
| e376cac1d1 | |||
| b7bcf5c16c | |||
| 31349393ba | |||
| 8df9974169 | |||
| f427296520 | |||
| 920a129de3 | |||
| 34d02325be | |||
| aa189cf00f | |||
| 2dab053e22 | |||
| 0561247d07 | |||
| 1381bbc262 |
@@ -1,6 +0,0 @@
|
||||
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.
|
||||
+64
-226
@@ -22,7 +22,7 @@ TOP = @abs_srcdir@
|
||||
#
|
||||
BCC = @BUILD_CC@ @BUILD_CFLAGS@
|
||||
|
||||
# TCC is the C Compile and options for use in building executables that
|
||||
# TCC is the C Compile and options for use in building executables that
|
||||
# will run on the target platform. (BCC and TCC are usually the
|
||||
# same unless your are cross-compiling.) Separate CC and CFLAGS macros
|
||||
# are provide so that these aspects of the build process can be changed
|
||||
@@ -32,11 +32,10 @@ CC = @CC@
|
||||
CFLAGS = @CPPFLAGS@ @CFLAGS@
|
||||
TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu
|
||||
TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
|
||||
TCC += -I${TOP}/ext/userauth
|
||||
|
||||
# Define this for the autoconf-based build, so that the code knows it can
|
||||
# include the generated sqlite_cfg.h
|
||||
#
|
||||
# include the generated config.h
|
||||
#
|
||||
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
|
||||
|
||||
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
|
||||
@@ -67,7 +66,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
|
||||
TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
|
||||
# Any target libraries which libsqlite must be linked against
|
||||
#
|
||||
#
|
||||
TLIBS = @LIBS@ $(LIBS)
|
||||
|
||||
# Flags controlling use of the in memory btree implementation
|
||||
@@ -79,8 +78,8 @@ TLIBS = @LIBS@ $(LIBS)
|
||||
TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
|
||||
|
||||
# Enable/disable loadable extensions, and other optional features
|
||||
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||
# The same set of OMIT and ENABLE flags should be passed to the
|
||||
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||
# The same set of OMIT and ENABLE flags should be passed to the
|
||||
# LEMON parser generator and the mkkeywordhash tool as well.
|
||||
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
|
||||
|
||||
@@ -127,8 +126,8 @@ SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
|
||||
# If gcov support was enabled by the configure script, add the appropriate
|
||||
# flags here. It's not always as easy as just having the user add the right
|
||||
# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
|
||||
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
|
||||
# Supposedly GCC does the right thing if you use --coverage, but in
|
||||
# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.
|
||||
# Supposedly GCC does the right thing if you use --coverage, but in
|
||||
# practice it still fails. See:
|
||||
#
|
||||
# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html
|
||||
@@ -165,7 +164,6 @@ LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
|
||||
###############################################################################
|
||||
|
||||
USE_AMALGAMATION = @USE_AMALGAMATION@
|
||||
AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@
|
||||
|
||||
# Object files for the SQLite library (non-amalgamation).
|
||||
#
|
||||
@@ -180,20 +178,19 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
|
||||
fts5.lo \
|
||||
func.lo global.lo hash.lo \
|
||||
icu.lo insert.lo json.lo legacy.lo loadext.lo \
|
||||
icu.lo insert.lo json1.lo legacy.lo loadext.lo \
|
||||
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
|
||||
memdb.lo memjournal.lo \
|
||||
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
|
||||
notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \
|
||||
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
|
||||
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
|
||||
random.lo resolve.lo rowset.lo rtree.lo \
|
||||
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
|
||||
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
|
||||
update.lo userauth.lo upsert.lo util.lo vacuum.lo \
|
||||
update.lo util.lo vacuum.lo \
|
||||
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
|
||||
vdbetrace.lo vdbevtab.lo \
|
||||
wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
||||
window.lo utf.lo vtab.lo
|
||||
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
||||
utf.lo vtab.lo
|
||||
|
||||
# Object files for the amalgamation.
|
||||
#
|
||||
@@ -234,7 +231,6 @@ SRC = \
|
||||
$(TOP)/src/hash.h \
|
||||
$(TOP)/src/hwtime.h \
|
||||
$(TOP)/src/insert.c \
|
||||
$(TOP)/src/json.c \
|
||||
$(TOP)/src/legacy.c \
|
||||
$(TOP)/src/loadext.c \
|
||||
$(TOP)/src/main.c \
|
||||
@@ -257,7 +253,6 @@ SRC = \
|
||||
$(TOP)/src/os.h \
|
||||
$(TOP)/src/os_common.h \
|
||||
$(TOP)/src/os_setup.h \
|
||||
$(TOP)/src/os_kv.c \
|
||||
$(TOP)/src/os_unix.c \
|
||||
$(TOP)/src/os_win.c \
|
||||
$(TOP)/src/os_win.h \
|
||||
@@ -289,7 +284,6 @@ SRC = \
|
||||
$(TOP)/src/trigger.c \
|
||||
$(TOP)/src/utf.c \
|
||||
$(TOP)/src/update.c \
|
||||
$(TOP)/src/upsert.c \
|
||||
$(TOP)/src/util.c \
|
||||
$(TOP)/src/vacuum.c \
|
||||
$(TOP)/src/vdbe.c \
|
||||
@@ -300,7 +294,6 @@ SRC = \
|
||||
$(TOP)/src/vdbemem.c \
|
||||
$(TOP)/src/vdbesort.c \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbevtab.c \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vtab.c \
|
||||
$(TOP)/src/vxworks.h \
|
||||
@@ -310,8 +303,7 @@ SRC = \
|
||||
$(TOP)/src/where.c \
|
||||
$(TOP)/src/wherecode.c \
|
||||
$(TOP)/src/whereexpr.c \
|
||||
$(TOP)/src/whereInt.h \
|
||||
$(TOP)/src/window.c
|
||||
$(TOP)/src/whereInt.h
|
||||
|
||||
# Source code for extensions
|
||||
#
|
||||
@@ -356,18 +348,15 @@ SRC += \
|
||||
$(TOP)/ext/icu/icu.c
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
SRC += \
|
||||
$(TOP)/ext/userauth/userauth.c \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
SRC += \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.h \
|
||||
$(TOP)/ext/rbu/sqlite3rbu.c
|
||||
SRC += \
|
||||
$(TOP)/ext/misc/json1.c \
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
|
||||
# Generated source code files
|
||||
@@ -378,7 +367,7 @@ SRC += \
|
||||
opcodes.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
sqlite_cfg.h \
|
||||
config.h \
|
||||
shell.c \
|
||||
sqlite3.h
|
||||
|
||||
@@ -426,17 +415,12 @@ TESTSRC = \
|
||||
$(TOP)/src/test_tclsh.c \
|
||||
$(TOP)/src/test_tclvar.c \
|
||||
$(TOP)/src/test_thread.c \
|
||||
$(TOP)/src/test_vdbecov.c \
|
||||
$(TOP)/src/test_vfs.c \
|
||||
$(TOP)/src/test_windirent.c \
|
||||
$(TOP)/src/test_window.c \
|
||||
$(TOP)/src/test_wsd.c \
|
||||
$(TOP)/ext/fts3/fts3_term.c \
|
||||
$(TOP)/ext/fts3/fts3_test.c \
|
||||
$(TOP)/ext/session/test_session.c \
|
||||
$(TOP)/ext/recover/sqlite3recover.c \
|
||||
$(TOP)/ext/recover/dbdata.c \
|
||||
$(TOP)/ext/recover/test_recover.c \
|
||||
$(TOP)/ext/rbu/test_rbu.c
|
||||
|
||||
# Statically linked extensions
|
||||
@@ -445,15 +429,10 @@ TESTSRC += \
|
||||
$(TOP)/ext/expert/sqlite3expert.c \
|
||||
$(TOP)/ext/expert/test_expert.c \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/appendvfs.c \
|
||||
$(TOP)/ext/misc/basexx.c \
|
||||
$(TOP)/ext/misc/carray.c \
|
||||
$(TOP)/ext/misc/cksumvfs.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/csv.c \
|
||||
$(TOP)/ext/misc/decimal.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
$(TOP)/ext/misc/explain.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/fuzzer.c \
|
||||
$(TOP)/ext/fts5/fts5_tcl.c \
|
||||
@@ -464,8 +443,6 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/nextchar.c \
|
||||
$(TOP)/ext/misc/normalize.c \
|
||||
$(TOP)/ext/misc/percentile.c \
|
||||
$(TOP)/ext/misc/prefixes.c \
|
||||
$(TOP)/ext/misc/qpvtab.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
$(TOP)/ext/misc/remember.c \
|
||||
$(TOP)/ext/misc/series.c \
|
||||
@@ -473,9 +450,7 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/totype.c \
|
||||
$(TOP)/ext/misc/unionvtab.c \
|
||||
$(TOP)/ext/misc/wholenumber.c \
|
||||
$(TOP)/ext/misc/zipfile.c \
|
||||
$(TOP)/ext/userauth/userauth.c \
|
||||
$(TOP)/ext/rtree/test_rtreedoc.c
|
||||
$(TOP)/ext/misc/zipfile.c
|
||||
|
||||
# Source code to the library files needed by the test fixture
|
||||
#
|
||||
@@ -491,13 +466,11 @@ TESTSRC2 = \
|
||||
$(TOP)/src/dbstat.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/global.c \
|
||||
$(TOP)/src/insert.c \
|
||||
$(TOP)/src/wal.c \
|
||||
$(TOP)/src/main.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/os.c \
|
||||
$(TOP)/src/os_kv.c \
|
||||
$(TOP)/src/os_unix.c \
|
||||
$(TOP)/src/os_win.c \
|
||||
$(TOP)/src/pager.c \
|
||||
@@ -509,7 +482,6 @@ TESTSRC2 = \
|
||||
$(TOP)/src/pcache1.c \
|
||||
$(TOP)/src/select.c \
|
||||
$(TOP)/src/tokenize.c \
|
||||
$(TOP)/src/treeview.c \
|
||||
$(TOP)/src/utf.c \
|
||||
$(TOP)/src/util.c \
|
||||
$(TOP)/src/vdbeapi.c \
|
||||
@@ -517,11 +489,9 @@ TESTSRC2 = \
|
||||
$(TOP)/src/vdbe.c \
|
||||
$(TOP)/src/vdbemem.c \
|
||||
$(TOP)/src/vdbetrace.c \
|
||||
$(TOP)/src/vdbevtab.c \
|
||||
$(TOP)/src/where.c \
|
||||
$(TOP)/src/wherecode.c \
|
||||
$(TOP)/src/whereexpr.c \
|
||||
$(TOP)/src/window.c \
|
||||
parse.c \
|
||||
$(TOP)/ext/fts3/fts3.c \
|
||||
$(TOP)/ext/fts3/fts3_aux.c \
|
||||
@@ -531,8 +501,7 @@ TESTSRC2 = \
|
||||
$(TOP)/ext/fts3/fts3_write.c \
|
||||
$(TOP)/ext/async/sqlite3async.c \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/misc/stmt.c \
|
||||
fts5.c
|
||||
$(TOP)/ext/misc/stmt.c
|
||||
|
||||
# Header files used by all library source files.
|
||||
#
|
||||
@@ -561,7 +530,7 @@ HDR = \
|
||||
$(TOP)/src/vdbeInt.h \
|
||||
$(TOP)/src/vxworks.h \
|
||||
$(TOP)/src/whereInt.h \
|
||||
sqlite_cfg.h
|
||||
config.h
|
||||
|
||||
# Header files used by extensions
|
||||
#
|
||||
@@ -579,14 +548,11 @@ EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/geopoly.c
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
|
||||
# executables needed for testing
|
||||
#
|
||||
@@ -605,10 +571,7 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata2.db \
|
||||
$(TOP)/test/fuzzdata3.db \
|
||||
$(TOP)/test/fuzzdata4.db \
|
||||
$(TOP)/test/fuzzdata5.db \
|
||||
$(TOP)/test/fuzzdata6.db \
|
||||
$(TOP)/test/fuzzdata7.db \
|
||||
$(TOP)/test/fuzzdata8.db
|
||||
$(TOP)/test/fuzzdata5.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
@@ -616,7 +579,7 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
SHELL_OPT = -DSQLITE_ENABLE_FTS4
|
||||
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
|
||||
#SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_RTREE
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
@@ -624,30 +587,14 @@ SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
FUZZERSHELL_OPT =
|
||||
FUZZCHECK_OPT += -I$(TOP)/test
|
||||
FUZZCHECK_OPT += -I$(TOP)/ext/recover
|
||||
FUZZCHECK_OPT += -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c
|
||||
FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c
|
||||
FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
|
||||
FUZZCHECK_SRC += $(TOP)/test/vt02.c
|
||||
DBFUZZ_OPT =
|
||||
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
|
||||
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.
|
||||
@@ -696,7 +643,7 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
|
||||
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
|
||||
|
||||
fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP)
|
||||
fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
|
||||
|
||||
ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
|
||||
@@ -704,42 +651,11 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.
|
||||
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
|
||||
$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
|
||||
|
||||
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
DBFUZZ2_OPTS = \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_DEBUG \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB \
|
||||
-DSQLITE_ENABLE_BYTECODE_VTAB \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_FTS4 \
|
||||
-DSQLITE_ENABLE_FTS5
|
||||
|
||||
dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
|
||||
$(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
|
||||
-DSTANDALONE -o dbfuzz2 \
|
||||
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
|
||||
mkdir -p dbfuzz2-dir
|
||||
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
|
||||
|
||||
dbfuzz2-asan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
|
||||
clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
|
||||
-fsanitize=fuzzer,undefined,address -o dbfuzz2-asan \
|
||||
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
|
||||
mkdir -p dbfuzz2-dir
|
||||
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
|
||||
|
||||
dbfuzz2-msan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
|
||||
clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
|
||||
-fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan \
|
||||
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
|
||||
mkdir -p dbfuzz2-dir
|
||||
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
|
||||
|
||||
mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
@@ -775,19 +691,10 @@ mptest: mptester$(TEXE)
|
||||
touch .target_source
|
||||
|
||||
sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS)
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
|
||||
cp tsrc/sqlite3ext.h .
|
||||
cp $(TOP)/ext/session/sqlite3session.h .
|
||||
|
||||
sqlite3r.h: sqlite3.h
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h
|
||||
|
||||
sqlite3r.c: sqlite3.c sqlite3r.h
|
||||
cp $(TOP)/ext/recover/sqlite3recover.c tsrc/
|
||||
cp $(TOP)/ext/recover/sqlite3recover.h tsrc/
|
||||
cp $(TOP)/ext/recover/dbdata.c tsrc/
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS)
|
||||
|
||||
sqlite3ext.h: .target_source
|
||||
cp tsrc/sqlite3ext.h .
|
||||
|
||||
@@ -899,9 +806,6 @@ hash.lo: $(TOP)/src/hash.c $(HDR)
|
||||
insert.lo: $(TOP)/src/insert.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c
|
||||
|
||||
json.lo: $(TOP)/src/json.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c
|
||||
|
||||
legacy.lo: $(TOP)/src/legacy.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c
|
||||
|
||||
@@ -962,9 +866,6 @@ pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h
|
||||
os.lo: $(TOP)/src/os.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c
|
||||
|
||||
os_kv.lo: $(TOP)/src/os_kv.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c
|
||||
|
||||
os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c
|
||||
|
||||
@@ -1013,9 +914,6 @@ trigger.lo: $(TOP)/src/trigger.c $(HDR)
|
||||
update.lo: $(TOP)/src/update.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c
|
||||
|
||||
upsert.lo: $(TOP)/src/upsert.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c
|
||||
|
||||
utf.lo: $(TOP)/src/utf.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c
|
||||
|
||||
@@ -1046,9 +944,6 @@ vdbesort.lo: $(TOP)/src/vdbesort.c $(HDR)
|
||||
vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c
|
||||
|
||||
vdbevtab.lo: $(TOP)/src/vdbevtab.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c
|
||||
|
||||
vtab.lo: $(TOP)/src/vtab.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c
|
||||
|
||||
@@ -1067,9 +962,6 @@ wherecode.lo: $(TOP)/src/wherecode.c $(HDR)
|
||||
whereexpr.lo: $(TOP)/src/whereexpr.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c
|
||||
|
||||
window.lo: $(TOP)/src/window.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c
|
||||
|
||||
tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
||||
$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
|
||||
|
||||
@@ -1095,19 +987,16 @@ opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)/src/parse.y lemon$(BEXE)
|
||||
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
|
||||
cp $(TOP)/src/parse.y .
|
||||
./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y
|
||||
rm -f parse.h
|
||||
./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
|
||||
mv parse.h parse.h.temp
|
||||
$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
|
||||
|
||||
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION
|
||||
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
|
||||
|
||||
sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION
|
||||
echo '#ifndef SQLITE_RESOURCE_VERSION' >$@
|
||||
echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@
|
||||
cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@
|
||||
echo '#endif' >>sqlite3rc.h
|
||||
|
||||
keywordhash.h: $(TOP)/tool/mkkeywordhash.c
|
||||
$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
|
||||
./mkkeywordhash$(BEXE) >keywordhash.h
|
||||
@@ -1116,22 +1005,13 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
|
||||
SHELL_SRC = \
|
||||
$(TOP)/src/shell.c.in \
|
||||
$(TOP)/ext/misc/appendvfs.c \
|
||||
$(TOP)/ext/misc/completion.c \
|
||||
$(TOP)/ext/misc/decimal.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
$(TOP)/ext/misc/series.c \
|
||||
$(TOP)/ext/misc/shathree.c \
|
||||
$(TOP)/ext/misc/fileio.c \
|
||||
$(TOP)/ext/misc/completion.c \
|
||||
$(TOP)/ext/misc/sqlar.c \
|
||||
$(TOP)/ext/misc/uint.c \
|
||||
$(TOP)/ext/expert/sqlite3expert.c \
|
||||
$(TOP)/ext/expert/sqlite3expert.h \
|
||||
$(TOP)/ext/misc/zipfile.c \
|
||||
$(TOP)/ext/misc/memtrace.c \
|
||||
$(TOP)/ext/recover/dbdata.c \
|
||||
$(TOP)/ext/recover/sqlite3recover.c \
|
||||
$(TOP)/ext/recover/sqlite3recover.h \
|
||||
$(TOP)/src/test_windirent.c
|
||||
|
||||
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
|
||||
@@ -1205,12 +1085,12 @@ fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
|
||||
rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
|
||||
|
||||
userauth.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c
|
||||
|
||||
sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c
|
||||
|
||||
json1.lo: $(TOP)/ext/misc/json1.c
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
|
||||
|
||||
stmt.lo: $(TOP)/ext/misc/stmt.c
|
||||
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c
|
||||
|
||||
@@ -1233,10 +1113,10 @@ FTS5_SRC = \
|
||||
$(TOP)/ext/fts5/fts5_varint.c \
|
||||
$(TOP)/ext/fts5/fts5_vocab.c \
|
||||
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE)
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
cp $(TOP)/ext/fts5/fts5parse.y .
|
||||
rm -f fts5parse.h
|
||||
./lemon$(BEXE) $(OPTS) -S fts5parse.y
|
||||
./lemon$(BEXE) $(OPTS) fts5parse.y
|
||||
|
||||
fts5parse.h: fts5parse.c
|
||||
|
||||
@@ -1260,14 +1140,12 @@ sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
|
||||
#
|
||||
TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||
TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
||||
TESTFIXTURE_SRC1 = sqlite3.c
|
||||
@@ -1278,15 +1156,8 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
|
||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||
|
||||
coretestprogs: $(TESTPROGS)
|
||||
|
||||
testprogs: coretestprogs srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
fulltest: alltest fuzztest
|
||||
|
||||
# Run most or all tcl test cases
|
||||
alltest: $(TESTPROGS)
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS)
|
||||
|
||||
# Really really long testing
|
||||
@@ -1302,8 +1173,12 @@ fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuz
|
||||
./fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
|
||||
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
@@ -1311,12 +1186,6 @@ valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessio
|
||||
tcltest: ./testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
|
||||
|
||||
# Runs all the same tests cases as the "tcltest" target but uses
|
||||
# the testrunner.tcl script to run them in multiple cores
|
||||
# concurrently.
|
||||
testrunner: testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes
|
||||
#
|
||||
quicktest: ./testfixture$(TEXE)
|
||||
@@ -1325,7 +1194,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: fuzztest sourcetest $(TESTPROGS) tcltest
|
||||
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.
|
||||
@@ -1340,16 +1209,13 @@ valgrindtest: $(TESTPROGS) valgrindfuzz
|
||||
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
|
||||
|
||||
shelltest: $(TESTPROGS)
|
||||
./testfixture$(TEXT) $(TOP)/test/permutations.test shell
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
|
||||
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
|
||||
|
||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
||||
|
||||
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
|
||||
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in
|
||||
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
|
||||
|
||||
sqltclsh$(TEXE): sqltclsh.c
|
||||
@@ -1378,9 +1244,6 @@ dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
|
||||
$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
|
||||
$(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
|
||||
|
||||
dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c
|
||||
$(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c
|
||||
|
||||
showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
|
||||
|
||||
@@ -1396,39 +1259,27 @@ showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo
|
||||
showshm$(TEXE): $(TOP)/tool/showshm.c
|
||||
$(LTLINK) -o $@ $(TOP)/tool/showshm.c
|
||||
|
||||
index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo
|
||||
$(LTLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS)
|
||||
|
||||
changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS)
|
||||
|
||||
changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS)
|
||||
|
||||
rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS)
|
||||
|
||||
atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS)
|
||||
|
||||
LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h
|
||||
$(LTLINK) -I. -o $@ $(TOP)/tool/logest.c
|
||||
|
||||
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)
|
||||
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c
|
||||
$(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS)
|
||||
|
||||
startup$(TEXE): $(TOP)/test/startup.c sqlite3.c
|
||||
$(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.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
|
||||
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)
|
||||
|
||||
loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
||||
@@ -1439,25 +1290,24 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
||||
# releasetest.tcl script.
|
||||
#
|
||||
VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
|
||||
checksymbols: sqlite3.o
|
||||
nm -g --defined-only sqlite3.o
|
||||
nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||
checksymbols: sqlite3.lo
|
||||
nm -g --defined-only sqlite3.lo | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||
echo '0 errors out of 1 tests'
|
||||
|
||||
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
|
||||
# a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz.
|
||||
# The snapshot-tarball target builds a tarball named by the SHA1 hash
|
||||
#
|
||||
amalgamation-tarball: sqlite3.c sqlite3rc.h
|
||||
amalgamation-tarball: sqlite3.c
|
||||
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal
|
||||
|
||||
snapshot-tarball: sqlite3.c sqlite3rc.h
|
||||
snapshot-tarball: sqlite3.c
|
||||
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot
|
||||
|
||||
# The next two rules are used to support the "threadtest" target. Building
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
# target is invoked by the releasetest.tcl script.
|
||||
#
|
||||
#
|
||||
THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
|
||||
$(TOP)/test/tt3_checkpoint.c \
|
||||
$(TOP)/test/tt3_index.c \
|
||||
@@ -1471,10 +1321,7 @@ threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
|
||||
threadtest: threadtest3$(TEXE)
|
||||
./threadtest3$(TEXE)
|
||||
|
||||
threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
|
||||
$(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS)
|
||||
|
||||
releasetest:
|
||||
releasetest:
|
||||
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
|
||||
|
||||
# Standard install and cleanup targets
|
||||
@@ -1482,7 +1329,7 @@ releasetest:
|
||||
lib_install: libsqlite3.la
|
||||
$(INSTALL) -d $(DESTDIR)$(libdir)
|
||||
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
||||
|
||||
|
||||
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
|
||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
||||
@@ -1493,20 +1340,19 @@ install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal
|
||||
$(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
pkgIndex.tcl:
|
||||
echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@
|
||||
echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3$(SHLIB_SUFFIX) sqlite3]' > $@
|
||||
tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
|
||||
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
|
||||
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
|
||||
|
||||
clean:
|
||||
clean:
|
||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
||||
rm -f sqlite3.h opcodes.*
|
||||
rm -rf .libs .deps
|
||||
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
|
||||
rm -f mkkeywordhash$(BEXE) keywordhash.h
|
||||
rm -f mksourceid$(BEXE)
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf tsrc .target_source
|
||||
rm -f tclsqlite3$(TEXE)
|
||||
@@ -1528,11 +1374,9 @@ clean:
|
||||
rm -f sqldiff sqldiff.exe
|
||||
rm -f dbhash dbhash.exe
|
||||
rm -f fts5.* fts5parse.*
|
||||
rm -f threadtest5
|
||||
|
||||
distclean: clean
|
||||
rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \
|
||||
$(TESTPROGS)
|
||||
rm -f config.h config.log config.status libtool Makefile sqlite3.pc
|
||||
|
||||
#
|
||||
# Windows section
|
||||
@@ -1551,9 +1395,3 @@ sqlite3.def: $(REAL_LIBOBJ)
|
||||
sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def
|
||||
$(TCC) -shared -o $@ sqlite3.def \
|
||||
-Wl,"--strip-all" $(REAL_LIBOBJ)
|
||||
|
||||
#
|
||||
# Fiddle app
|
||||
#
|
||||
fiddle: sqlite3.c shell.c
|
||||
make -C ext/wasm fiddle emcc_opt=-Os
|
||||
|
||||
+17
-9
@@ -19,7 +19,7 @@ TOP = ../sqlite
|
||||
#### C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = gcc -g -O0
|
||||
BCC = gcc -g -O2
|
||||
#BCC = /opt/ancic/bin/c89 -0
|
||||
|
||||
#### If the target operating system supports the "usleep()" system
|
||||
@@ -38,8 +38,8 @@ THREADSAFE = -DTHREADSAFE=0
|
||||
#### Specify any extra linker options needed to make the library
|
||||
# thread safe
|
||||
#
|
||||
THREADLIB = -lpthread -lm -ldl
|
||||
#THREADLIB =
|
||||
#THREADLIB = -lpthread
|
||||
THREADLIB =
|
||||
|
||||
#### Specify any extra libraries needed to access required functions.
|
||||
#
|
||||
@@ -54,9 +54,11 @@ TLIBS =
|
||||
# You can make the library go almost twice as fast if you compile
|
||||
# with -DNDEBUG=1
|
||||
#
|
||||
OPTS += -DSQLITE_DEBUG=1
|
||||
OPTS += -DSQLITE_ENABLE_WHERETRACE
|
||||
OPTS += -DSQLITE_ENABLE_SELECTTRACE
|
||||
#OPTS = -DSQLITE_DEBUG=2
|
||||
#OPTS = -DSQLITE_DEBUG=1
|
||||
#OPTS =
|
||||
OPTS = -DNDEBUG=1
|
||||
OPTS += -DHAVE_FDATASYNC=1
|
||||
|
||||
#### The suffix to add to executable files. ".exe" for windows.
|
||||
# Nothing for unix.
|
||||
@@ -68,7 +70,7 @@ EXE =
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
TCC = gcc -O0
|
||||
TCC = gcc -O6
|
||||
#TCC = gcc -g -O0 -Wall
|
||||
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
|
||||
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
|
||||
@@ -89,12 +91,18 @@ SHPREFIX = lib
|
||||
|
||||
#### Extra compiler options needed for programs that use the TCL library.
|
||||
#
|
||||
TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6
|
||||
#TCL_FLAGS =
|
||||
#TCL_FLAGS = -DSTATIC_BUILD=1
|
||||
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
|
||||
|
||||
#### Linker options needed to link against the TCL library.
|
||||
#
|
||||
#LIBTCL = -ltcl -lm -ldl
|
||||
LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz
|
||||
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
|
||||
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
|
||||
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
|
||||
|
||||
#### Additional objects for SQLite library when TCL support is enabled.
|
||||
#TCLOBJ =
|
||||
|
||||
+69
-268
@@ -73,7 +73,7 @@ API_ARMOR = 0
|
||||
!IFNDEF NO_WARN
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@@ -234,16 +234,6 @@ OSTRACE = 0
|
||||
DEBUG = 0
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# By default, use --linemacros=1 argument to the mksqlite3c.tcl tool, which
|
||||
# is used to build the amalgamation. This can be turned off to ease debug
|
||||
# of the amalgamation away from the source tree.
|
||||
#
|
||||
!IFNDEF NO_LINEMACROS
|
||||
NO_LINEMACROS = 0
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
|
||||
# Enable use of available compiler optimizations? Normally, this should be
|
||||
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
|
||||
# can be useful for testing.
|
||||
@@ -258,12 +248,6 @@ OPTIMIZATIONS = 2
|
||||
SESSION = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this to non-0 to enable support for the rbu extension.
|
||||
#
|
||||
!IFNDEF RBU
|
||||
RBU = 0
|
||||
!ENDIF
|
||||
|
||||
# Set the source code file to be used by executables and libraries when
|
||||
# they need the amalgamation.
|
||||
#
|
||||
@@ -336,13 +320,6 @@ SQLITETCLH = sqlite_tcl.h
|
||||
SQLITETCLDECLSH = sqlite_tclDecls.h
|
||||
!ENDIF
|
||||
|
||||
# This is the name to use for the dynamic link library (DLL) containing the
|
||||
# Tcl bindings for SQLite.
|
||||
#
|
||||
!IFNDEF SQLITE3TCLDLL
|
||||
SQLITE3TCLDLL = tclsqlite3.dll
|
||||
!ENDIF
|
||||
|
||||
# These are the additional targets that the targets that integrate with the
|
||||
# Tcl library should depend on when compiling, etc.
|
||||
#
|
||||
@@ -362,11 +339,6 @@ SQLITE_TCL_DEP =
|
||||
!IF $(MINIMAL_AMALGAMATION)==0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
!ENDIF
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
!ENDIF
|
||||
@@ -379,16 +351,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
|
||||
!ENDIF
|
||||
|
||||
# Always enable math functions on Windows
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS
|
||||
|
||||
# Should the rbu extension be enabled? If so, add compilation options
|
||||
# to enable it.
|
||||
#
|
||||
!IF $(RBU)!=0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1
|
||||
!ENDIF
|
||||
|
||||
# These are the "extended" SQLite compilation options used when compiling for
|
||||
# the Windows 10 platform.
|
||||
#
|
||||
@@ -526,9 +488,9 @@ UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
|
||||
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
|
||||
!ELSE
|
||||
BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
|
||||
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Check if assembly code listings should be generated for the source
|
||||
@@ -579,17 +541,17 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
|
||||
#
|
||||
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
|
||||
!IF "$(PLATFORM)"=="x86"
|
||||
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
# <<mark>>
|
||||
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
|
||||
TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
|
||||
# <</mark>>
|
||||
!ELSE
|
||||
!IFNDEF PLATFORM
|
||||
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
# <<mark>>
|
||||
TEST_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
|
||||
TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl
|
||||
# <</mark>>
|
||||
!ELSE
|
||||
CORE_CCONV_OPTS =
|
||||
@@ -658,10 +620,6 @@ SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
|
||||
!IFNDEF SHELL_CORE_SRC
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_CORE_SRC =
|
||||
# <<mark>>
|
||||
!ELSEIF $(USE_AMALGAMATION)==0
|
||||
SHELL_CORE_SRC =
|
||||
# <</mark>>
|
||||
!ELSE
|
||||
SHELL_CORE_SRC = $(SQLITE3C)
|
||||
!ENDIF
|
||||
@@ -672,10 +630,6 @@ SHELL_CORE_SRC = $(SQLITE3C)
|
||||
!IFNDEF SHELL_CORE_DEP
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_CORE_DEP = $(SQLITE3DLL)
|
||||
# <<mark>>
|
||||
!ELSEIF $(USE_AMALGAMATION)==0
|
||||
SHELL_CORE_DEP = libsqlite3.lib
|
||||
# <</mark>>
|
||||
!ELSE
|
||||
SHELL_CORE_DEP =
|
||||
!ENDIF
|
||||
@@ -695,10 +649,6 @@ TESTFIXTURE_DEP = zlib $(TESTFIXTURE_DEP)
|
||||
!IFNDEF SHELL_CORE_LIB
|
||||
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
|
||||
SHELL_CORE_LIB = $(SQLITE3LIB)
|
||||
# <<mark>>
|
||||
!ELSEIF $(USE_AMALGAMATION)==0
|
||||
SHELL_CORE_LIB = libsqlite3.lib
|
||||
# <</mark>>
|
||||
!ELSE
|
||||
SHELL_CORE_LIB =
|
||||
!ENDIF
|
||||
@@ -787,10 +737,10 @@ MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MKSQLITE3C_ARGS
|
||||
!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0
|
||||
MKSQLITE3C_ARGS = --linemacros=1
|
||||
!IF $(DEBUG)>1
|
||||
MKSQLITE3C_ARGS = --linemacros
|
||||
!ELSE
|
||||
MKSQLITE3C_ARGS = --linemacros=0
|
||||
MKSQLITE3C_ARGS =
|
||||
!ENDIF
|
||||
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
|
||||
MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall
|
||||
@@ -884,14 +834,6 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
|
||||
# prior to running nmake in order to match the actual installed location and
|
||||
# version on this machine.
|
||||
#
|
||||
!IFNDEF TCLVERSION
|
||||
TCLVERSION = 86
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLSUFFIX
|
||||
TCLSUFFIX =
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLDIR
|
||||
TCLDIR = $(TOP)\compat\tcl
|
||||
!ENDIF
|
||||
@@ -905,11 +847,11 @@ TCLLIBDIR = $(TCLDIR)\lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCL
|
||||
LIBTCL = tcl$(TCLVERSION)$(TCLSUFFIX).lib
|
||||
LIBTCL = tcl86.lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLSTUB
|
||||
LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib
|
||||
LIBTCLSTUB = tclstub86.lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLPATH
|
||||
@@ -1102,7 +1044,7 @@ RCC = $(RCC) -I$(ICUINCDIR)
|
||||
# Command line prefixes for compiling code, compiling resources,
|
||||
# linking, etc.
|
||||
#
|
||||
LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
|
||||
LTCOMPILE = $(TCC) -Fo$@
|
||||
LTRCOMPILE = $(RCC) -r
|
||||
LTLIB = lib.exe
|
||||
LTLINK = $(TCC) -Fe$@
|
||||
@@ -1120,11 +1062,6 @@ LTLIBS = $(LTLIBS) rpcrt4.lib
|
||||
!IFDEF PLATFORM
|
||||
LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||
LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||
!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
|
||||
"$(VISUALSTUDIOVERSION)"=="14.0" || \
|
||||
"$(VISUALSTUDIOVERSION)"=="15.0"
|
||||
LTLINKOPTS = /NOLOGO /MACHINE:x86
|
||||
LTLIBOPTS = /NOLOGO /MACHINE:x86
|
||||
!ELSE
|
||||
LTLINKOPTS = /NOLOGO
|
||||
LTLIBOPTS = /NOLOGO
|
||||
@@ -1247,20 +1184,19 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
||||
fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
|
||||
fts5.lo \
|
||||
func.lo global.lo hash.lo \
|
||||
icu.lo insert.lo json.lo legacy.lo loadext.lo \
|
||||
icu.lo insert.lo legacy.lo loadext.lo \
|
||||
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
|
||||
memdb.lo memjournal.lo \
|
||||
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
|
||||
notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \
|
||||
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
|
||||
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
|
||||
random.lo resolve.lo rowset.lo rtree.lo \
|
||||
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
|
||||
sqlite3session.lo select.lo sqlite3rbu.lo status.lo \
|
||||
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
|
||||
update.lo upsert.lo util.lo vacuum.lo \
|
||||
update.lo util.lo vacuum.lo \
|
||||
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
|
||||
vdbetrace.lo vdbevtab.lo wal.lo walker.lo where.lo wherecode.lo \
|
||||
whereexpr.lo \
|
||||
window.lo utf.lo vtab.lo
|
||||
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
|
||||
utf.lo vtab.lo
|
||||
# <</mark>>
|
||||
|
||||
# Object files for the amalgamation.
|
||||
@@ -1314,7 +1250,6 @@ SRC00 = \
|
||||
$(TOP)\src\global.c \
|
||||
$(TOP)\src\hash.c \
|
||||
$(TOP)\src\insert.c \
|
||||
$(TOP)\src\json.c \
|
||||
$(TOP)\src\legacy.c \
|
||||
$(TOP)\src\loadext.c \
|
||||
$(TOP)\src\main.c \
|
||||
@@ -1332,7 +1267,6 @@ SRC00 = \
|
||||
$(TOP)\src\mutex_w32.c \
|
||||
$(TOP)\src\notify.c \
|
||||
$(TOP)\src\os.c \
|
||||
$(TOP)\src\os_kv.c \
|
||||
$(TOP)\src\os_unix.c \
|
||||
$(TOP)\src\os_win.c
|
||||
|
||||
@@ -1358,7 +1292,6 @@ SRC01 = \
|
||||
$(TOP)\src\trigger.c \
|
||||
$(TOP)\src\utf.c \
|
||||
$(TOP)\src\update.c \
|
||||
$(TOP)\src\upsert.c \
|
||||
$(TOP)\src\util.c \
|
||||
$(TOP)\src\vacuum.c \
|
||||
$(TOP)\src\vdbe.c \
|
||||
@@ -1368,14 +1301,12 @@ SRC01 = \
|
||||
$(TOP)\src\vdbemem.c \
|
||||
$(TOP)\src\vdbesort.c \
|
||||
$(TOP)\src\vdbetrace.c \
|
||||
$(TOP)\src\vdbevtab.c \
|
||||
$(TOP)\src\vtab.c \
|
||||
$(TOP)\src\wal.c \
|
||||
$(TOP)\src\walker.c \
|
||||
$(TOP)\src\where.c \
|
||||
$(TOP)\src\wherecode.c \
|
||||
$(TOP)\src\whereexpr.c \
|
||||
$(TOP)\src\window.c
|
||||
$(TOP)\src\whereexpr.c
|
||||
|
||||
# Core miscellaneous files.
|
||||
#
|
||||
@@ -1446,6 +1377,7 @@ SRC07 = \
|
||||
$(TOP)\ext\rtree\rtree.c \
|
||||
$(TOP)\ext\session\sqlite3session.c \
|
||||
$(TOP)\ext\rbu\sqlite3rbu.c \
|
||||
$(TOP)\ext\misc\json1.c \
|
||||
$(TOP)\ext\misc\stmt.c
|
||||
|
||||
# Extension header files, part 1.
|
||||
@@ -1467,7 +1399,6 @@ SRC09 = \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.h \
|
||||
$(TOP)\ext\icu\sqliteicu.h \
|
||||
$(TOP)\ext\rtree\rtree.h \
|
||||
$(TOP)\ext\rtree\geopoly.c \
|
||||
$(TOP)\ext\rbu\sqlite3rbu.h \
|
||||
$(TOP)\ext\session\sqlite3session.h
|
||||
|
||||
@@ -1498,7 +1429,7 @@ SRC12 =
|
||||
|
||||
# All source code files.
|
||||
#
|
||||
SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) $(SRC12)
|
||||
SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11)
|
||||
|
||||
# Source code to the test files.
|
||||
#
|
||||
@@ -1544,15 +1475,13 @@ TESTSRC = \
|
||||
$(TOP)\src\test_tclsh.c \
|
||||
$(TOP)\src\test_tclvar.c \
|
||||
$(TOP)\src\test_thread.c \
|
||||
$(TOP)\src\test_vdbecov.c \
|
||||
$(TOP)\src\test_vfs.c \
|
||||
$(TOP)\src\test_windirent.c \
|
||||
$(TOP)\src\test_window.c \
|
||||
$(TOP)\src\test_wsd.c \
|
||||
$(TOP)\ext\fts3\fts3_term.c \
|
||||
$(TOP)\ext\fts3\fts3_test.c \
|
||||
$(TOP)\ext\rbu\test_rbu.c \
|
||||
$(TOP)\ext\session\test_session.c
|
||||
$(TOP)\ext\session\test_session.c
|
||||
|
||||
# Statically linked extensions.
|
||||
#
|
||||
@@ -1560,15 +1489,10 @@ TESTEXT = \
|
||||
$(TOP)\ext\expert\sqlite3expert.c \
|
||||
$(TOP)\ext\expert\test_expert.c \
|
||||
$(TOP)\ext\misc\amatch.c \
|
||||
$(TOP)\ext\misc\appendvfs.c \
|
||||
$(TOP)\ext\misc\basexx.c \
|
||||
$(TOP)\ext\misc\carray.c \
|
||||
$(TOP)\ext\misc\cksumvfs.c \
|
||||
$(TOP)\ext\misc\closure.c \
|
||||
$(TOP)\ext\misc\csv.c \
|
||||
$(TOP)\ext\misc\decimal.c \
|
||||
$(TOP)\ext\misc\eval.c \
|
||||
$(TOP)\ext\misc\explain.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\fuzzer.c \
|
||||
$(TOP)\ext\fts5\fts5_tcl.c \
|
||||
@@ -1579,20 +1503,13 @@ TESTEXT = \
|
||||
$(TOP)\ext\misc\nextchar.c \
|
||||
$(TOP)\ext\misc\normalize.c \
|
||||
$(TOP)\ext\misc\percentile.c \
|
||||
$(TOP)\ext\misc\prefixes.c \
|
||||
$(TOP)\ext\misc\qpvtab.c \
|
||||
$(TOP)\ext\misc\regexp.c \
|
||||
$(TOP)\ext\misc\remember.c \
|
||||
$(TOP)\ext\misc\series.c \
|
||||
$(TOP)\ext\misc\spellfix.c \
|
||||
$(TOP)\ext\misc\totype.c \
|
||||
$(TOP)\ext\misc\unionvtab.c \
|
||||
$(TOP)\ext\misc\wholenumber.c \
|
||||
$(TOP)\ext\rtree\test_rtreedoc.c \
|
||||
$(TOP)\ext\recover\sqlite3recover.c \
|
||||
$(TOP)\ext\recover\test_recover.c \
|
||||
$(TOP)\ext\recover\dbdata.c \
|
||||
fts5.c
|
||||
$(TOP)\ext\misc\wholenumber.c
|
||||
|
||||
# If use of zlib is enabled, add the "zipfile.c" source file.
|
||||
#
|
||||
@@ -1655,8 +1572,7 @@ EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\fts3\fts3_hash.h \
|
||||
$(TOP)\ext\fts3\fts3_tokenizer.h
|
||||
EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\rtree\rtree.h \
|
||||
$(TOP)\ext\rtree\geopoly.c
|
||||
$(TOP)\ext\rtree\rtree.h
|
||||
EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\icu\sqliteicu.h
|
||||
EXTHDR = $(EXTHDR) \
|
||||
@@ -1682,45 +1598,26 @@ FUZZDATA = \
|
||||
$(TOP)\test\fuzzdata2.db \
|
||||
$(TOP)\test\fuzzdata3.db \
|
||||
$(TOP)\test\fuzzdata4.db \
|
||||
$(TOP)\test\fuzzdata5.db \
|
||||
$(TOP)\test\fuzzdata6.db \
|
||||
$(TOP)\test\fuzzdata7.db \
|
||||
$(TOP)\test\fuzzdata8.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_ENABLE_FTS4=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
# Extra compiler options for various test tools.
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS =
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -I$(TOP)\test -I$(TOP)\ext\recover
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS5
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzcheck.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\ossfuzz.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
|
||||
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
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
|
||||
@@ -1733,7 +1630,7 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
# Extra targets for the "all" target that require Tcl.
|
||||
#
|
||||
!IF $(NO_TCL)==0
|
||||
ALL_TCL_TARGETS = $(SQLITE3TCLDLL)
|
||||
ALL_TCL_TARGETS = libtclsqlite3.lib
|
||||
!ELSE
|
||||
ALL_TCL_TARGETS =
|
||||
!ENDIF
|
||||
@@ -1765,22 +1662,7 @@ libsqlite3.lib: $(LIBOBJ)
|
||||
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
|
||||
|
||||
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
|
||||
$(LTLIB) $(LTLIBOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
||||
|
||||
tclsqlite3.def: tclsqlite.lo
|
||||
echo EXPORTS > tclsqlite3.def
|
||||
dumpbin /all tclsqlite.lo \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+/EXPORT:_?((?:Sqlite3|Tclsqlite3)_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> tclsqlite3.def
|
||||
|
||||
pkgIndex.tcl: $(TOP)\VERSION
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \
|
||||
)
|
||||
|
||||
$(SQLITE3TCLDLL): libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
|
||||
# <</mark>>
|
||||
|
||||
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
@@ -1790,7 +1672,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(?:session|changeset|changegroup|rebaser|rbu)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
# <</block2>>
|
||||
|
||||
@@ -1811,8 +1693,8 @@ scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
|
||||
srcck1.exe: $(TOP)\tool\srcck1.c
|
||||
$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c
|
||||
|
||||
sourcetest: srcck1.exe $(SQLITE3C)
|
||||
srcck1.exe $(SQLITE3C)
|
||||
sourcetest: srcck1.exe sqlite3.c
|
||||
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)
|
||||
@@ -1821,10 +1703,10 @@ 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_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
|
||||
@@ -1868,16 +1750,15 @@ mptest: mptester.exe
|
||||
for %i in ($(SRC11)) do copy /Y %i tsrc
|
||||
for %i in ($(SRC12)) do copy /Y %i tsrc
|
||||
copy /Y fts5.c tsrc
|
||||
copy /B tsrc\fts5.c +,,
|
||||
copy /Y fts5.h tsrc
|
||||
copy /B tsrc\fts5.h +,,
|
||||
del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
|
||||
$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
|
||||
move vdbe.new tsrc\vdbe.c
|
||||
echo > .target_source
|
||||
|
||||
sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL)
|
||||
sqlite3.c: .target_source sqlite3ext.h $(MKSQLITE3C_TOOL)
|
||||
$(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS)
|
||||
copy $(TOP)\ext\session\sqlite3session.h .
|
||||
|
||||
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
|
||||
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
|
||||
@@ -1892,8 +1773,7 @@ sqlite3.lo: $(SQLITE3C)
|
||||
# Rules to build the LEMON compiler generator
|
||||
#
|
||||
lempar.c: $(TOP)\tool\lempar.c
|
||||
copy /Y $(TOP)\tool\lempar.c .
|
||||
copy /B lempar.c +,,
|
||||
copy $(TOP)\tool\lempar.c .
|
||||
|
||||
lemon.exe: $(TOP)\tool\lemon.c lempar.c
|
||||
$(BCC) $(NO_WARN) -Daccess=_access \
|
||||
@@ -1922,7 +1802,7 @@ opcodes.lo: opcodes.c
|
||||
#
|
||||
!IF $(USE_RC)!=0
|
||||
# <<block1>>
|
||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) $(TOP)\VERSION
|
||||
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H)
|
||||
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo #define SQLITE_RESOURCE_VERSION %%V \
|
||||
@@ -2005,9 +1885,6 @@ hash.lo: $(TOP)\src\hash.c $(HDR)
|
||||
insert.lo: $(TOP)\src\insert.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\insert.c
|
||||
|
||||
json.lo: $(TOP)\src\json.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\json.c
|
||||
|
||||
legacy.lo: $(TOP)\src\legacy.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\legacy.c
|
||||
|
||||
@@ -2068,9 +1945,6 @@ pcache1.lo: $(TOP)\src\pcache1.c $(HDR) $(TOP)\src\pcache.h
|
||||
os.lo: $(TOP)\src\os.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os.c
|
||||
|
||||
os_kv.lo: $(TOP)\src\os_kv.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os_kv.c
|
||||
|
||||
os_unix.lo: $(TOP)\src\os_unix.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\os_unix.c
|
||||
|
||||
@@ -2119,9 +1993,6 @@ trigger.lo: $(TOP)\src\trigger.c $(HDR)
|
||||
update.lo: $(TOP)\src\update.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\update.c
|
||||
|
||||
upsert.lo: $(TOP)\src\upsert.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\upsert.c
|
||||
|
||||
utf.lo: $(TOP)\src\utf.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\utf.c
|
||||
|
||||
@@ -2152,9 +2023,6 @@ vdbesort.lo: $(TOP)\src\vdbesort.c $(HDR)
|
||||
vdbetrace.lo: $(TOP)\src\vdbetrace.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbetrace.c
|
||||
|
||||
vdbevtab.lo: $(TOP)\src\vdbevtab.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbevtab.c
|
||||
|
||||
vtab.lo: $(TOP)\src\vtab.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vtab.c
|
||||
|
||||
@@ -2173,9 +2041,6 @@ wherecode.lo: $(TOP)\src\wherecode.c $(HDR)
|
||||
whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c
|
||||
|
||||
window.lo: $(TOP)\src\window.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c
|
||||
|
||||
tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
|
||||
$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
||||
|
||||
@@ -2197,11 +2062,12 @@ opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
|
||||
#
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)\src\parse.y lemon.exe
|
||||
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
|
||||
del /Q parse.y parse.h parse.h.temp 2>NUL
|
||||
copy /Y $(TOP)\src\parse.y .
|
||||
copy /B parse.y +,,
|
||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y
|
||||
copy $(TOP)\src\parse.y .
|
||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
|
||||
move parse.h parse.h.temp
|
||||
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
|
||||
|
||||
$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION
|
||||
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS)
|
||||
@@ -2213,13 +2079,8 @@ sqlite3ext.h: .target_source
|
||||
copy /Y sqlite3ext.h tsrc\sqlite3ext.h
|
||||
!ELSE
|
||||
copy /Y tsrc\sqlite3ext.h sqlite3ext.h
|
||||
copy /B sqlite3ext.h +,,
|
||||
!ENDIF
|
||||
|
||||
sqlite3session.h: $(TOP)\ext\session\sqlite3session.h
|
||||
copy /Y $(TOP)\ext\session\sqlite3session.h .
|
||||
copy /B sqlite3session.h +,,
|
||||
|
||||
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
|
||||
$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
|
||||
$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
|
||||
@@ -2231,20 +2092,11 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
||||
SHELL_SRC = \
|
||||
$(TOP)\src\shell.c.in \
|
||||
$(TOP)\ext\misc\appendvfs.c \
|
||||
$(TOP)\ext\misc\completion.c \
|
||||
$(TOP)\ext\misc\decimal.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\ieee754.c \
|
||||
$(TOP)\ext\misc\regexp.c \
|
||||
$(TOP)\ext\misc\series.c \
|
||||
$(TOP)\ext\misc\shathree.c \
|
||||
$(TOP)\ext\misc\uint.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\completion.c \
|
||||
$(TOP)\ext\expert\sqlite3expert.c \
|
||||
$(TOP)\ext\expert\sqlite3expert.h \
|
||||
$(TOP)\ext\misc\memtrace.c \
|
||||
$(TOP)/ext/recover/dbdata.c \
|
||||
$(TOP)/ext/recover/sqlite3recover.c \
|
||||
$(TOP)/ext/recover/sqlite3recover.h \
|
||||
$(TOP)\src\test_windirent.c
|
||||
|
||||
# If use of zlib is enabled, add the "zipfile.c" source file.
|
||||
@@ -2322,9 +2174,6 @@ fts3_unicode2.lo: $(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
|
||||
fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c
|
||||
|
||||
stmt.lo: $(TOP)\ext\misc\stmt.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\stmt.c
|
||||
|
||||
rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
|
||||
|
||||
@@ -2369,22 +2218,19 @@ LSM1_SRC = \
|
||||
$(TOP)\ext\lsm1\lsm_win32.c
|
||||
|
||||
fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe
|
||||
copy /Y $(TOP)\ext\fts5\fts5parse.y .
|
||||
copy /B fts5parse.y +,,
|
||||
copy $(TOP)\ext\fts5\fts5parse.y .
|
||||
del /Q fts5parse.h 2>NUL
|
||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S fts5parse.y
|
||||
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
|
||||
|
||||
fts5parse.h: fts5parse.c
|
||||
|
||||
fts5.c: $(FTS5_SRC)
|
||||
$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
|
||||
copy /Y $(TOP)\ext\fts5\fts5.h .
|
||||
copy /B fts5.h +,,
|
||||
copy $(TOP)\ext\fts5\fts5.h .
|
||||
|
||||
lsm1.c: $(LSM1_SRC)
|
||||
$(TCLSH_CMD) $(TOP)\ext\lsm1\tool\mklsm1c.tcl
|
||||
copy /Y $(TOP)\ext\lsm1\lsm.h .
|
||||
copy /B lsm.h +,,
|
||||
copy $(TOP)\ext\lsm1\lsm.h .
|
||||
|
||||
fts5.lo: fts5.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c
|
||||
@@ -2410,10 +2256,9 @@ 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=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
|
||||
@@ -2454,13 +2299,7 @@ extensiontest: testfixture.exe testloadext.dll
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
|
||||
|
||||
coretestprogs: $(TESTPROGS)
|
||||
|
||||
testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe
|
||||
|
||||
fulltest: alltest fuzztest
|
||||
|
||||
alltest: $(TESTPROGS)
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
|
||||
|
||||
@@ -2479,6 +2318,9 @@ queryplantest: testfixture.exe shell
|
||||
fuzztest: fuzzcheck.exe
|
||||
.\fuzzcheck.exe $(FUZZDATA)
|
||||
|
||||
fastfuzztest: fuzzcheck.exe
|
||||
.\fuzzcheck.exe --limit-mem 100M $(FUZZDATA)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes (on a fast machine)
|
||||
#
|
||||
quicktest: testfixture.exe sourcetest
|
||||
@@ -2488,27 +2330,14 @@ quicktest: testfixture.exe sourcetest
|
||||
# This is the common case. Run many tests that do not take too long,
|
||||
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
|
||||
#
|
||||
test: $(TESTPROGS) sourcetest fuzztest tcltest
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
#
|
||||
tcltest: testfixture.exe
|
||||
test: $(TESTPROGS) sourcetest fastfuzztest
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
|
||||
|
||||
# Runs all the same tests cases as the "tcltest" target but uses
|
||||
# the testrunner.tcl script to run them in multiple cores
|
||||
# concurrently.
|
||||
testrunner: testfixture.exe
|
||||
.\testfixture.exe $(TOP)\test\testrunner.tcl
|
||||
|
||||
smoketest: $(TESTPROGS)
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
||||
|
||||
shelltest: $(TESTPROGS)
|
||||
.\testfixture.exe $(TOP)\test\permutations.test shell
|
||||
|
||||
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
|
||||
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
|
||||
|
||||
@@ -2553,9 +2382,6 @@ testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H)
|
||||
testloadext.dll: testloadext.lo
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
|
||||
|
||||
dbtotxt.exe: $(TOP)\tool\dbtotxt.c
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbtotxt.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
@@ -2575,20 +2401,11 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
|
||||
showshm.exe: $(TOP)\tool\showshm.c
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
index_usage.exe: $(TOP)\tool\index_usage.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\index_usage.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
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)
|
||||
|
||||
changesetfuzz.exe: $(TOP)\ext\session\changesetfuzz.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\changesetfuzz.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 \
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
@@ -2597,10 +2414,6 @@ rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
atrc.exe: $(TOP)\test\atrc.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\test\atrc.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
@@ -2620,17 +2433,6 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
|
||||
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
THREADTEST3_SRC = \
|
||||
$(TOP)\test\threadtest3.c \
|
||||
$(TOP)\test\tt3_checkpoint.c \
|
||||
$(TOP)\test\tt3_index.c \
|
||||
$(TOP)\test\tt3_vacuum.c \
|
||||
$(TOP)\test\tt3_stress.c \
|
||||
$(TOP)\test\tt3_lookaside1.c
|
||||
|
||||
threadtest3.exe: $(THREADTEST3_SRC) $(TOP)\src\test_multiplex.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LSMDIR=$(TOP)\ext\lsm1
|
||||
!INCLUDE $(LSMDIR)\Makefile.msc
|
||||
|
||||
@@ -2643,7 +2445,7 @@ clean:
|
||||
del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
|
||||
del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
|
||||
# <<mark>>
|
||||
del /Q $(SQLITE3TCLDLL) pkgIndex.tcl 2>NUL
|
||||
del /Q sqlite3.c sqlite3.h 2>NUL
|
||||
del /Q opcodes.c opcodes.h 2>NUL
|
||||
del /Q lemon.* lempar.c parse.* 2>NUL
|
||||
del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL
|
||||
@@ -2654,21 +2456,20 @@ clean:
|
||||
del /Q .target_source 2>NUL
|
||||
del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
|
||||
del /Q lsm.dll lsmtest.exe 2>NUL
|
||||
del /Q atrc.exe changesetfuzz.exe dbtotxt.exe index_usage.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 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
|
||||
del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL
|
||||
del /Q sqlite3.c sqlite3-*.c 2>NUL
|
||||
del /Q sqlite3rc.h 2>NUL
|
||||
del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
|
||||
del /Q sqltclsh.* 2>NUL
|
||||
del /Q dbfuzz.exe sessionfuzz.exe threadtest3.exe 2>NUL
|
||||
del /Q dbfuzz.exe sessionfuzz.exe 2>NUL
|
||||
del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL
|
||||
del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL
|
||||
del /Q fts5.* fts5parse.* 2>NUL
|
||||
|
||||
@@ -0,0 +1,440 @@
|
||||
<html>
|
||||
|
||||
<center>
|
||||
<h1> The "server-process-edition" Branch</h1>
|
||||
</center>
|
||||
|
||||
<p>
|
||||
The "server-process-edition" branch contains two modifications to stock
|
||||
SQLite that work together to provide concurrent read/write transactions
|
||||
using pessimistic page-level-locking. The system runs in two modes:
|
||||
|
||||
<ul>
|
||||
<li><p> Single-process mode - where all clients must be within the
|
||||
same address space, and
|
||||
<li><p> Multi-process mode - where clients may be distributed between
|
||||
multiple OS processes.
|
||||
</ul>
|
||||
|
||||
<p> The system is designed to be most efficient when used with
|
||||
<a href="https://www.sqlite.org/pragma.html#pragma_synchronous">
|
||||
"PRAGMA synchronous=OFF"</a>, although it does not require this.
|
||||
|
||||
<p>
|
||||
Up to 16 simultaneous read/write transactions controlled by page-level-locking
|
||||
are possible. Additionally, in single-process mode there may be any number of
|
||||
read-only transactions started using the "BEGIN READONLY" command. Read-only
|
||||
transactions do not block read-write transactions, and read-write transactions
|
||||
do not block read-only transactions. Read-only transactions access a consistent
|
||||
snapshot of the database - writes committed by other clients after the
|
||||
transaction has started are never visible to read-only transactions. In
|
||||
multi-process mode, the "BEGIN READONLY" command is equivalent to a stock
|
||||
"BEGIN".
|
||||
|
||||
<p>
|
||||
The two features on this branch are:
|
||||
<ol>
|
||||
<li><p> An
|
||||
<a href=#freelist>alternative layout for the database free-page list</a>.
|
||||
This is intended to reduce contention between writers when allocating
|
||||
new database pages, either from the free-list or by extending the
|
||||
database file.
|
||||
|
||||
<li><p> The <a href=#servermode>"server-mode" extension</a>, which
|
||||
provides read/write page-level-locking concurrency and (in
|
||||
single-process mode) read-only MVCC concurrency mentioned above.
|
||||
</ol>
|
||||
|
||||
|
||||
<h2 id=freelist> 1.0 Alternative Free-List Format </h2>
|
||||
|
||||
<p>
|
||||
The alternative free-list format is very similar to the current format. It
|
||||
differs in the following respects:
|
||||
|
||||
<ul>
|
||||
<li><p>The "total number of free pages" field in the db header is not
|
||||
maintained. It is always set to zero.
|
||||
<li><p> Instead of pointing to the first free-list trunk page, the free-list
|
||||
pointer in the db header points to a page known as the "free-list node".
|
||||
<li><p> The free-list node page contains N pointers to free-lists stored in the
|
||||
legacy format (i.e. a linked list of trunk pages each containing
|
||||
pointers to many free leaf pages).
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This effectively means that a database has N free-lists instead of just one. To
|
||||
allocate a free page, a writer only needs to lock one such free-list, and so up
|
||||
to N transactions that allocate new pages may proceed concurrently.
|
||||
|
||||
<p>
|
||||
Allocating pages from the end of the db file still locks out all other
|
||||
read/write transactions (because it involves writing to page 1, which every
|
||||
transaction needs to read). To minimize the frequency with which this occurs,
|
||||
when a page must be allocated from the end of the database file, the file is
|
||||
extended by 2048 pages. These are distributed equally between 16 free-lists
|
||||
(children of the free-list node page). Additionally, the first trunk page in
|
||||
each free list is never reused. Doing so would require writing to the
|
||||
free-list node page - effectively an exclusive lock on the entire
|
||||
page-allocation system.
|
||||
|
||||
<p>
|
||||
The current format used for the free-list can be modified or queried using a
|
||||
new pragma:
|
||||
|
||||
<pre>
|
||||
PRAGMA [database.]freelist_format;
|
||||
PRAGMA [database.]freelist_format = 1|2;
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
At present, the free-list format may only be modified when the free-list is
|
||||
completely empty. Which, as the implementation ensures that a free-list that
|
||||
uses the alternative format is never completely emptied, effectively precludes
|
||||
changing the format from 2 (alternative) to 1 (legacy).
|
||||
|
||||
<p>
|
||||
For databases that use the "alternative" free-list format, the read and write
|
||||
versions in the database header (byte offsets 18 and 19) are set to 3 for
|
||||
rollback mode or 4 for wal mode (instead of 1 and 2 respectively).
|
||||
|
||||
<h2 id=servermode> 2.0 Page level locking - "Server Mode" </h2>
|
||||
|
||||
<p>
|
||||
A database client automatically enters "server mode" if there exists a
|
||||
<i>directory</i> named "<database>-journal" in the file system alongside
|
||||
the database file "<database>" There is currently no provision for
|
||||
creating this directory, although it could be safely done for a database in
|
||||
rollback mode using something like:
|
||||
|
||||
<pre>
|
||||
PRAGMA journal_mode = off;
|
||||
BEGIN EXCLUSIVE;
|
||||
<create directory>
|
||||
END;
|
||||
</pre>
|
||||
|
||||
<p> As well as signalling new clients that they should enter server-mode,
|
||||
creating a directory named "<database>-journal" has the helpful
|
||||
side-effect of preventing legacy clients from accessing the database file at
|
||||
all.
|
||||
|
||||
<p> If the VFS is one that takes an exclusive lock on the db file (to
|
||||
guarantee that no other process accesses the db file), then the system
|
||||
automatically enters single-process mode. Otherwise, multi-process mode.
|
||||
|
||||
<p> In both single and multi-process modes, page-level-locking is managed
|
||||
by allocating a fixed-size array of "locking slots". Each locking slot is
|
||||
32-bits in size. By default, the array contains 262144 (2^18) slots. Pages are
|
||||
assigned to locking slots using the formula (pgno % 262144) - so pages 1,
|
||||
262145, 524289 etc. share a single locking slot.
|
||||
|
||||
<p> In single-process mode, the array of locking slots is allocated on
|
||||
the process heap and access is protected by a mutex. In multi-process mode, it
|
||||
is created by memory-mapping a file on disk (similar to the *-shm file in
|
||||
SQLite wal mode) and access is performed using
|
||||
<a href="https://en.wikipedia.org/wiki/Compare-and-swap">atomic CAS
|
||||
primitives</a> exclusively.
|
||||
|
||||
<p> Each time a read/write transaction is opened, the client assumes a client
|
||||
id between 0 and 15 for the duration of the transaction. Client ids are unique
|
||||
at any point in time - concurrently executing transactions must use different
|
||||
client ids. So there may exist a maximum of 16 concurrent read/write
|
||||
transactions at any one time.
|
||||
|
||||
<p> Read/write transactions in server-mode are similar to regular SQLite
|
||||
transactions in rollback mode. The most significant differences are that:
|
||||
|
||||
<ul>
|
||||
<li> <p>Instead of using journal file <database>-journal, server-mode
|
||||
clients use <database>-journal/<client-id>-journal. If
|
||||
there are multiple concurrent transactions, each uses a separate
|
||||
journal file.
|
||||
|
||||
<li> <p>No database-wide lock is taken. Instead, individual read and write
|
||||
locks are taken on the pages accessed by the transaction.
|
||||
</ul>
|
||||
|
||||
<p> Each locking slot is 32-bits in size. A locking slot may simultaneously
|
||||
support a single write-lock, up to 16 read-locks from read/write clients, and
|
||||
(in single process mode) up 1024 read-locks from "BEGIN READONLY" clients.
|
||||
Locking slot bits are used as follows:
|
||||
|
||||
<ul>
|
||||
<li> <p> The least-significant 16-bits are used for read-locks taken by
|
||||
read/write clients. To take a read-lock, bit <client-id> of the
|
||||
locking slot is set.
|
||||
|
||||
<li> <p> The next 5 bytes are used for the write-lock. If no write-lock
|
||||
is held on the slot, then this 5 byte integer is set to 0. Otherwise,
|
||||
it is set to (<i>C</i> + 1), where <i>C</i> is the <client-id> of
|
||||
the client holding the write-lock.
|
||||
|
||||
<li> <p> The next 10 bits contain the total number of read-locks held by
|
||||
"BEGIN READONLY" clients on the locking slot. See the section below
|
||||
for a description of how these are used.
|
||||
</ul>
|
||||
|
||||
<p> Currently, if a client requests a lock that cannot be granted due to
|
||||
a conflicting lock, SQLITE_BUSY is returned to the caller and either the
|
||||
entire transaction or statement transaction must be rolled back. See
|
||||
<a href=#problems>Problems and Issues</a> below for more details.
|
||||
|
||||
<h3> 2.1 Single-Process Mode </h3>
|
||||
|
||||
<p> Single process mode is simpler than multi-process mode because it does
|
||||
not have to deal with runtime client failure - it is assumed that if one
|
||||
client fails mid-transaction the entire process crashes. As a result the
|
||||
only time hot-journal rollback is required in single-process mode is as
|
||||
part of startup. The first client to connect to a database in single-process
|
||||
mode attempts to open and rollback all 16 potential hot journal files.
|
||||
|
||||
<p> But, in order to support non-blocking "BEGIN READONLY" transactions, it is
|
||||
also in some ways more complicated than multi-process mode. "BEGIN READONLY"
|
||||
support works as follows:
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p>In single-process mode, writers never spill the cache mid-transaction.
|
||||
Data is only written to the database as part of committing a transaction.
|
||||
|
||||
<li> <p>As well as writing the contents of overwritten pages out to the journal
|
||||
file, a writer in single-process mode also accumulates a list of buffers
|
||||
containing the original data for each page overwritten by the current
|
||||
transaction in main-memory.
|
||||
|
||||
<li> <p>When a transaction is ready to be committed, a writer obtains a
|
||||
transaction-id. Transaction-ids are assigned to writers using a
|
||||
monotonically increasing function. The writer then adds all of its "old
|
||||
data" buffers to a hash table accessible to all database clients.
|
||||
Associated with each hash table entry is the newly assigned transaction-id.
|
||||
It then waits (spin-locks) for all "BEGIN READONLY" read-locks to clear on
|
||||
all pages that will be written out by the transaction. Following this, it
|
||||
commits the transaction as normal (writes out the dirty pages and zeroes
|
||||
the journal file header).
|
||||
|
||||
<li> <p>Clients executing "BEGIN READONLY" transactions are not assigned
|
||||
a <client-id>. Instead, they are assigned a transaction-id that is
|
||||
either (a) that of the oldest transaction-id belonging to a writer that has
|
||||
not yet finished committing, or (b) if there are currently no writers
|
||||
committing then the value that will be assigned to the next committer.
|
||||
|
||||
<li> <p>When a "BEGIN READONLY" transaction reads a page, it first checks
|
||||
the aforementioned hash table for a suitable entry. A suitable entry
|
||||
is one with the right page-number and a transaction-id greater than or
|
||||
equal to that of the "BEGIN READONLY" transaction (i.e. one that had not
|
||||
finished committing when the BEGIN READONLY transaction started). If such
|
||||
an entry can be found, the client uses the associated data instead of
|
||||
reading from the db file. Or, if no such entry is found, the client:
|
||||
<ol>
|
||||
<li> Increments the number of BEGIN READONLY read-locks on the page.
|
||||
<li> Reads the contents of the page from the database file.
|
||||
<li> Decrements the number of BEGIN READONLY read-locks on the page.
|
||||
</ol>
|
||||
<p> The mutex used to protect access to the array of locking slots and
|
||||
the shared hash table is relinquished for step 2 above.
|
||||
|
||||
<li> <p>After each transaction is commited in single-process mode, the
|
||||
client searches the hash table for entries that can be discarded. An
|
||||
entry can be discarded if it has a transaction-id older than any still
|
||||
in use (either by BEGIN READONLY transactions or committers).
|
||||
</ul>
|
||||
|
||||
<h3> 2.2 Multi-Process Mode </h3>
|
||||
|
||||
<p> Multi-process mode differs from single-process mode in two important ways:
|
||||
|
||||
<ul>
|
||||
<li> <p>Individual clients may fail mid-transaction and the system must recover
|
||||
from this.
|
||||
|
||||
<li> <p>Partly as a consequence of the above, there are no convenient
|
||||
primitives like mutexes or malloc() with which to build complicated data
|
||||
structures like the hash-table used in single-process mode. As a result,
|
||||
there is no support for "BEGIN READONLY" transactions in multi-process
|
||||
mode.
|
||||
</ul>
|
||||
|
||||
<p> Unlike single-process mode clients, which may be assigned a different
|
||||
client-id for each transaction, clients in multi-process mode are assigned a
|
||||
client-id when they connect to the database and do not relinquish it until
|
||||
they disconnect. As such, a database in multi-process server-mode supports
|
||||
at most 16 concurrent client connections.
|
||||
|
||||
<p> As well as the array of locking slots, the shared-memory mapping used
|
||||
by clients in multi-process mode contains 16 "client slots". When a client
|
||||
connects, it takes a posix WRITE lock on the client slot that corresponds
|
||||
to its client id. This lock is not released until the client disconnects.
|
||||
Additionally, whenever a client starts a transaction, it sets the value
|
||||
in its client locking slot to 1, and clears it again after the transaction
|
||||
is concluded.
|
||||
|
||||
<p> This assists with handling client failure mid-transaction in two ways:
|
||||
|
||||
<ul>
|
||||
<li><p> If client A cannot obtain a lock due to a conflicting lock held by
|
||||
client B, it can check whether or not client B has failed by attempting a
|
||||
WRITE lock on its client locking slot. If successful, then client B must
|
||||
have failed and client A may:
|
||||
<ul>
|
||||
<li> Roll back client B's journal, and
|
||||
<li> By iterating through the entire locking slot array, release all
|
||||
locks held by client B when it failed.
|
||||
</ul>
|
||||
|
||||
<li><p> When a client first connects and locks its client locking slot, it
|
||||
can check whether or not the previous user of the client locking slot failed
|
||||
mid-transaction (since if it did, the locking slot value will still be
|
||||
non-zero). If it did, the new owner of the client locking slot can release
|
||||
any locks and roll back any hot-journal before proceeding.
|
||||
</ul>
|
||||
|
||||
<h3> 2.3 Required VFS Support </h3>
|
||||
|
||||
<p> The server-mode extension requires that the VFS support various special
|
||||
file-control commands. Currently support is limited to the "unix" VFS.
|
||||
|
||||
<dl>
|
||||
<dt> SQLITE_FCNTL_SERVER_MODE
|
||||
<dd><p> This is used by SQLite to query the VFS as to whether the
|
||||
connection should use single-process server-mode, multi-process server-mode,
|
||||
or continue in legacy mode.
|
||||
|
||||
<p>SQLite invokes this file-control as part of the procedure for detecting a
|
||||
hot journal (after it has established that there is a file-system entry named
|
||||
<database>-journal and that no other process holds a RESERVED lock).
|
||||
If the <database>-journal directory is present in the file-system and
|
||||
the current VFS takes an exclusive lock on the database file (i.e. is
|
||||
"unix-excl"), then this file-control indicates that the connection should use
|
||||
single-process server-mode. Or, if the directory exists but the VFS does not
|
||||
take an exclusive lock on the database file, that the connection should use
|
||||
multi-proces server-mode. Or, if there is no directory of the required name,
|
||||
that the connection should use legacy mode.
|
||||
|
||||
<dt> SQLITE_FCNTL_FILEID
|
||||
<dd><p> Return a 128-bit value that uniquely identifies an open file on disk
|
||||
from the VFS. This is used to ensure that all connections to the same
|
||||
database from within a process use the same shared state, even if they
|
||||
connect to the db using different file-system paths.
|
||||
|
||||
<dt> SQLITE_FCNTL_SHMOPEN
|
||||
<dd>
|
||||
|
||||
<dt> SQLITE_FCNTL_SHMOPEN2
|
||||
<dd>
|
||||
|
||||
<dt> SQLITE_FCNTL_SHMLOCK
|
||||
<dd>
|
||||
|
||||
<dt> SQLITE_FCNTL_SHMCLOSE
|
||||
<dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h2 id=problems> 3.0 Problems and Issues </h2>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p>Writer starvation might be the biggest issue. How can it be
|
||||
prevented?
|
||||
|
||||
<li> <p>Blocking locks of some sort would likely improve things. The issue
|
||||
here is deadlock detection.
|
||||
|
||||
<li> <p>The limit of 16 concurrent clients in multi-process mode could be
|
||||
raised to 27 (since the locking-slot bits used for BEGIN READONLY
|
||||
locks in single-process mode can be reassigned to support more
|
||||
read/write client read-locks).
|
||||
|
||||
</ul>
|
||||
|
||||
<h2> 4.0 Performance Test </h2>
|
||||
|
||||
<p>
|
||||
The test uses a single table with the following schema:
|
||||
|
||||
<pre>
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB(16), c BLOB(16), d BLOB(400));
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
CREATE INDEX i2 ON t1(c);
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The database initially contains 5,000,000 rows. Values for column "a" are
|
||||
between 1 and 5,000,000, inclusive. Other columns are populated with randomly
|
||||
generated blob values, each 16, 16, and 400 bytes in size, respectively.
|
||||
|
||||
<p>
|
||||
Read/write transactions used by the test take the following form. Each such
|
||||
transaction modifies approximately 25 pages (5 in the main table and 10 in each
|
||||
index), not accounting for tree rebalancing operations.
|
||||
|
||||
<pre>
|
||||
BEGIN;
|
||||
REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
|
||||
REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
|
||||
REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
|
||||
REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
|
||||
REPLACE INTO t1 VALUES(abs(random() % 5000000), randomblob(16), randomblob(16), randomblob(400));
|
||||
COMMIT;
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Read-only transactions are as follows:
|
||||
|
||||
<pre>
|
||||
BEGIN READONLY;
|
||||
SELECT * FROM t1 WHERE a>abs((random()%5000000)) LIMIT 10;
|
||||
SELECT * FROM t1 WHERE a>abs((random()%5000000)) LIMIT 10;
|
||||
SELECT * FROM t1 WHERE a>abs((random()%5000000)) LIMIT 10;
|
||||
SELECT * FROM t1 WHERE a>abs((random()%5000000)) LIMIT 10;
|
||||
SELECT * FROM t1 WHERE a>abs((random()%5000000)) LIMIT 10;
|
||||
END;
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The performance test features one or more clients executing read/write
|
||||
transactions as fast as possible, and zero or more clients executing read-only
|
||||
transactions, also as fast as possible. All tests use the "unix-excl" VFS and
|
||||
all clients execute in a separate thread within the same process. The database
|
||||
is located on a tmpfs file-system.
|
||||
|
||||
<p>
|
||||
In the table below "rw:" refers to the number of read-write clients, and "ro:"
|
||||
the number of read-only clients used by the test. The TPS values in brackets
|
||||
are the number of read-only transactions per second. All other values are
|
||||
read-write transactions per second.
|
||||
|
||||
<p>
|
||||
The collision rate (percentage of attempted transactions that failed due to a
|
||||
page-level locking conflict) in all tests was between 1 and 2%. Failed
|
||||
transactions are not included in the TPS counts below.
|
||||
|
||||
<p>
|
||||
<table border=1 width=90% align=center>
|
||||
<!--
|
||||
320 jm=persist, rw:1 139675, 135797
|
||||
320 jm=wal, rw:1 120995, 118889
|
||||
begin-concurrent, rw:1 119438, 117580
|
||||
begin-concurrent, rw:2 166923, 166904
|
||||
begin-concurrent, rw:3 180432, 172825
|
||||
begin-concurrent, rw:2,ro:1 150427(347319),152087(351601)
|
||||
server-mode, rw:1 126592, 126742
|
||||
server-mode, rw:2 228317, 227155
|
||||
server-mode, rw:3 309712, 306218
|
||||
server-mode, rw:2,ro:1 213303(576032),210994(556005)
|
||||
-->
|
||||
|
||||
<tr><th> Configuration <th>TPS per client <th> TPS total
|
||||
<tr><td> 3.20.0, journal_mode=persist, rw:1, ro:0 <td>6886 <td> 6886
|
||||
<tr><td> 3.20.0, journal_mode=wal, rw:1, ro:0 <td>5997 <td> 5997
|
||||
<tr><td> begin-concurrent, rw:1, ro:0<td>5925<td> 5925
|
||||
<tr><td> begin-concurrent, rw:2, ro:0<td>4172 <td> 8345
|
||||
<tr><td> begin-concurrent, rw:3, ro:0<td>2943 <td> 8831
|
||||
<tr><td> begin-concurrent, rw:2, ro:1<td>3781 <td> 7562 (17473)
|
||||
<tr><td> server-mode, rw:1, ro:0 <td>6333 <td> 6333
|
||||
<tr><td> server-mode, rw:2, ro:0<td> 5693 <td> 11386
|
||||
<tr><td> server-mode, rw:3, ro:0<td>5132 <td> 15398
|
||||
<tr><td> server-mode, rw:2, ro:1<td>5303 <td> 10607 (28300)
|
||||
</table>
|
||||
|
||||
@@ -1,36 +1,22 @@
|
||||
<h1 align="center">SQLite Source Repository</h1>
|
||||
|
||||
This repository contains the complete source code for the
|
||||
[SQLite database engine](https://sqlite.org/). Some test scripts
|
||||
are also included. However, many other test scripts
|
||||
This repository contains the complete source code for the SQLite database
|
||||
engine. Some test scripts are also included. However, many other test scripts
|
||||
and most of the documentation are managed separately.
|
||||
|
||||
## Version Control
|
||||
|
||||
SQLite sources are managed using the
|
||||
[Fossil](https://www.fossil-scm.org/), a distributed version control system
|
||||
that was specifically designed and written to support SQLite development.
|
||||
The [Fossil repository](https://sqlite.org/src/timeline) contains the urtext.
|
||||
|
||||
If you are reading this on GitHub or some other Git repository or service,
|
||||
then you are looking at a mirror. The names of check-ins and
|
||||
other artifacts in a Git mirror are different from the official
|
||||
names for those objects. The official names for check-ins are
|
||||
found in a footer on the check-in comment for authorized mirrors.
|
||||
The official check-in name can also be seen in the `manifest.uuid` file
|
||||
in the root of the tree. Always use the official name, not the
|
||||
Git-name, when communicating about an SQLite check-in.
|
||||
|
||||
If you pulled your SQLite source code from a secondary source and want to
|
||||
verify its integrity, there are hints on how to do that in the
|
||||
[Verifying Code Authenticity](#vauth) section below.
|
||||
If you are reading this on a Git mirror someplace, you are doing it wrong.
|
||||
The [official repository](https://www.sqlite.org/src/) is better. Go there
|
||||
now.
|
||||
|
||||
## Obtaining The Code
|
||||
|
||||
SQLite sources are managed using the
|
||||
[Fossil](https://www.fossil-scm.org/), a distributed version control system
|
||||
that was specifically designed to support SQLite development.
|
||||
If you do not want to use Fossil, you can download tarballs or ZIP
|
||||
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
|
||||
|
||||
* Latest trunk check-in as
|
||||
* Lastest trunk check-in as
|
||||
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
|
||||
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
|
||||
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
|
||||
@@ -41,34 +27,34 @@ archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
|
||||
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
|
||||
|
||||
* For other check-ins, substitute an appropriate branch name or
|
||||
tag or hash prefix in place of "release" in the URLs of the previous
|
||||
tag or hash prefix for "release" in the URLs of the previous
|
||||
bullet. Or browse the [timeline](https://www.sqlite.org/src/timeline)
|
||||
to locate the check-in desired, click on its information page link,
|
||||
then click on the "Tarball" or "ZIP Archive" links on the information
|
||||
page.
|
||||
|
||||
If you do want to use Fossil to check out the source tree,
|
||||
If you do want to use Fossil to check out the source tree,
|
||||
first install Fossil version 2.0 or later.
|
||||
(Source tarballs and precompiled binaries available
|
||||
[here](https://www.fossil-scm.org/fossil/uv/download.html). Fossil is
|
||||
a stand-alone program. To install, simply download or build the single
|
||||
a stand-alone program. To install, simply download or build the single
|
||||
executable file and put that file someplace on your $PATH.)
|
||||
Then run commands like this:
|
||||
|
||||
mkdir -p ~/sqlite ~/Fossils
|
||||
mkdir ~/sqlite
|
||||
cd ~/sqlite
|
||||
fossil clone https://www.sqlite.org/src ~/Fossils/sqlite.fossil
|
||||
fossil open ~/Fossils/sqlite.fossil
|
||||
|
||||
fossil clone https://www.sqlite.org/src sqlite.fossil
|
||||
fossil open sqlite.fossil
|
||||
|
||||
After setting up a repository using the steps above, you can always
|
||||
update to the latest version using:
|
||||
update to the lastest version using:
|
||||
|
||||
fossil update trunk ;# latest trunk check-in
|
||||
fossil update release ;# latest official release
|
||||
|
||||
Or type "fossil ui" to get a web-based user interface.
|
||||
|
||||
## Compiling for Unix-like systems
|
||||
## Compiling
|
||||
|
||||
First create a directory in which to place
|
||||
the build products. It is recommended, but not required, that the
|
||||
@@ -94,22 +80,22 @@ script does not work out for you, there is a generic makefile named
|
||||
can copy and edit to suit your needs. Comments on the generic makefile
|
||||
show what changes are needed.
|
||||
|
||||
## Using MSVC for Windows systems
|
||||
## Using MSVC
|
||||
|
||||
On Windows, all applicable build products can be compiled with MSVC.
|
||||
First open the command prompt window associated with the desired compiler
|
||||
version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE
|
||||
with the provided "Makefile.msc" to build one of the supported targets.
|
||||
|
||||
For example, from the parent directory of the source subtree named "sqlite":
|
||||
For example:
|
||||
|
||||
mkdir bld
|
||||
cd bld
|
||||
nmake /f ..\sqlite\Makefile.msc TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.c TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.dll TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc sqlite3.exe TOP=..\sqlite
|
||||
nmake /f ..\sqlite\Makefile.msc test TOP=..\sqlite
|
||||
nmake /f Makefile.msc TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.c TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite
|
||||
nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite
|
||||
nmake /f Makefile.msc test TOP=..\sqlite
|
||||
|
||||
There are several build options that can be set via the NMAKE command
|
||||
line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument
|
||||
@@ -136,7 +122,7 @@ the "tclsqlite.c" file which implements the
|
||||
extension and only later escaped to the wild as an independent library.)
|
||||
|
||||
Test scripts and programs are found in the **test/** subdirectory.
|
||||
Additional test code is found in other source repositories.
|
||||
Addtional test code is found in other source repositories.
|
||||
See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for
|
||||
additional information.
|
||||
|
||||
@@ -170,17 +156,20 @@ at just the right spots. Note that comment text in the sqlite3.h file is
|
||||
used to generate much of the SQLite API documentation. The Tcl scripts
|
||||
used to generate that documentation are in a separate source repository.
|
||||
|
||||
The SQL language parser is **parse.c** which is generated from a grammar in
|
||||
The SQL language parser is **parse.c** which is generate from a grammar in
|
||||
the src/parse.y file. The conversion of "parse.y" into "parse.c" is done
|
||||
by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code
|
||||
for lemon is at tool/lemon.c. Lemon uses the tool/lempar.c file as a
|
||||
template for generating its parser.
|
||||
|
||||
Lemon also generates the **parse.h** header file, at the same time it
|
||||
generates parse.c.
|
||||
generates parse.c. But the parse.h header file is
|
||||
modified further (to add additional symbols) using the ./addopcodes.tcl
|
||||
Tcl script.
|
||||
|
||||
The **opcodes.h** header file contains macros that define the numbers
|
||||
corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h
|
||||
file is generated by scanning the src/vdbe.c source file. The
|
||||
file is generated by the scanning the src/vdbe.c source file. The
|
||||
Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
|
||||
A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
|
||||
the **opcodes.c** source file, which contains a reverse mapping from
|
||||
@@ -237,7 +226,7 @@ prepared statements, the description of
|
||||
[how transactions work](http://www.sqlite.org/atomiccommit.html), and
|
||||
the [overview of the query planner](http://www.sqlite.org/optoverview.html).
|
||||
|
||||
Years of effort have gone into optimizing SQLite, both
|
||||
Years of effort have gone into optimizating SQLite, both
|
||||
for small size and high performance. And optimizations tend to result in
|
||||
complex code. So there is a lot of complexity in the current SQLite
|
||||
implementation. It will not be the easiest library in the world to hack.
|
||||
@@ -294,36 +283,19 @@ Key files:
|
||||
building the "testfixture.exe" program. The testfixture.exe program is
|
||||
an enhanced Tcl shell. The testfixture.exe program runs scripts in the
|
||||
test/ folder to validate the core SQLite code. The testfixture program
|
||||
(and some other test programs too) is built and run when you type
|
||||
(and some other test programs too) is build and run when you type
|
||||
"make test".
|
||||
|
||||
* **ext/misc/json1.c** - This file implements the various JSON functions
|
||||
that are built into SQLite.
|
||||
that are build into SQLite.
|
||||
|
||||
There are many other source files. Each has a succinct header comment that
|
||||
describes its purpose and role within the larger system.
|
||||
|
||||
<a name="vauth"></a>
|
||||
## Verifying Code Authenticity
|
||||
|
||||
The `manifest` file at the root directory of the source tree
|
||||
contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for
|
||||
older files) for every source file in the repository.
|
||||
The name of the version of the entire source tree is just the
|
||||
SHA3-256 hash of the `manifest` file itself, possibly with the
|
||||
last line of that file omitted if the last line begins with
|
||||
"`# Remove this line`".
|
||||
The `manifest.uuid` file should contain the SHA3-256 hash of the
|
||||
`manifest` file. If all of the above hash comparisons are correct, then
|
||||
you can be confident that your source tree is authentic and unadulterated.
|
||||
|
||||
The format of the `manifest` file should be mostly self-explanatory, but
|
||||
if you want details, they are available
|
||||
[here](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest).
|
||||
|
||||
## Contacts
|
||||
|
||||
The main SQLite website is [http://www.sqlite.org/](http://www.sqlite.org/)
|
||||
The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
|
||||
with geographically distributed backups at
|
||||
[http://www2.sqlite.org/](http://www2.sqlite.org) and
|
||||
[http://www3.sqlite.org/](http://www3.sqlite.org).
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
AM_CFLAGS = @BUILD_CFLAGS@
|
||||
AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
|
||||
|
||||
lib_LTLIBRARIES = libsqlite3.la
|
||||
libsqlite3_la_SOURCES = sqlite3.c
|
||||
libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
|
||||
@@ -13,7 +14,7 @@ sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_D
|
||||
|
||||
include_HEADERS = sqlite3.h sqlite3ext.h
|
||||
|
||||
EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc sqlite3rc.h README.txt Replace.cs Makefile.fallback
|
||||
EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
|
||||
pkgconfigdir = ${libdir}/pkgconfig
|
||||
pkgconfig_DATA = sqlite3.pc
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/bin/make
|
||||
#
|
||||
# If the configure script does not work, then this Makefile is available
|
||||
# as a backup. Manually configure the variables below.
|
||||
#
|
||||
# Note: This makefile works out-of-the-box on MacOS 10.2 (Jaguar)
|
||||
#
|
||||
CC = gcc
|
||||
CFLAGS = -O0 -I.
|
||||
LIBS = -lz
|
||||
COPTS += -D_BSD_SOURCE
|
||||
COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0
|
||||
COPTS += -DSQLITE_THREADSAFE=0
|
||||
COPTS += -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
COPTS += -DSQLITE_WITHOUT_ZONEMALLOC
|
||||
COPTS += -DSQLITE_ENABLE_RTREE
|
||||
|
||||
sqlite3: shell.c sqlite3.c
|
||||
$(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS)
|
||||
+13
-39
@@ -73,7 +73,7 @@ API_ARMOR = 0
|
||||
!IFNDEF NO_WARN
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@@ -196,7 +196,6 @@ OSTRACE = 0
|
||||
DEBUG = 0
|
||||
!ENDIF
|
||||
|
||||
|
||||
# Enable use of available compiler optimizations? Normally, this should be
|
||||
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
|
||||
# can be useful for testing.
|
||||
@@ -211,12 +210,6 @@ OPTIMIZATIONS = 2
|
||||
SESSION = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this to non-0 to enable support for the rbu extension.
|
||||
#
|
||||
!IFNDEF RBU
|
||||
RBU = 0
|
||||
!ENDIF
|
||||
|
||||
# Set the source code file to be used by executables and libraries when
|
||||
# they need the amalgamation.
|
||||
#
|
||||
@@ -284,11 +277,6 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
|
||||
!IF $(MINIMAL_AMALGAMATION)==0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
!ENDIF
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
!ENDIF
|
||||
@@ -301,16 +289,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
|
||||
!ENDIF
|
||||
|
||||
# Always enable math functions on Windows
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS
|
||||
|
||||
# Should the rbu extension be enabled? If so, add compilation options
|
||||
# to enable it.
|
||||
#
|
||||
!IF $(RBU)!=0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1
|
||||
!ENDIF
|
||||
|
||||
# These are the "extended" SQLite compilation options used when compiling for
|
||||
# the Windows 10 platform.
|
||||
#
|
||||
@@ -448,9 +426,9 @@ UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
!IF $(USE_FULLWARN)!=0
|
||||
BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
|
||||
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
|
||||
!ELSE
|
||||
BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
|
||||
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
|
||||
!ENDIF
|
||||
|
||||
# Check if assembly code listings should be generated for the source
|
||||
@@ -501,12 +479,12 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
|
||||
#
|
||||
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
|
||||
!IF "$(PLATFORM)"=="x86"
|
||||
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
!ELSE
|
||||
!IFNDEF PLATFORM
|
||||
CORE_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -guard:cf -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall
|
||||
!ELSE
|
||||
CORE_CCONV_OPTS =
|
||||
SHELL_CCONV_OPTS =
|
||||
@@ -823,7 +801,7 @@ BCC = $(BCC) -Zi
|
||||
# Command line prefixes for compiling code, compiling resources,
|
||||
# linking, etc.
|
||||
#
|
||||
LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
|
||||
LTCOMPILE = $(TCC) -Fo$@
|
||||
LTRCOMPILE = $(RCC) -r
|
||||
LTLIB = lib.exe
|
||||
LTLINK = $(TCC) -Fe$@
|
||||
@@ -841,11 +819,6 @@ LTLIBS = $(LTLIBS) rpcrt4.lib
|
||||
!IFDEF PLATFORM
|
||||
LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||
LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
|
||||
!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
|
||||
"$(VISUALSTUDIOVERSION)"=="14.0" || \
|
||||
"$(VISUALSTUDIOVERSION)"=="15.0"
|
||||
LTLINKOPTS = /NOLOGO /MACHINE:x86
|
||||
LTLIBOPTS = /NOLOGO /MACHINE:x86
|
||||
!ELSE
|
||||
LTLINKOPTS = /NOLOGO
|
||||
LTLIBOPTS = /NOLOGO
|
||||
@@ -955,9 +928,10 @@ LIBRESOBJS =
|
||||
# when the shell is not being dynamically linked.
|
||||
#
|
||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -992,7 +966,7 @@ Replace.exe:
|
||||
sqlite3.def: Replace.exe $(LIBOBJ)
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all $(LIBOBJ) \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
$(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ may be specified in this manner as some require the amalgamation to be built
|
||||
with them enabled (see http://www.sqlite.org/compile.html). For example, the
|
||||
following will work:
|
||||
|
||||
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1"
|
||||
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
|
||||
|
||||
However, the following will not compile unless the amalgamation was built
|
||||
with it enabled:
|
||||
|
||||
+22
-92
@@ -29,7 +29,6 @@ AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
|
||||
AC_FUNC_STRERROR_R
|
||||
|
||||
AC_CONFIG_FILES([Makefile sqlite3.pc])
|
||||
BUILD_CFLAGS=
|
||||
AC_SUBST(BUILD_CFLAGS)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -87,13 +86,13 @@ AC_SUBST(READLINE_LIBS)
|
||||
AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
|
||||
[--enable-threadsafe], [build a thread-safe library [default=yes]])],
|
||||
[], [enable_threadsafe=yes])
|
||||
if test x"$enable_threadsafe" == "xno"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0"
|
||||
else
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
|
||||
THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
|
||||
if test x"$enable_threadsafe" != "xno"; then
|
||||
THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
|
||||
AC_SEARCH_LIBS(pthread_create, pthread)
|
||||
AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
|
||||
fi
|
||||
AC_SUBST(THREADSAFE_FLAGS)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@@ -105,87 +104,36 @@ AC_ARG_ENABLE(dynamic-extensions, [AS_HELP_STRING(
|
||||
if test x"$enable_dynamic_extensions" != "xno"; then
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
else
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
|
||||
DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
fi
|
||||
AC_MSG_CHECKING([for whether to support dynamic extensions])
|
||||
AC_MSG_RESULT($enable_dynamic_extensions)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-math
|
||||
#
|
||||
AC_ARG_ENABLE(math, [AS_HELP_STRING(
|
||||
[--enable-math], [SQL math functions [default=yes]])],
|
||||
[], [enable_math=yes])
|
||||
AC_MSG_CHECKING([SQL math functions])
|
||||
if test x"$enable_math" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_MATH_FUNCTIONS"
|
||||
AC_MSG_RESULT([enabled])
|
||||
AC_SEARCH_LIBS(ceil, m)
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
fi
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-fts4
|
||||
#
|
||||
AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
|
||||
[--enable-fts4], [include fts4 support [default=yes]])],
|
||||
[], [enable_fts4=yes])
|
||||
AC_MSG_CHECKING([FTS4 extension])
|
||||
if test x"$enable_fts4" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
|
||||
AC_MSG_RESULT([enabled])
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
fi
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-fts3
|
||||
#
|
||||
AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
|
||||
[--enable-fts3], [include fts3 support [default=no]])],
|
||||
[], [])
|
||||
AC_MSG_CHECKING([FTS3 extension])
|
||||
if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
|
||||
AC_MSG_RESULT([enabled])
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
fi
|
||||
AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-fts5
|
||||
#
|
||||
AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
|
||||
[--enable-fts5], [include fts5 support [default=yes]])],
|
||||
[], [enable_fts5=yes])
|
||||
AC_MSG_CHECKING([FTS5 extension])
|
||||
[--enable-fts5], [include fts5 support [default=no]])],
|
||||
[], [enable_fts5=no])
|
||||
if test x"$enable_fts5" = "xyes"; then
|
||||
AC_MSG_RESULT([enabled])
|
||||
AC_SEARCH_LIBS(log, m)
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
|
||||
fi
|
||||
AC_SUBST(FTS5_FLAGS)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-rtree
|
||||
# --enable-json1
|
||||
#
|
||||
AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
|
||||
[--enable-rtree], [include rtree support [default=yes]])],
|
||||
[], [enable_rtree=yes])
|
||||
AC_MSG_CHECKING([RTREE extension])
|
||||
if test x"$enable_rtree" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
|
||||
AC_MSG_RESULT([enabled])
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
|
||||
[--enable-json1], [include json1 support [default=no]])],
|
||||
[], [enable_json1=no])
|
||||
if test x"$enable_json1" = "xyes"; then
|
||||
JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
|
||||
fi
|
||||
AC_SUBST(JSON1_FLAGS)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@@ -193,30 +141,11 @@ fi
|
||||
#
|
||||
AC_ARG_ENABLE(session, [AS_HELP_STRING(
|
||||
[--enable-session], [enable the session extension [default=no]])],
|
||||
[], [])
|
||||
AC_MSG_CHECKING([Session extension])
|
||||
[], [enable_session=no])
|
||||
if test x"$enable_session" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
AC_MSG_RESULT([enabled])
|
||||
else
|
||||
AC_MSG_RESULT([disabled])
|
||||
fi
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# --enable-debug
|
||||
#
|
||||
AC_ARG_ENABLE(debug, [AS_HELP_STRING(
|
||||
[--enable-debug], [build with debugging features enabled [default=no]])],
|
||||
[], [])
|
||||
AC_MSG_CHECKING([Build type])
|
||||
if test x"$enable_debug" = "xyes"; then
|
||||
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
|
||||
CFLAGS="-g -O0"
|
||||
AC_MSG_RESULT([debug])
|
||||
else
|
||||
AC_MSG_RESULT([release])
|
||||
SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
fi
|
||||
AC_SUBST(SESSION_FLAGS)
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@@ -236,8 +165,9 @@ AC_SUBST(EXTRA_SHELL_OBJ)
|
||||
|
||||
AC_CHECK_FUNCS(posix_fallocate)
|
||||
AC_CHECK_HEADERS(zlib.h,[
|
||||
AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"])
|
||||
AC_SEARCH_LIBS(deflate,z,[ZLIB_FLAGS="-DSQLITE_HAVE_ZLIB"])
|
||||
])
|
||||
AC_SUBST(ZLIB_FLAGS)
|
||||
|
||||
AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"])
|
||||
AC_SUBST(SHELL_CFLAGS)
|
||||
|
||||
+74
-109
@@ -11,6 +11,8 @@
|
||||
#
|
||||
# See the file "license.terms" for information on usage and redistribution
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
#
|
||||
# RCS: @(#) $Id: Makefile.in,v 1.59 2005/07/26 19:17:02 mdejong Exp $
|
||||
|
||||
#========================================================================
|
||||
# Add additional lines to handle any additional AC_SUBST cases that
|
||||
@@ -58,8 +60,6 @@ PKG_HEADERS = @PKG_HEADERS@
|
||||
#========================================================================
|
||||
|
||||
PKG_LIB_FILE = @PKG_LIB_FILE@
|
||||
PKG_LIB_FILE8 = @PKG_LIB_FILE8@
|
||||
PKG_LIB_FILE9 = @PKG_LIB_FILE9@
|
||||
PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
|
||||
|
||||
lib_BINARIES = $(PKG_LIB_FILE)
|
||||
@@ -73,11 +73,10 @@ exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
datarootdir = @datarootdir@
|
||||
runstatedir = @runstatedir@
|
||||
datadir = @datadir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
|
||||
DESTDIR =
|
||||
|
||||
@@ -86,25 +85,24 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
|
||||
pkglibdir = $(libdir)/$(PKG_DIR)
|
||||
pkgincludedir = $(includedir)/$(PKG_DIR)
|
||||
|
||||
top_builddir = @abs_top_builddir@
|
||||
top_builddir = .
|
||||
|
||||
INSTALL_OPTIONS =
|
||||
INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
|
||||
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_LIBRARY = @INSTALL_LIBRARY@
|
||||
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
CC = @CC@
|
||||
CCLD = @CCLD@
|
||||
CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
|
||||
CFLAGS_WARNING = @CFLAGS_WARNING@
|
||||
CLEANFILES = @CLEANFILES@
|
||||
EXEEXT = @EXEEXT@
|
||||
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
|
||||
MAKE_LIB = @MAKE_LIB@
|
||||
MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
|
||||
MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
|
||||
MAKE_STUB_LIB = @MAKE_STUB_LIB@
|
||||
OBJEXT = @OBJEXT@
|
||||
RANLIB = @RANLIB@
|
||||
@@ -119,6 +117,8 @@ TCL_SRC_DIR = @TCL_SRC_DIR@
|
||||
#TK_BIN_DIR = @TK_BIN_DIR@
|
||||
#TK_SRC_DIR = @TK_SRC_DIR@
|
||||
|
||||
# This is no longer necessary even for packages that use private Tcl headers
|
||||
#TCL_TOP_DIR_NATIVE = @TCL_TOP_DIR_NATIVE@
|
||||
# Not used, but retained for reference of what libs Tcl required
|
||||
#TCL_LIBS = @TCL_LIBS@
|
||||
|
||||
@@ -132,52 +132,41 @@ TCL_SRC_DIR = @TCL_SRC_DIR@
|
||||
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
|
||||
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
|
||||
TCLLIBPATH = $(top_builddir)
|
||||
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
|
||||
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
|
||||
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
|
||||
@LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
|
||||
PATH="$(EXTRA_PATH):$(PATH)" \
|
||||
TCLLIBPATH="$(TCLLIBPATH)"
|
||||
# TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
|
||||
|
||||
TCLSH_PROG = @TCLSH_PROG@
|
||||
TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
|
||||
TCLSH = $(TCLSH_ENV) $(TCLSH_PROG)
|
||||
|
||||
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
|
||||
#WISH_PROG = @WISH_PROG@
|
||||
#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
|
||||
#WISH = $(TCLSH_ENV) $(WISH_PROG)
|
||||
|
||||
|
||||
SHARED_BUILD = @SHARED_BUILD@
|
||||
|
||||
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I. -I$(srcdir)/..
|
||||
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I$(srcdir)/..
|
||||
#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
|
||||
|
||||
PKG_CFLAGS = @PKG_CFLAGS@
|
||||
|
||||
# TCL_DEFS is not strictly need here, but if you remove it, then you
|
||||
# must make sure that configure.ac checks for the necessary components
|
||||
# must make sure that configure.in checks for the necessary components
|
||||
# that your library may use. TCL_DEFS can actually be a problem if
|
||||
# you do not compile with a similar machine setup as the Tcl core was
|
||||
# compiled with.
|
||||
#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
|
||||
DEFS = @DEFS@ $(PKG_CFLAGS)
|
||||
|
||||
# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
|
||||
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
|
||||
CLEANFILES = @CLEANFILES@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LIBS = @PKG_LIBS@ @LIBS@
|
||||
AR = @AR@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \
|
||||
$(CFLAGS_DEFAULT) $(CFLAGS_WARNING) $(SHLIB_CFLAGS) $(CFLAGS)
|
||||
|
||||
GDB = gdb
|
||||
VALGRIND = valgrind
|
||||
VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
|
||||
--leak-check=yes --show-reachable=yes -v
|
||||
|
||||
.SUFFIXES: .c .$(OBJEXT)
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
|
||||
#========================================================================
|
||||
# Start of user-definable TARGETS section
|
||||
@@ -185,7 +174,7 @@ VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
|
||||
|
||||
#========================================================================
|
||||
# TEA TARGETS. Please note that the "libraries:" target refers to platform
|
||||
# independent files, and the "binaries:" target includes executable programs and
|
||||
# independent files, and the "binaries:" target inclues executable programs and
|
||||
# platform-dependent libraries. Modify these targets so that they install
|
||||
# the various pieces of your package. The make and install rules
|
||||
# for the BINARIES that you specified above have already been done.
|
||||
@@ -204,6 +193,7 @@ binaries: $(BINARIES)
|
||||
|
||||
libraries:
|
||||
|
||||
|
||||
#========================================================================
|
||||
# Your doc target should differentiate from doc builds (by the developer)
|
||||
# and doc installs (see install-doc), which just install the docs on the
|
||||
@@ -226,11 +216,11 @@ install-binaries: binaries install-lib-binaries install-bin-binaries
|
||||
#========================================================================
|
||||
|
||||
install-libraries: libraries
|
||||
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(includedir)"
|
||||
@mkdir -p $(DESTDIR)$(includedir)
|
||||
@echo "Installing header files in $(DESTDIR)$(includedir)"
|
||||
@list='$(PKG_HEADERS)'; for i in $$list; do \
|
||||
echo "Installing $(srcdir)/$$i" ; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$i "$(DESTDIR)$(includedir)" ; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
|
||||
done;
|
||||
|
||||
#========================================================================
|
||||
@@ -239,11 +229,12 @@ install-libraries: libraries
|
||||
#========================================================================
|
||||
|
||||
install-doc: doc
|
||||
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(mandir)/mann"
|
||||
@mkdir -p $(DESTDIR)$(mandir)/mann
|
||||
@echo "Installing documentation in $(DESTDIR)$(mandir)"
|
||||
@list='$(srcdir)/doc/*.n'; for i in $$list; do \
|
||||
echo "Installing $$i"; \
|
||||
$(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/mann" ; \
|
||||
rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
|
||||
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
|
||||
done
|
||||
|
||||
test: binaries libraries
|
||||
@@ -253,21 +244,7 @@ shell: binaries libraries
|
||||
@$(TCLSH) $(SCRIPT)
|
||||
|
||||
gdb:
|
||||
$(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
|
||||
|
||||
gdb-test: binaries libraries
|
||||
$(TCLSH_ENV) $(PKG_ENV) $(GDB) \
|
||||
--args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
|
||||
$(TESTFLAGS) -singleproc 1 \
|
||||
-load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
|
||||
[list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]"
|
||||
|
||||
valgrind: binaries libraries
|
||||
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
|
||||
`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
|
||||
|
||||
valgrindshell: binaries libraries
|
||||
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
|
||||
$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
|
||||
|
||||
depend:
|
||||
|
||||
@@ -306,70 +283,49 @@ $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
|
||||
# As necessary, add $(srcdir):$(srcdir)/compat:....
|
||||
#========================================================================
|
||||
|
||||
VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
|
||||
VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
|
||||
|
||||
.c.@OBJEXT@:
|
||||
$(COMPILE) -c `@CYGPATH@ $<` -o $@
|
||||
|
||||
tclsample.@OBJEXT@: sampleUuid.h
|
||||
|
||||
$(srcdir)/manifest.uuid:
|
||||
printf "git-" >$(srcdir)/manifest.uuid
|
||||
(cd $(srcdir); git rev-parse HEAD >>$(srcdir)/manifest.uuid || \
|
||||
(printf "svn-r" >$(srcdir)/manifest.uuid ; \
|
||||
svn info --show-item last-changed-revision >>$(srcdir)/manifest.uuid) || \
|
||||
printf "unknown" >$(srcdir)/manifest.uuid)
|
||||
|
||||
sampleUuid.h: $(srcdir)/manifest.uuid
|
||||
echo "#define SAMPLE_VERSION_UUID \\" >$@
|
||||
cat $(srcdir)/manifest.uuid >>$@
|
||||
echo "" >>$@
|
||||
|
||||
#========================================================================
|
||||
# Distribution creation
|
||||
# You may need to tweak this target to make it work correctly.
|
||||
#========================================================================
|
||||
|
||||
#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
|
||||
COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
|
||||
COMPRESS = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
|
||||
DIST_ROOT = /tmp/dist
|
||||
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
|
||||
|
||||
DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
|
||||
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
|
||||
|
||||
dist-clean:
|
||||
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
|
||||
|
||||
dist: dist-clean $(srcdir)/manifest.uuid
|
||||
$(INSTALL_DATA_DIR) $(DIST_DIR)
|
||||
dist: dist-clean
|
||||
mkdir -p $(DIST_DIR)
|
||||
cp -p $(srcdir)/README* $(srcdir)/license* \
|
||||
$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
|
||||
$(DIST_DIR)/
|
||||
chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
|
||||
chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
|
||||
|
||||
# TEA files
|
||||
$(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
|
||||
$(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
|
||||
$(DIST_DIR)/
|
||||
$(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
|
||||
for i in $(srcdir)/*.[ch]; do \
|
||||
if [ -f $$i ]; then \
|
||||
cp -p $$i $(DIST_DIR)/ ; \
|
||||
fi; \
|
||||
done;
|
||||
|
||||
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
|
||||
$(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
|
||||
$(srcdir)/manifest.uuid \
|
||||
$(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
|
||||
$(DIST_DIR)/tclconfig/
|
||||
mkdir $(DIST_DIR)/tclconfig
|
||||
cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
|
||||
$(DIST_DIR)/tclconfig/
|
||||
chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
|
||||
chmod +x $(DIST_DIR)/tclconfig/install-sh
|
||||
|
||||
# Extension files
|
||||
$(DIST_INSTALL_DATA) \
|
||||
$(srcdir)/ChangeLog \
|
||||
$(srcdir)/README.sha \
|
||||
$(srcdir)/license.terms \
|
||||
$(srcdir)/README \
|
||||
$(srcdir)/pkgIndex.tcl.in \
|
||||
$(DIST_DIR)/
|
||||
|
||||
list='demos doc generic library macosx tests unix win'; \
|
||||
list='demos doc generic library mac tests unix win'; \
|
||||
for p in $$list; do \
|
||||
if test -d $(srcdir)/$$p ; then \
|
||||
$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
|
||||
$(DIST_INSTALL_DATA) $(srcdir)/$$p/* $(DIST_DIR)/$$p/; \
|
||||
mkdir $(DIST_DIR)/$$p; \
|
||||
cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
@@ -381,10 +337,10 @@ dist: dist-clean $(srcdir)/manifest.uuid
|
||||
|
||||
#========================================================================
|
||||
# Don't modify the file to clean here. Instead, set the "CLEANFILES"
|
||||
# variable in configure.ac
|
||||
# variable in configure.in
|
||||
#========================================================================
|
||||
|
||||
clean:
|
||||
clean:
|
||||
-test -z "$(BINARIES)" || rm -f $(BINARIES)
|
||||
-rm -f *.$(OBJEXT) core *.core
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
@@ -392,7 +348,7 @@ clean:
|
||||
distclean: clean
|
||||
-rm -f *.tab.c
|
||||
-rm -f $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log config.status
|
||||
-rm -f config.h config.cache config.log config.status
|
||||
|
||||
#========================================================================
|
||||
# Install binary object libraries. On Windows this includes both .dll and
|
||||
@@ -406,17 +362,25 @@ distclean: clean
|
||||
#========================================================================
|
||||
|
||||
install-lib-binaries: binaries
|
||||
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(pkglibdir)"
|
||||
@mkdir -p $(DESTDIR)$(pkglibdir)
|
||||
@list='$(lib_BINARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
$(INSTALL_LIBRARY) $$p "$(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
|
||||
stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
|
||||
if test "x$$stub" = "xstub"; then \
|
||||
echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
|
||||
else \
|
||||
echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
|
||||
fi; \
|
||||
ext=`echo $$p|sed -e "s/.*\.//"`; \
|
||||
if test "x$$ext" = "xdll"; then \
|
||||
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
|
||||
if test -f $$lib; then \
|
||||
echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
|
||||
$(INSTALL_DATA) $$lib "$(DESTDIR)$(pkglibdir)/$$lib"; \
|
||||
$(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
|
||||
fi; \
|
||||
fi; \
|
||||
fi; \
|
||||
@@ -425,12 +389,12 @@ install-lib-binaries: binaries
|
||||
if test -f $(srcdir)/$$p; then \
|
||||
destp=`basename $$p`; \
|
||||
echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$p "$(DESTDIR)$(pkglibdir)/$$destp"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
|
||||
fi; \
|
||||
done
|
||||
@if test "x$(SHARED_BUILD)" = "x1"; then \
|
||||
echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
|
||||
$(INSTALL_DATA) pkgIndex.tcl "$(DESTDIR)$(pkglibdir)"; \
|
||||
$(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
|
||||
fi
|
||||
|
||||
#========================================================================
|
||||
@@ -443,32 +407,33 @@ install-lib-binaries: binaries
|
||||
#========================================================================
|
||||
|
||||
install-bin-binaries: binaries
|
||||
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(bindir)"
|
||||
@mkdir -p $(DESTDIR)$(bindir)
|
||||
@list='$(bin_BINARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
|
||||
$(INSTALL_PROGRAM) $$p "$(DESTDIR)$(bindir)/$$p"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
.SUFFIXES: .c .$(OBJEXT)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
uninstall-binaries:
|
||||
list='$(lib_BINARIES)'; for p in $$list; do \
|
||||
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
rm -f $(DESTDIR)$(pkglibdir)/$$p; \
|
||||
done
|
||||
list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
|
||||
p=`basename $$p`; \
|
||||
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
|
||||
rm -f $(DESTDIR)$(pkglibdir)/$$p; \
|
||||
done
|
||||
list='$(bin_BINARIES)'; for p in $$list; do \
|
||||
rm -f "$(DESTDIR)$(bindir)/$$p"; \
|
||||
rm -f $(DESTDIR)$(bindir)/$$p; \
|
||||
done
|
||||
|
||||
.PHONY: all binaries clean depend distclean doc install libraries test
|
||||
.PHONY: gdb gdb-test valgrind valgrindshell
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
|
||||
+34
-60
@@ -2,9 +2,11 @@
|
||||
dnl This file is an input file used by the GNU "autoconf" program to
|
||||
dnl generate the file "configure", which is run during Tcl installation
|
||||
dnl to configure the system for the local environment.
|
||||
#
|
||||
# RCS: @(#) $Id: configure.in,v 1.43 2005/07/26 19:17:05 mdejong Exp $
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# Sample configure.ac for Tcl Extensions. The only places you should
|
||||
# Sample configure.in for Tcl Extensions. The only places you should
|
||||
# need to modify this file are marked by the string __CHANGE__
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
@@ -15,11 +17,9 @@ dnl to configure the system for the local environment.
|
||||
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
|
||||
# set as provided. These will also be added as -D defs in your Makefile
|
||||
# so you can encode the package version directly into the source files.
|
||||
# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
|
||||
# so that we create the export library with the dll.
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
AC_INIT([sqlite],[3.40.0])
|
||||
AC_INIT([sqlite], [3.7.4])
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
|
||||
@@ -27,7 +27,7 @@ AC_INIT([sqlite],[3.40.0])
|
||||
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
TEA_INIT()
|
||||
TEA_INIT([3.9])
|
||||
|
||||
AC_CONFIG_AUX_DIR(tclconfig)
|
||||
|
||||
@@ -55,8 +55,8 @@ TEA_PREFIX
|
||||
#-----------------------------------------------------------------------
|
||||
# Standard compiler checks.
|
||||
# This sets up CC by using the CC env var, or looks for gcc otherwise.
|
||||
# This also calls AC_PROG_CC and a few others to create the basic setup
|
||||
# necessary to compile executables.
|
||||
# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
|
||||
# the basic setup necessary to compile executables.
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
TEA_SETUP_COMPILER
|
||||
@@ -73,19 +73,11 @@ TEA_SETUP_COMPILER
|
||||
|
||||
TEA_ADD_SOURCES([tclsqlite3.c])
|
||||
TEA_ADD_HEADERS([])
|
||||
TEA_ADD_INCLUDES([])
|
||||
TEA_ADD_INCLUDES([-I\"`\${CYGPATH} \${srcdir}/generic`\"])
|
||||
TEA_ADD_LIBS([])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS5=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_GEOPOLY=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_MATH_FUNCTIONS=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DESERIALIZE=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBPAGE_VTAB=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_BYTECODE_VTAB=1])
|
||||
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
|
||||
TEA_ADD_STUB_SOURCES([])
|
||||
TEA_ADD_TCL_SOURCES([])
|
||||
|
||||
@@ -107,31 +99,6 @@ if test x$with_system_sqlite != xno; then
|
||||
LIBS="$LIBS -lsqlite3"])])
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# __CHANGE__
|
||||
#
|
||||
# You can add more files to clean if your extension creates any extra
|
||||
# files by extending CLEANFILES.
|
||||
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
|
||||
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
|
||||
#
|
||||
# A few miscellaneous platform-specific items:
|
||||
# TEA_ADD_* any platform specific compiler/build info here.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
|
||||
if test "${TEA_PLATFORM}" = "windows" ; then
|
||||
# Ensure no empty if clauses
|
||||
:
|
||||
#TEA_ADD_SOURCES([win/winFile.c])
|
||||
#TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
|
||||
else
|
||||
# Ensure no empty else clauses
|
||||
:
|
||||
#TEA_ADD_SOURCES([unix/unixFile.c])
|
||||
#TEA_ADD_LIBS([-lsuperfly])
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# __CHANGE__
|
||||
# Choose which headers you need. Extension authors should try very
|
||||
@@ -184,6 +151,28 @@ TEA_CONFIG_CFLAGS
|
||||
|
||||
TEA_ENABLE_SYMBOLS
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Everyone should be linking against the Tcl stub library. If you
|
||||
# can't for some reason, remove this definition. If you aren't using
|
||||
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
|
||||
# link against the non-stubbed Tcl library. Add Tk too if necessary.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
|
||||
#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Redefine fdatasync as fsync on systems that lack fdatasync
|
||||
#--------------------------------------------------------------------
|
||||
#
|
||||
#AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
|
||||
# Check for library functions that SQLite can optionally use.
|
||||
AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
|
||||
|
||||
AC_FUNC_STRERROR_R
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# This macro generates a line to use when building a library. It
|
||||
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
|
||||
@@ -204,24 +193,9 @@ TEA_PROG_TCLSH
|
||||
#TEA_PROG_WISH
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Setup a *Config.sh.in configuration file.
|
||||
# Finally, substitute all of the various values into the Makefile.
|
||||
# You may alternatively have a special pkgIndex.tcl.in or other files
|
||||
# which require substituting th AC variables in. Include these here.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
#TEA_EXPORT_CONFIG([sample])
|
||||
#AC_SUBST(SAMPLE_VAR)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Specify files to substitute AC variables in. You may alternatively
|
||||
# have a special pkgIndex.tcl.in or other files which require
|
||||
# substituting the AC variables in. Include these here.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
AC_CONFIG_FILES([Makefile pkgIndex.tcl])
|
||||
#AC_CONFIG_FILES([sampleConfig.sh])
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Finally, substitute all of the various values into the files
|
||||
# specified with AC_CONFIG_FILES.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
AC_OUTPUT
|
||||
AC_OUTPUT([Makefile pkgIndex.tcl])
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
# -*- tcl -*-
|
||||
# Tcl package index file, version 1.1
|
||||
#
|
||||
if {[package vsatisfies [package provide Tcl] 9.0-]} {
|
||||
package ifneeded sqlite3 @PACKAGE_VERSION@ \
|
||||
[list load [file join $dir @PKG_LIB_FILE9@] sqlite3]
|
||||
} else {
|
||||
package ifneeded sqlite3 @PACKAGE_VERSION@ \
|
||||
[list load [file join $dir @PKG_LIB_FILE8@] sqlite3]
|
||||
}
|
||||
# Tcl package index file
|
||||
#
|
||||
# Note sqlite*3* init specifically
|
||||
#
|
||||
package ifneeded sqlite3 @PACKAGE_VERSION@ \
|
||||
[list load [file join $dir @PKG_LIB_FILE@] Sqlite3]
|
||||
|
||||
+628
-527
File diff suppressed because it is too large
Load Diff
@@ -162,15 +162,18 @@ PROJECT = sqlite3
|
||||
|
||||
!if [echo REM = This file is generated from Makefile.vc > versions.vc]
|
||||
!endif
|
||||
# get project version from row "AC_INIT([sqlite], [3.x.y])"
|
||||
# get project version from row "AC_INIT([sqlite], [3.7.14])"
|
||||
!if [echo DOTVERSION = \>> versions.vc] \
|
||||
&& [nmakehlp -V ..\configure.ac AC_INIT >> versions.vc]
|
||||
&& [nmakehlp -V ..\configure.in AC_INIT >> versions.vc]
|
||||
!endif
|
||||
!include "versions.vc"
|
||||
|
||||
VERSION = $(DOTVERSION:.=)
|
||||
STUBPREFIX = $(PROJECT)stub
|
||||
|
||||
DLLOBJS = \
|
||||
$(TMP_DIR)\tclsqlite3.obj
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Target names and paths ( shouldn't need changing )
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -179,7 +182,7 @@ BINROOT = .
|
||||
ROOT = ..
|
||||
|
||||
PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
|
||||
PRJLIBNAME = $(PROJECT).$(EXT)
|
||||
PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
|
||||
PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
|
||||
|
||||
PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
|
||||
@@ -201,17 +204,6 @@ DOCDIR = $(ROOT)\doc
|
||||
TOOLSDIR = $(ROOT)\tools
|
||||
COMPATDIR = $(ROOT)\compat
|
||||
|
||||
### Figure out where the primary source code file(s) is/are.
|
||||
!if exist("$(ROOT)\..\..\sqlite3.c") && exist("$(ROOT)\..\..\src\tclsqlite.c")
|
||||
SQL_INCLUDES = -I"$(ROOT)\..\.."
|
||||
SQLITE_SRCDIR = $(ROOT)\..\..
|
||||
TCLSQLITE_SRCDIR = $(ROOT)\..\..\src
|
||||
DLLOBJS = $(TMP_DIR)\sqlite3.obj $(TMP_DIR)\tclsqlite.obj
|
||||
!else
|
||||
TCLSQLITE_SRCDIR = $(ROOT)\generic
|
||||
DLLOBJS = $(TMP_DIR)\tclsqlite3.obj
|
||||
!endif
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Compile flags
|
||||
#---------------------------------------------------------------------
|
||||
@@ -231,7 +223,7 @@ cdebug = -Z7 -WX -Od -GZ
|
||||
!endif
|
||||
|
||||
### Declarations common to all compiler options
|
||||
cflags = -nologo -c -W3 -D_CRT_SECURE_NO_WARNINGS -YX -Fp$(TMP_DIR)^\
|
||||
cflags = -nologo -c -W3 -YX -Fp$(TMP_DIR)^\
|
||||
|
||||
!if $(MSVCRT)
|
||||
!if $(DEBUG)
|
||||
@@ -247,22 +239,11 @@ crt = -MT
|
||||
!endif
|
||||
!endif
|
||||
|
||||
INCLUDES = $(SQL_INCLUDES) $(TCL_INCLUDES) -I"$(WINDIR)" \
|
||||
-I"$(GENERICDIR)" -I"$(ROOT)\.."
|
||||
INCLUDES = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" \
|
||||
-I"$(ROOT)\.."
|
||||
BASE_CLFAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES) \
|
||||
-DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
|
||||
-DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1 \
|
||||
-DSQLITE_ENABLE_FTS4=1 \
|
||||
-DSQLITE_ENABLE_FTS5=1 \
|
||||
-DSQLITE_3_SUFFIX_ONLY=1 \
|
||||
-DSQLITE_ENABLE_RTREE=1 \
|
||||
-DSQLITE_ENABLE_GEOPOLY=1 \
|
||||
-DSQLITE_ENABLE_MATH_FUNCTIONS=1 \
|
||||
-DSQLITE_ENABLE_DESERIALIZE=1 \
|
||||
-DSQLITE_ENABLE_DBPAGE_VTAB=1 \
|
||||
-DSQLITE_ENABLE_BYTECODE_VTAB=1 \
|
||||
-DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
|
||||
-DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1
|
||||
CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE -DSQLITE_ENABLE_FTS3=1
|
||||
TCL_CFLAGS = -DBUILD_sqlite -DUSE_TCL_STUBS \
|
||||
-DPACKAGE_VERSION="\"$(DOTVERSION)\"" $(BASE_CLFAGS) \
|
||||
@@ -360,17 +341,20 @@ $(PRJSTUBLIB): $(PRJSTUBOBJS)
|
||||
# Implicit rules
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
$(TMP_DIR)\sqlite3.obj: $(SQLITE_SRCDIR)\sqlite3.c
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
|
||||
-c $(SQLITE_SRCDIR)\sqlite3.c
|
||||
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
|
||||
$<
|
||||
<<
|
||||
|
||||
$(TMP_DIR)\tclsqlite.obj: $(TCLSQLITE_SRCDIR)\tclsqlite.c
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
|
||||
-c $(TCLSQLITE_SRCDIR)\tclsqlite.c
|
||||
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
|
||||
$<
|
||||
<<
|
||||
|
||||
$(TMP_DIR)\tclsqlite3.obj: $(TCLSQLITE_SRCDIR)\tclsqlite3.c
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
|
||||
-c $(TCLSQLITE_SRCDIR)\tclsqlite3.c
|
||||
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
|
||||
$(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
|
||||
$<
|
||||
<<
|
||||
|
||||
{$(WINDIR)}.rc{$(TMP_DIR)}.res:
|
||||
$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
|
||||
|
||||
+47
-168
@@ -14,10 +14,13 @@
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#include <windows.h>
|
||||
#ifdef _MSC_VER
|
||||
#define NO_SHLWAPI_GDI
|
||||
#define NO_SHLWAPI_STREAM
|
||||
#define NO_SHLWAPI_REG
|
||||
#include <shlwapi.h>
|
||||
#pragma comment (lib, "user32.lib")
|
||||
#pragma comment (lib, "kernel32.lib")
|
||||
#endif
|
||||
#pragma comment (lib, "shlwapi.lib")
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -36,15 +39,15 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* protos */
|
||||
|
||||
static int CheckForCompilerFeature(const char *option);
|
||||
static int CheckForLinkerFeature(char **options, int count);
|
||||
static int CheckForLinkerFeature(const char *option);
|
||||
static int IsIn(const char *string, const char *substring);
|
||||
static int SubstituteFile(const char *substs, const char *filename);
|
||||
static int QualifyPath(const char *path);
|
||||
static int LocateDependency(const char *keyfile);
|
||||
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
|
||||
static const char *GetVersionFromFile(const char *filename, const char *match);
|
||||
static DWORD WINAPI ReadFromPipe(LPVOID args);
|
||||
|
||||
/* globals */
|
||||
@@ -56,8 +59,8 @@ typedef struct {
|
||||
char buffer[STATICBUFFERSIZE];
|
||||
} pipeinfo;
|
||||
|
||||
pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
|
||||
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
|
||||
pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
|
||||
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
|
||||
|
||||
/*
|
||||
* exitcodes: 0 == no, 1 == yes, 2 == error
|
||||
@@ -71,7 +74,6 @@ main(
|
||||
char msg[300];
|
||||
DWORD dwWritten;
|
||||
int chars;
|
||||
const char *s;
|
||||
|
||||
/*
|
||||
* Make sure children (cl.exe and link.exe) are kept quiet.
|
||||
@@ -100,16 +102,16 @@ main(
|
||||
}
|
||||
return CheckForCompilerFeature(argv[2]);
|
||||
case 'l':
|
||||
if (argc < 3) {
|
||||
if (argc != 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
|
||||
"usage: %s -l <linker option>\n"
|
||||
"Tests for whether link.exe supports an option\n"
|
||||
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
return CheckForLinkerFeature(&argv[2], argc-2);
|
||||
return CheckForLinkerFeature(argv[2]);
|
||||
case 'f':
|
||||
if (argc == 2) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
@@ -151,13 +153,8 @@ main(
|
||||
&dwWritten, NULL);
|
||||
return 0;
|
||||
}
|
||||
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
|
||||
if (s && *s) {
|
||||
printf("%s\n", s);
|
||||
return 0;
|
||||
} else
|
||||
return 1; /* Version not found. Return non-0 exit code */
|
||||
|
||||
printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
|
||||
return 0;
|
||||
case 'Q':
|
||||
if (argc != 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
@@ -169,18 +166,6 @@ main(
|
||||
return 2;
|
||||
}
|
||||
return QualifyPath(argv[2]);
|
||||
|
||||
case 'L':
|
||||
if (argc != 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -L keypath\n"
|
||||
"Emit the fully qualified path of directory containing keypath\n"
|
||||
"exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
return LocateDependency(argv[2]);
|
||||
}
|
||||
}
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
@@ -275,7 +260,7 @@ CheckForCompilerFeature(
|
||||
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
|
||||
(300-chars), 0);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
|
||||
return 2;
|
||||
@@ -328,8 +313,7 @@ CheckForCompilerFeature(
|
||||
|
||||
static int
|
||||
CheckForLinkerFeature(
|
||||
char **options,
|
||||
int count)
|
||||
const char *option)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
@@ -338,8 +322,7 @@ CheckForLinkerFeature(
|
||||
char msg[300];
|
||||
BOOL ok;
|
||||
HANDLE hProcess, h, pipeThreads[2];
|
||||
int i;
|
||||
char cmdline[255];
|
||||
char cmdline[100];
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
|
||||
@@ -385,11 +368,7 @@ CheckForLinkerFeature(
|
||||
* Append our option for testing.
|
||||
*/
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
lstrcat(cmdline, " \"");
|
||||
lstrcat(cmdline, options[i]);
|
||||
lstrcat(cmdline, "\"");
|
||||
}
|
||||
lstrcat(cmdline, option);
|
||||
|
||||
ok = CreateProcess(
|
||||
NULL, /* Module name. */
|
||||
@@ -409,7 +388,7 @@ CheckForLinkerFeature(
|
||||
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
|
||||
(300-chars), 0);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
|
||||
return 2;
|
||||
@@ -454,9 +433,7 @@ CheckForLinkerFeature(
|
||||
return !(strstr(Out.buffer, "LNK1117") != NULL ||
|
||||
strstr(Err.buffer, "LNK1117") != NULL ||
|
||||
strstr(Out.buffer, "LNK4044") != NULL ||
|
||||
strstr(Err.buffer, "LNK4044") != NULL ||
|
||||
strstr(Out.buffer, "LNK4224") != NULL ||
|
||||
strstr(Err.buffer, "LNK4224") != NULL);
|
||||
strstr(Err.buffer, "LNK4044") != NULL);
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
@@ -502,9 +479,9 @@ IsIn(
|
||||
static const char *
|
||||
GetVersionFromFile(
|
||||
const char *filename,
|
||||
const char *match,
|
||||
int numdots)
|
||||
const char *match)
|
||||
{
|
||||
size_t cbBuffer = 100;
|
||||
static char szBuffer[100];
|
||||
char *szResult = NULL;
|
||||
FILE *fp = fopen(filename, "rt");
|
||||
@@ -514,17 +491,16 @@ GetVersionFromFile(
|
||||
* Read data until we see our match string.
|
||||
*/
|
||||
|
||||
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
|
||||
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
|
||||
LPSTR p, q;
|
||||
|
||||
p = strstr(szBuffer, match);
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* Skip to first digit after the match.
|
||||
* Skip to first digit.
|
||||
*/
|
||||
|
||||
p += strlen(match);
|
||||
while (*p && !isdigit((unsigned char)*p)) {
|
||||
while (*p && !isdigit(*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
@@ -533,13 +509,13 @@ GetVersionFromFile(
|
||||
*/
|
||||
|
||||
q = p;
|
||||
while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
|
||||
&& !strchr("ab", q[-1])) || --numdots))) {
|
||||
while (*q && (isalnum(*q) || *q == '.')) {
|
||||
++q;
|
||||
}
|
||||
|
||||
*q = 0;
|
||||
szResult = p;
|
||||
memcpy(szBuffer, p, q - p);
|
||||
szBuffer[q-p] = 0;
|
||||
szResult = szBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -562,7 +538,7 @@ typedef struct list_item_t {
|
||||
static list_item_t *
|
||||
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
|
||||
{
|
||||
list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
|
||||
list_item_t *itemPtr = malloc(sizeof(list_item_t));
|
||||
if (itemPtr) {
|
||||
itemPtr->key = strdup(key);
|
||||
itemPtr->value = strdup(value);
|
||||
@@ -611,7 +587,9 @@ SubstituteFile(
|
||||
const char *substitutions,
|
||||
const char *filename)
|
||||
{
|
||||
size_t cbBuffer = 1024;
|
||||
static char szBuffer[1024], szCopy[1024];
|
||||
char *szResult = NULL;
|
||||
list_item_t *substPtr = NULL;
|
||||
FILE *fp, *sp;
|
||||
|
||||
@@ -624,7 +602,7 @@ SubstituteFile(
|
||||
|
||||
sp = fopen(substitutions, "rt");
|
||||
if (sp != NULL) {
|
||||
while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
|
||||
while (fgets(szBuffer, cbBuffer, sp) != NULL) {
|
||||
unsigned char *ks, *ke, *vs, *ve;
|
||||
ks = (unsigned char*)szBuffer;
|
||||
while (ks && *ks && isspace(*ks)) ++ks;
|
||||
@@ -641,7 +619,7 @@ SubstituteFile(
|
||||
}
|
||||
|
||||
/* debug: dump the list */
|
||||
#ifndef NDEBUG
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
int n = 0;
|
||||
list_item_t *p = NULL;
|
||||
@@ -650,12 +628,12 @@ SubstituteFile(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Run the substitutions over each line of the input
|
||||
*/
|
||||
|
||||
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
|
||||
|
||||
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
|
||||
list_item_t *p = NULL;
|
||||
for (p = substPtr; p != NULL; p = p->nextPtr) {
|
||||
char *m = strstr(szBuffer, p->key);
|
||||
@@ -672,26 +650,15 @@ SubstituteFile(
|
||||
memcpy(szBuffer, szCopy, sizeof(szCopy));
|
||||
}
|
||||
}
|
||||
printf("%s", szBuffer);
|
||||
printf(szBuffer);
|
||||
}
|
||||
|
||||
|
||||
list_free(&substPtr);
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL FileExists(LPCTSTR szPath)
|
||||
{
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
#endif
|
||||
DWORD pathAttr = GetFileAttributes(szPath);
|
||||
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QualifyPath --
|
||||
*
|
||||
@@ -705,105 +672,17 @@ QualifyPath(
|
||||
const char *szPath)
|
||||
{
|
||||
char szCwd[MAX_PATH + 1];
|
||||
|
||||
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
|
||||
char szTmp[MAX_PATH + 1];
|
||||
char *p;
|
||||
GetCurrentDirectory(MAX_PATH, szCwd);
|
||||
while ((p = strchr(szPath, '/')) && *p)
|
||||
*p = '\\';
|
||||
PathCombine(szTmp, szCwd, szPath);
|
||||
PathCanonicalize(szCwd, szTmp);
|
||||
printf("%s\n", szCwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements LocateDependency for a single directory. See that command
|
||||
* for an explanation.
|
||||
* Returns 0 if found after printing the directory.
|
||||
* Returns 1 if not found but no errors.
|
||||
* Returns 2 on any kind of error
|
||||
* Basically, these are used as exit codes for the process.
|
||||
*/
|
||||
static int LocateDependencyHelper(const char *dir, const char *keypath)
|
||||
{
|
||||
HANDLE hSearch;
|
||||
char path[MAX_PATH+1];
|
||||
size_t dirlen;
|
||||
int keylen, ret;
|
||||
WIN32_FIND_DATA finfo;
|
||||
|
||||
if (dir == NULL || keypath == NULL)
|
||||
return 2; /* Have no real error reporting mechanism into nmake */
|
||||
dirlen = strlen(dir);
|
||||
if ((dirlen + 3) > sizeof(path))
|
||||
return 2;
|
||||
strncpy(path, dir, dirlen);
|
||||
strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
|
||||
keylen = strlen(keypath);
|
||||
|
||||
#if 0 /* This function is not available in Visual C++ 6 */
|
||||
/*
|
||||
* Use numerics 0 -> FindExInfoStandard,
|
||||
* 1 -> FindExSearchLimitToDirectories,
|
||||
* as these are not defined in Visual C++ 6
|
||||
*/
|
||||
hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
|
||||
#else
|
||||
hSearch = FindFirstFile(path, &finfo);
|
||||
#endif
|
||||
if (hSearch == INVALID_HANDLE_VALUE)
|
||||
return 1; /* Not found */
|
||||
|
||||
/* Loop through all subdirs checking if the keypath is under there */
|
||||
ret = 1; /* Assume not found */
|
||||
do {
|
||||
int sublen;
|
||||
/*
|
||||
* We need to check it is a directory despite the
|
||||
* FindExSearchLimitToDirectories in the above call. See SDK docs
|
||||
*/
|
||||
if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
continue;
|
||||
sublen = strlen(finfo.cFileName);
|
||||
if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
|
||||
continue; /* Path does not fit, assume not matched */
|
||||
strncpy(path+dirlen+1, finfo.cFileName, sublen);
|
||||
path[dirlen+1+sublen] = '\\';
|
||||
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
|
||||
if (FileExists(path)) {
|
||||
/* Found a match, print to stdout */
|
||||
path[dirlen+1+sublen] = '\0';
|
||||
QualifyPath(path);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
} while (FindNextFile(hSearch, &finfo));
|
||||
FindClose(hSearch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* LocateDependency --
|
||||
*
|
||||
* Locates a dependency for a package.
|
||||
* keypath - a relative path within the package directory
|
||||
* that is used to confirm it is the correct directory.
|
||||
* The search path for the package directory is currently only
|
||||
* the parent and grandparent of the current working directory.
|
||||
* If found, the command prints
|
||||
* name_DIRPATH=<full path of located directory>
|
||||
* and returns 0. If not found, does not print anything and returns 1.
|
||||
*/
|
||||
static int LocateDependency(const char *keypath)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
|
||||
|
||||
for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
|
||||
ret = LocateDependencyHelper(paths[i], keypath);
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: c
|
||||
|
||||
Vendored
+609
-733
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* sqlite_cfg.h.in. Generated from configure.ac by autoheader. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
@@ -45,16 +45,16 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `pread' function. */
|
||||
/* Define to 1 if you have the pread() function. */
|
||||
#undef HAVE_PREAD
|
||||
|
||||
/* Define to 1 if you have the `pread64' function. */
|
||||
/* Define to 1 if you have the pread64() function. */
|
||||
#undef HAVE_PREAD64
|
||||
|
||||
/* Define to 1 if you have the `pwrite' function. */
|
||||
/* Define to 1 if you have the pwrite() function. */
|
||||
#undef HAVE_PWRITE
|
||||
|
||||
/* Define to 1 if you have the `pwrite64' function. */
|
||||
/* Define to 1 if you have the pwrite64() function. */
|
||||
#undef HAVE_PWRITE64
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
@@ -63,7 +63,7 @@
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchrnul' function. */
|
||||
/* Define to 1 if you have the strchrnul() function */
|
||||
#undef HAVE_STRCHRNUL
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
@@ -99,12 +99,9 @@
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
/* Define to 1 if you have the utime() library function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#undef HAVE_ZLIB_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
@@ -121,20 +118,12 @@
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
Vendored
+1248
-1402
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.41.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.23.0.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.41.0'
|
||||
PACKAGE_STRING='sqlite 3.41.0'
|
||||
PACKAGE_VERSION='3.23.0'
|
||||
PACKAGE_STRING='sqlite 3.23.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -770,7 +770,6 @@ ac_includes_default="\
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
BUILD_CFLAGS
|
||||
AMALGAMATION_LINE_MACROS
|
||||
USE_GCOV
|
||||
OPT_FEATURE_FLAGS
|
||||
HAVE_ZLIB
|
||||
@@ -800,6 +799,7 @@ TEMP_STORE
|
||||
ALLOWRELEASE
|
||||
SQLITE_THREADSAFE
|
||||
BUILD_CC
|
||||
VERSION_NUMBER
|
||||
RELEASE
|
||||
VERSION
|
||||
program_prefix
|
||||
@@ -904,16 +904,13 @@ with_readline_inc
|
||||
enable_debug
|
||||
enable_amalgamation
|
||||
enable_load_extension
|
||||
enable_math
|
||||
enable_json
|
||||
enable_all
|
||||
enable_memsys5
|
||||
enable_memsys3
|
||||
enable_fts3
|
||||
enable_fts4
|
||||
enable_fts5
|
||||
enable_json1
|
||||
enable_update_limit
|
||||
enable_geopoly
|
||||
enable_rtree
|
||||
enable_session
|
||||
enable_gcov
|
||||
@@ -1468,7 +1465,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.41.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.23.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1533,7 +1530,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.41.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.23.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1559,16 +1556,13 @@ Optional Features:
|
||||
separately
|
||||
--disable-load-extension
|
||||
Disable loading of external extensions
|
||||
--disable-math Disable math functions
|
||||
--disable-json Disable JSON functions
|
||||
--enable-all Enable FTS4, FTS5, Geopoly, RTree, Sessions
|
||||
--enable-memsys5 Enable MEMSYS5
|
||||
--enable-memsys3 Enable MEMSYS3
|
||||
--enable-fts3 Enable the FTS3 extension
|
||||
--enable-fts4 Enable the FTS4 extension
|
||||
--enable-fts5 Enable the FTS5 extension
|
||||
--enable-json1 Enable the JSON1 extension
|
||||
--enable-update-limit Enable the UPDATE/DELETE LIMIT clause
|
||||
--enable-geopoly Enable the GEOPOLY extension
|
||||
--enable-rtree Enable the RTREE extension
|
||||
--enable-session Enable the SESSION extension
|
||||
--enable-gcov Enable coverage testing using gcov
|
||||
@@ -1661,7 +1655,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.41.0
|
||||
sqlite configure 3.23.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2080,7 +2074,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.41.0, which was
|
||||
It was created by sqlite $as_me 3.23.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3938,13 +3932,13 @@ if ${lt_cv_nm_interface+:} false; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:3941: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:3935: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3944: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:3938: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3947: output\"" >&5)
|
||||
(eval echo "\"\$as_me:3941: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@@ -5150,7 +5144,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5153 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5147 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -6675,11 +6669,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6678: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6672: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6682: \$? = $ac_status" >&5
|
||||
echo "$as_me:6676: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7014,11 +7008,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7017: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7011: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7021: \$? = $ac_status" >&5
|
||||
echo "$as_me:7015: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7119,11 +7113,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7122: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7116: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7126: \$? = $ac_status" >&5
|
||||
echo "$as_me:7120: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -7174,11 +7168,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7177: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7171: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7181: \$? = $ac_status" >&5
|
||||
echo "$as_me:7175: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -9554,7 +9548,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9557 "configure"
|
||||
#line 9551 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -9650,7 +9644,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9653 "configure"
|
||||
#line 9647 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -10367,10 +10361,8 @@ fi
|
||||
if test "x${TCLLIBDIR+set}" != "xset" ; then
|
||||
TCLLIBDIR='$(libdir)'
|
||||
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
|
||||
if test -d $i ; then
|
||||
TCLLIBDIR=$i
|
||||
break
|
||||
fi
|
||||
TCLLIBDIR=$i
|
||||
break
|
||||
done
|
||||
TCLLIBDIR="${TCLLIBDIR}/sqlite3"
|
||||
fi
|
||||
@@ -10392,6 +10384,12 @@ RELEASE=`cat $srcdir/VERSION`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Release set to $RELEASE" >&5
|
||||
$as_echo "$as_me: Release set to $RELEASE" >&6;}
|
||||
|
||||
VERSION_NUMBER=`cat $srcdir/VERSION \
|
||||
| sed 's/[^0-9]/ /g' \
|
||||
| awk '{printf "%d%03d%03d",$1,$2,$3}'`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Version number set to $VERSION_NUMBER" >&5
|
||||
$as_echo "$as_me: Version number set to $VERSION_NUMBER" >&6;}
|
||||
|
||||
|
||||
#########
|
||||
# Locate a compiler for the build machine. This compiler should
|
||||
@@ -10457,6 +10455,8 @@ fi
|
||||
# Check whether --enable-threadsafe was given.
|
||||
if test "${enable_threadsafe+set}" = set; then :
|
||||
enableval=$enable_threadsafe;
|
||||
else
|
||||
enable_threadsafe=yes
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5
|
||||
@@ -11249,19 +11249,15 @@ fi
|
||||
# check for debug enabled
|
||||
# Check whether --enable-debug was given.
|
||||
if test "${enable_debug+set}" = set; then :
|
||||
enableval=$enable_debug;
|
||||
enableval=$enable_debug; use_debug=$enableval
|
||||
else
|
||||
use_debug=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5
|
||||
$as_echo_n "checking build type... " >&6; }
|
||||
if test "${enable_debug}" = "yes" ; then
|
||||
if test "${use_debug}" = "yes" ; then
|
||||
TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5
|
||||
$as_echo "debug" >&6; }
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5
|
||||
$as_echo "release" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
@@ -11269,10 +11265,12 @@ fi
|
||||
# See whether we should use the amalgamation to build
|
||||
# Check whether --enable-amalgamation was given.
|
||||
if test "${enable_amalgamation+set}" = set; then :
|
||||
enableval=$enable_amalgamation;
|
||||
enableval=$enable_amalgamation; use_amalgamation=$enableval
|
||||
else
|
||||
use_amalgamation=yes
|
||||
fi
|
||||
|
||||
if test "${enable_amalgamation}" = "no" ; then
|
||||
if test "${use_amalgamation}" != "yes" ; then
|
||||
USE_AMALGAMATION=0
|
||||
fi
|
||||
|
||||
@@ -11355,12 +11353,12 @@ fi
|
||||
# See whether we should allow loadable extensions
|
||||
# Check whether --enable-load-extension was given.
|
||||
if test "${enable_load_extension+set}" = set; then :
|
||||
enableval=$enable_load_extension;
|
||||
enableval=$enable_load_extension; use_loadextension=$enableval
|
||||
else
|
||||
enable_load_extension=yes
|
||||
use_loadextension=yes
|
||||
fi
|
||||
|
||||
if test "${enable_load_extension}" = "yes" ; then
|
||||
if test "${use_loadextension}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS=""
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
|
||||
$as_echo_n "checking for library containing dlopen... " >&6; }
|
||||
@@ -11422,115 +11420,14 @@ else
|
||||
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support math functions
|
||||
#
|
||||
# Check whether --enable-math was given.
|
||||
if test "${enable_math+set}" = set; then :
|
||||
enableval=$enable_math;
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5
|
||||
$as_echo_n "checking whether to support math functions... " >&6; }
|
||||
if test "$enable_math" = "no"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5
|
||||
$as_echo_n "checking for library containing ceil... " >&6; }
|
||||
if ${ac_cv_search_ceil+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char ceil ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return ceil ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' m; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_ceil=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_ceil+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_ceil+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_ceil=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5
|
||||
$as_echo "$ac_cv_search_ceil" >&6; }
|
||||
ac_res=$ac_cv_search_ceil
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support JSON functions
|
||||
#
|
||||
# Check whether --enable-json was given.
|
||||
if test "${enable_json+set}" = set; then :
|
||||
enableval=$enable_json;
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON functions" >&5
|
||||
$as_echo_n "checking whether to support JSON functions... " >&6; }
|
||||
if test "$enable_json" = "no"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON"
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
fi
|
||||
|
||||
########
|
||||
# The --enable-all argument is short-hand to enable
|
||||
# multiple extensions.
|
||||
# Check whether --enable-all was given.
|
||||
if test "${enable_all+set}" = set; then :
|
||||
enableval=$enable_all;
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
# Do we want to support memsys3 and/or memsys5
|
||||
#
|
||||
# Check whether --enable-memsys5 was given.
|
||||
if test "${enable_memsys5+set}" = set; then :
|
||||
enableval=$enable_memsys5;
|
||||
enableval=$enable_memsys5; enable_memsys5=yes
|
||||
else
|
||||
enable_memsys5=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
|
||||
@@ -11545,7 +11442,9 @@ $as_echo "no" >&6; }
|
||||
fi
|
||||
# Check whether --enable-memsys3 was given.
|
||||
if test "${enable_memsys3+set}" = set; then :
|
||||
enableval=$enable_memsys3;
|
||||
enableval=$enable_memsys3; enable_memsys3=yes
|
||||
else
|
||||
enable_memsys3=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
|
||||
@@ -11563,29 +11462,22 @@ fi
|
||||
# See whether we should enable Full Text Search extensions
|
||||
# Check whether --enable-fts3 was given.
|
||||
if test "${enable_fts3+set}" = set; then :
|
||||
enableval=$enable_fts3;
|
||||
enableval=$enable_fts3; enable_fts3=yes
|
||||
else
|
||||
enable_fts3=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS3" >&5
|
||||
$as_echo_n "checking whether to support FTS3... " >&6; }
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
# Check whether --enable-fts4 was given.
|
||||
if test "${enable_fts4+set}" = set; then :
|
||||
enableval=$enable_fts4;
|
||||
enableval=$enable_fts4; enable_fts4=yes
|
||||
else
|
||||
enable_fts4=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS4" >&5
|
||||
$as_echo_n "checking whether to support FTS4... " >&6; }
|
||||
if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
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; }
|
||||
@@ -11643,20 +11535,15 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
# Check whether --enable-fts5 was given.
|
||||
if test "${enable_fts5+set}" = set; then :
|
||||
enableval=$enable_fts5;
|
||||
enableval=$enable_fts5; enable_fts5=yes
|
||||
else
|
||||
enable_fts5=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS5" >&5
|
||||
$as_echo_n "checking whether to support FTS5... " >&6; }
|
||||
if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
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; }
|
||||
@@ -11714,9 +11601,19 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable JSON1
|
||||
# Check whether --enable-json1 was given.
|
||||
if test "${enable_json1+set}" = set; then :
|
||||
enableval=$enable_json1; enable_json1=yes
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
enable_json1=no
|
||||
fi
|
||||
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11724,76 +11621,40 @@ fi
|
||||
# statements.
|
||||
# Check whether --enable-update-limit was given.
|
||||
if test "${enable_update_limit+set}" = set; then :
|
||||
enableval=$enable_update_limit;
|
||||
enableval=$enable_update_limit; enable_udlimit=yes
|
||||
else
|
||||
enable_udlimit=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support LIMIT on UPDATE and DELETE statements" >&5
|
||||
$as_echo_n "checking whether to support LIMIT on UPDATE and DELETE statements... " >&6; }
|
||||
if test "${enable_update_limit}" = "yes" ; then
|
||||
if test "${enable_udlimit}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable GEOPOLY
|
||||
# Check whether --enable-geopoly was given.
|
||||
if test "${enable_geopoly+set}" = set; then :
|
||||
enableval=$enable_geopoly; enable_geopoly=yes
|
||||
else
|
||||
enable_geopoly=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support GEOPOLY" >&5
|
||||
$as_echo_n "checking whether to support GEOPOLY... " >&6; }
|
||||
if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
|
||||
enable_rtree=yes
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable RTREE
|
||||
# Check whether --enable-rtree was given.
|
||||
if test "${enable_rtree+set}" = set; then :
|
||||
enableval=$enable_rtree;
|
||||
enableval=$enable_rtree; enable_rtree=yes
|
||||
else
|
||||
enable_rtree=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support RTREE" >&5
|
||||
$as_echo_n "checking whether to support RTREE... " >&6; }
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable the SESSION extension
|
||||
# Check whether --enable-session was given.
|
||||
if test "${enable_session+set}" = set; then :
|
||||
enableval=$enable_session;
|
||||
enableval=$enable_session; enable_session=yes
|
||||
else
|
||||
enable_session=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support SESSION" >&5
|
||||
$as_echo_n "checking whether to support SESSION... " >&6; }
|
||||
if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -11851,7 +11712,9 @@ BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS
|
||||
# See whether we should use GCOV
|
||||
# Check whether --enable-gcov was given.
|
||||
if test "${enable_gcov+set}" = set; then :
|
||||
enableval=$enable_gcov;
|
||||
enableval=$enable_gcov; use_gcov=$enableval
|
||||
else
|
||||
use_gcov=no
|
||||
fi
|
||||
|
||||
if test "${use_gcov}" = "yes" ; then
|
||||
@@ -11861,21 +11724,10 @@ else
|
||||
fi
|
||||
|
||||
|
||||
#########
|
||||
# Enable/disabled amalagamation line macros
|
||||
########
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=0
|
||||
if test "${amalgamation_line_macros}" = "yes" ; then
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=1
|
||||
fi
|
||||
if test "${amalgamation_line_macros}" = "no" ; then
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=0
|
||||
fi
|
||||
|
||||
|
||||
#########
|
||||
# Output the config header
|
||||
ac_config_headers="$ac_config_headers sqlite_cfg.h"
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
|
||||
#########
|
||||
@@ -12390,7 +12242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.41.0, which was
|
||||
This file was extended by sqlite $as_me 3.23.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12456,7 +12308,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.41.0
|
||||
sqlite config.status 3.23.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -12838,7 +12690,7 @@ for ac_config_target in $ac_config_targets
|
||||
do
|
||||
case $ac_config_target in
|
||||
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
|
||||
"sqlite_cfg.h") CONFIG_HEADERS="$CONFIG_HEADERS sqlite_cfg.h" ;;
|
||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;;
|
||||
|
||||
|
||||
+49
-110
@@ -134,10 +134,8 @@ AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin])
|
||||
if test "x${TCLLIBDIR+set}" != "xset" ; then
|
||||
TCLLIBDIR='$(libdir)'
|
||||
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
|
||||
if test -d $i ; then
|
||||
TCLLIBDIR=$i
|
||||
break
|
||||
fi
|
||||
TCLLIBDIR=$i
|
||||
break
|
||||
done
|
||||
TCLLIBDIR="${TCLLIBDIR}/sqlite3"
|
||||
fi
|
||||
@@ -157,6 +155,11 @@ AC_SUBST(VERSION)
|
||||
RELEASE=`cat $srcdir/VERSION`
|
||||
AC_MSG_NOTICE(Release set to $RELEASE)
|
||||
AC_SUBST(RELEASE)
|
||||
VERSION_NUMBER=[`cat $srcdir/VERSION \
|
||||
| sed 's/[^0-9]/ /g' \
|
||||
| awk '{printf "%d%03d%03d",$1,$2,$3}'`]
|
||||
AC_MSG_NOTICE(Version number set to $VERSION_NUMBER)
|
||||
AC_SUBST(VERSION_NUMBER)
|
||||
|
||||
#########
|
||||
# Locate a compiler for the build machine. This compiler should
|
||||
@@ -179,7 +182,7 @@ AC_SUBST(BUILD_CC)
|
||||
# Do we want to support multithreaded use of sqlite
|
||||
#
|
||||
AC_ARG_ENABLE(threadsafe,
|
||||
AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]))
|
||||
AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]),,enable_threadsafe=yes)
|
||||
AC_MSG_CHECKING([whether to support threadsafe operation])
|
||||
if test "$enable_threadsafe" = "no"; then
|
||||
SQLITE_THREADSAFE=0
|
||||
@@ -554,22 +557,21 @@ AC_SEARCH_LIBS(fdatasync, [rt])
|
||||
|
||||
#########
|
||||
# check for debug enabled
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]))
|
||||
AC_MSG_CHECKING([build type])
|
||||
if test "${enable_debug}" = "yes" ; then
|
||||
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 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
|
||||
AC_MSG_RESULT([debug])
|
||||
else
|
||||
TARGET_DEBUG="-DNDEBUG"
|
||||
AC_MSG_RESULT([release])
|
||||
fi
|
||||
AC_SUBST(TARGET_DEBUG)
|
||||
|
||||
#########
|
||||
# See whether we should use the amalgamation to build
|
||||
AC_ARG_ENABLE(amalgamation, AC_HELP_STRING([--disable-amalgamation],
|
||||
[Disable the amalgamation and instead build all files separately]))
|
||||
if test "${enable_amalgamation}" = "no" ; then
|
||||
[Disable the amalgamation and instead build all files separately]),
|
||||
[use_amalgamation=$enableval],[use_amalgamation=yes])
|
||||
if test "${use_amalgamation}" != "yes" ; then
|
||||
USE_AMALGAMATION=0
|
||||
fi
|
||||
AC_SUBST(USE_AMALGAMATION)
|
||||
@@ -583,52 +585,21 @@ AC_SUBST(HAVE_ZLIB)
|
||||
#########
|
||||
# See whether we should allow loadable extensions
|
||||
AC_ARG_ENABLE(load-extension, AC_HELP_STRING([--disable-load-extension],
|
||||
[Disable loading of external extensions]),,[enable_load_extension=yes])
|
||||
if test "${enable_load_extension}" = "yes" ; then
|
||||
[Disable loading of external extensions]),
|
||||
[use_loadextension=$enableval],[use_loadextension=yes])
|
||||
if test "${use_loadextension}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS=""
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
else
|
||||
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support math functions
|
||||
#
|
||||
AC_ARG_ENABLE(math,
|
||||
AC_HELP_STRING([--disable-math],[Disable math functions]))
|
||||
AC_MSG_CHECKING([whether to support math functions])
|
||||
if test "$enable_math" = "no"; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS"
|
||||
AC_SEARCH_LIBS(ceil, m)
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support JSON functions
|
||||
#
|
||||
AC_ARG_ENABLE(json,
|
||||
AC_HELP_STRING([--disable-json],[Disable JSON functions]))
|
||||
AC_MSG_CHECKING([whether to support JSON functions])
|
||||
if test "$enable_json" = "no"; then
|
||||
AC_MSG_RESULT([no])
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON"
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
########
|
||||
# The --enable-all argument is short-hand to enable
|
||||
# multiple extensions.
|
||||
AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all],
|
||||
[Enable FTS4, FTS5, Geopoly, RTree, Sessions]))
|
||||
|
||||
##########
|
||||
# Do we want to support memsys3 and/or memsys5
|
||||
#
|
||||
AC_ARG_ENABLE(memsys5,
|
||||
AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]))
|
||||
AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),
|
||||
[enable_memsys5=yes],[enable_memsys5=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS5])
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
|
||||
@@ -637,7 +608,8 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_ARG_ENABLE(memsys3,
|
||||
AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]))
|
||||
AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),
|
||||
[enable_memsys3=yes],[enable_memsys3=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS3])
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
|
||||
@@ -649,85 +621,62 @@ fi
|
||||
#########
|
||||
# See whether we should enable Full Text Search extensions
|
||||
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
|
||||
[Enable the FTS3 extension]))
|
||||
AC_MSG_CHECKING([whether to support FTS3])
|
||||
[Enable the FTS3 extension]),
|
||||
[enable_fts3=yes],[enable_fts3=no])
|
||||
if test "${enable_fts3}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
|
||||
[Enable the FTS4 extension]))
|
||||
AC_MSG_CHECKING([whether to support FTS4])
|
||||
if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
AC_MSG_RESULT([yes])
|
||||
[Enable the FTS4 extension]),
|
||||
[enable_fts4=yes],[enable_fts4=no])
|
||||
if test "${enable_fts4}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
|
||||
[Enable the FTS5 extension]))
|
||||
AC_MSG_CHECKING([whether to support FTS5])
|
||||
if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
AC_MSG_RESULT([yes])
|
||||
[Enable the FTS5 extension]),
|
||||
[enable_fts5=yes],[enable_fts5=no])
|
||||
if test "${enable_fts5}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
|
||||
AC_SEARCH_LIBS([log],[m])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable JSON1
|
||||
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
|
||||
[Enable the JSON1 extension]),
|
||||
[enable_json1=yes],[enable_json1=no])
|
||||
if test "${enable_json1}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable the LIMIT clause on UPDATE and DELETE
|
||||
# statements.
|
||||
AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit],
|
||||
[Enable the UPDATE/DELETE LIMIT clause]))
|
||||
AC_MSG_CHECKING([whether to support LIMIT on UPDATE and DELETE statements])
|
||||
if test "${enable_update_limit}" = "yes" ; then
|
||||
[Enable the UPDATE/DELETE LIMIT clause]),
|
||||
[enable_udlimit=yes],[enable_udlimit=no])
|
||||
if test "${enable_udlimit}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable GEOPOLY
|
||||
AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
|
||||
[Enable the GEOPOLY extension]),
|
||||
[enable_geopoly=yes],[enable_geopoly=no])
|
||||
AC_MSG_CHECKING([whether to support GEOPOLY])
|
||||
if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
|
||||
enable_rtree=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable RTREE
|
||||
AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
|
||||
[Enable the RTREE extension]))
|
||||
AC_MSG_CHECKING([whether to support RTREE])
|
||||
[Enable the RTREE extension]),
|
||||
[enable_rtree=yes],[enable_rtree=no])
|
||||
if test "${enable_rtree}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable the SESSION extension
|
||||
AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
|
||||
[Enable the SESSION extension]))
|
||||
AC_MSG_CHECKING([whether to support SESSION])
|
||||
if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then
|
||||
[Enable the SESSION extension]),
|
||||
[enable_session=yes],[enable_session=no])
|
||||
if test "${enable_session}" = "yes" ; then
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
|
||||
OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
@@ -784,7 +733,8 @@ BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS
|
||||
#########
|
||||
# See whether we should use GCOV
|
||||
AC_ARG_ENABLE(gcov, AC_HELP_STRING([--enable-gcov],
|
||||
[Enable coverage testing using gcov]))
|
||||
[Enable coverage testing using gcov]),
|
||||
[use_gcov=$enableval],[use_gcov=no])
|
||||
if test "${use_gcov}" = "yes" ; then
|
||||
USE_GCOV=1
|
||||
else
|
||||
@@ -792,21 +742,10 @@ else
|
||||
fi
|
||||
AC_SUBST(USE_GCOV)
|
||||
|
||||
#########
|
||||
# Enable/disabled amalagamation line macros
|
||||
########
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=0
|
||||
if test "${amalgamation_line_macros}" = "yes" ; then
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=1
|
||||
fi
|
||||
if test "${amalgamation_line_macros}" = "no" ; then
|
||||
AMALGAMATION_LINE_MACROS=--linemacros=0
|
||||
fi
|
||||
AC_SUBST(AMALGAMATION_LINE_MACROS)
|
||||
|
||||
#########
|
||||
# Output the config header
|
||||
AC_CONFIG_HEADERS(sqlite_cfg.h)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
#########
|
||||
# Generate the output files.
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
SQLite's OS layer contains the following definitions used in F2FS related
|
||||
calls:
|
||||
|
||||
#define F2FS_IOCTL_MAGIC 0xf5
|
||||
#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
|
||||
#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
|
||||
#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
|
||||
#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
|
||||
#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32)
|
||||
#define F2FS_FEATURE_ATOMIC_WRITE 0x0004
|
||||
|
||||
After opening a database file on Linux (including Android), SQLite determines
|
||||
whether or not a file supports F2FS atomic commits as follows:
|
||||
|
||||
u32 flags = 0;
|
||||
rc = ioctl(fd, F2FS_IOC_GET_FEATURES, &flags);
|
||||
if( rc==0 && (flags & F2FS_FEATURE_ATOMIC_WRITE) ){
|
||||
/* File supports F2FS atomic commits */
|
||||
}else{
|
||||
/* File does NOT support F2FS atomic commits */
|
||||
}
|
||||
|
||||
where "fd" is the file-descriptor open on the database file.
|
||||
|
||||
Usually, when writing to a database file that supports atomic commits, SQLite
|
||||
accumulates the entire transaction in heap memory, deferring all writes to the
|
||||
db file until the transaction is committed.
|
||||
|
||||
When it is time to commit a transaction on a file that supports atomic
|
||||
commits, SQLite does:
|
||||
|
||||
/* Take an F_WRLCK lock on the database file. This prevents any other
|
||||
** SQLite clients from reading or writing the file until the lock
|
||||
** is released. */
|
||||
rc = fcntl(fd, F_SETLK, ...);
|
||||
if( rc!=0 ) goto failed;
|
||||
|
||||
rc = ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE);
|
||||
if( rc!=0 ) goto fallback_to_legacy_journal_commit;
|
||||
|
||||
foreach (dirty page){
|
||||
rc = write(fd, ...dirty page...);
|
||||
if( rc!=0 ){
|
||||
ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE);
|
||||
goto fallback_to_legacy_journal_commit;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE);
|
||||
if( rc!=0 ){
|
||||
ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE);
|
||||
goto fallback_to_legacy_journal_commit;
|
||||
}
|
||||
|
||||
/* If we get there, the transaction has been successfully
|
||||
** committed to persistent storage. The following call
|
||||
** relinquishes the F_WRLCK lock. */
|
||||
fcntl(fd, F_SETLK, ...);
|
||||
|
||||
Assumptions:
|
||||
|
||||
1. After either of the F2FS_IOC_ABORT_VOLATILE_WRITE calls return,
|
||||
the database file is in the state that it was in before
|
||||
F2FS_IOC_START_ATOMIC_WRITE was invoked. Even if the ioctl()
|
||||
fails - we're ignoring the return code.
|
||||
|
||||
This is true regardless of the type of error that occurred in
|
||||
ioctl() or write().
|
||||
|
||||
2. If the system fails before the F2FS_IOC_COMMIT_ATOMIC_WRITE is
|
||||
completed, then following a reboot the database file is in the
|
||||
state that it was in before F2FS_IOC_START_ATOMIC_WRITE was invoked.
|
||||
Or, if the write was commited right before the system failed, in a
|
||||
state indicating that all write() calls were successfully committed
|
||||
to persistent storage before the failure occurred.
|
||||
|
||||
3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is
|
||||
completed then the file is automatically restored to the state that
|
||||
it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs
|
||||
before the posix advisory lock is automatically dropped - there is
|
||||
no chance that another client will be able to read the file in a
|
||||
half-committed state before the rollback operation occurs.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# JSON Functions Enhancements (2022)
|
||||
|
||||
This document summaries enhancements to the SQLite JSON support added in
|
||||
early 2022.
|
||||
|
||||
## 1.0 Change summary:
|
||||
|
||||
1. New **->** and **->>** operators that work like MySQL and PostgreSQL (PG).
|
||||
2. JSON functions are built-in rather than being an extension. They
|
||||
are included by default, but can be omitted using the
|
||||
-DSQLITE_OMIT_JSON compile-time option.
|
||||
|
||||
|
||||
## 2.0 New operators **->** and **->>**
|
||||
|
||||
The SQLite language adds two new binary operators **->** and **->>**.
|
||||
Both operators are similar to json_extract(). The left operand is
|
||||
JSON and the right operand is a JSON path expression (possibly abbreviated
|
||||
for compatibility with PG - see below). So they are similar to a
|
||||
two-argument call to json_extract().
|
||||
|
||||
The difference between -> and ->> (and json_extract()) is as follows:
|
||||
|
||||
* The -> operator always returns JSON.
|
||||
|
||||
* The ->> operator converts the answer into a primitive SQL datatype
|
||||
such as TEXT, INTEGER, REAL, or NULL. If a JSON object or array
|
||||
is selected, that object or array is rendered as text. If a JSON
|
||||
value is selected, that value is converted into its corresponding
|
||||
SQL type
|
||||
|
||||
* The json_extract() interface returns JSON when a JSON object or
|
||||
array is selected, or a primitive SQL datatype when a JSON value
|
||||
is selected. This is different from MySQL, in which json_extract()
|
||||
always returns JSON, but the difference is retained because it has
|
||||
worked that way for 6 years and changing it now would likely break
|
||||
a lot of legacy code.
|
||||
|
||||
In MySQL and PG, the ->> operator always returns TEXT (or NULL) and never
|
||||
INTEGER or REAL. This is due to limitations in the type handling capabilities
|
||||
of those systems. In MySQL and PG, the result type a function or operator
|
||||
may only depend on the type of its arguments, never the value of its arguments.
|
||||
But the underlying JSON type depends on the value of the JSON path
|
||||
expression, not the type of the JSON path expression (which is always TEXT).
|
||||
Hence, the result type of ->> in MySQL and PG is unable to vary according
|
||||
to the type of the JSON value being extracted.
|
||||
|
||||
The type system in SQLite is more general. Functions in SQLite are able
|
||||
to return different datatypes depending on the value of their arguments.
|
||||
So the ->> operator in SQLite is able to return TEXT, INTEGER, REAL, or NULL
|
||||
depending on the JSON type of the value being extracted. This means that
|
||||
the behavior of the ->> is slightly different in SQLite versus MySQL and PG
|
||||
in that it will sometimes return INTEGER and REAL values, depending on its
|
||||
inputs. It is possible to implement the ->> operator in SQLite so that it
|
||||
always operates exactly like MySQL and PG and always returns TEXT or NULL,
|
||||
but I have been unable to think of any situations where returning the
|
||||
actual JSON value this would cause problems, so I'm including the enhanced
|
||||
functionality in SQLite.
|
||||
|
||||
The table below attempts to summarize the differences between the
|
||||
-> and ->> operators and the json_extract() function, for SQLite, MySQL,
|
||||
and PG. JSON values are shown using their SQL text representation but
|
||||
in a bold font.
|
||||
|
||||
|
||||
<table border=1 cellpadding=5 cellspacing=0>
|
||||
<tr><th>JSON<th>PATH<th>-> operator<br>(all)<th>->> operator<br>(MySQL/PG)
|
||||
<th>->> operator<br>(SQLite)<th>json_extract()<br>(SQLite)
|
||||
<tr><td> **'{"a":123}'** <td>'$.a'<td> **'123'** <td> '123' <td> 123 <td> 123
|
||||
<tr><td> **'{"a":4.5}'** <td>'$.a'<td> **'4.5'** <td> '4.5' <td> 4.5 <td> 4.5
|
||||
<tr><td> **'{"a":"xyz"}'** <td>'$.a'<td> **'"xyz"'** <td> 'xyz' <td> 'xyz' <td> 'xyz'
|
||||
<tr><td> **'{"a":null}'** <td>'$.a'<td> **'null'** <td> NULL <td> NULL <td> NULL
|
||||
<tr><td> **'{"a":[6,7,8]}'** <td>'$.a'<td> **'[6,7,8]'** <td> '[6,7,8]' <td> '[6,7,8]' <td> **'[6,7,8]'**
|
||||
<tr><td> **'{"a":{"x":9}}'** <td>'$.a'<td> **'{"x":9}'** <td> '{"x":9}' <td> '{"x":9}' <td> **'{"x":9}'**
|
||||
<tr><td> **'{"b":999}'** <td>'$.a'<td> NULL <td> NULL <td> NULL <td> NULL
|
||||
</table>
|
||||
|
||||
Important points about the table above:
|
||||
|
||||
* The -> operator always returns either JSON or NULL.
|
||||
|
||||
* The ->> operator never returns JSON. It always returns TEXT or NULL, or in the
|
||||
case of SQLite, INTEGER or REAL.
|
||||
|
||||
* The MySQL json_extract() function works exactly the same
|
||||
as the MySQL -> operator.
|
||||
|
||||
* The SQLite json_extract() operator works like -> for JSON objects and
|
||||
arrays, and like ->> for JSON values.
|
||||
|
||||
* The -> operator works the same for all systems.
|
||||
|
||||
* The only difference in ->> between SQLite and other systems is that
|
||||
when the JSON value is numeric, SQLite returns a numeric SQL value,
|
||||
whereas the other systems return a text representation of the numeric
|
||||
value.
|
||||
|
||||
### 2.1 Abbreviated JSON path expressions for PG compatibility
|
||||
|
||||
The table above always shows the full JSON path expression: '$.a'. But
|
||||
PG does not accept this syntax. PG only allows a single JSON object label
|
||||
name or a single integer array index. In order to provide compatibility
|
||||
with PG, The -> and ->> operators in SQLite are extended to also support
|
||||
a JSON object label or an integer array index for the right-hand side
|
||||
operand, in addition to a full JSON path expression.
|
||||
|
||||
Thus, a -> or ->> operator that works on MySQL will work in
|
||||
SQLite. And a -> or ->> operator that works in PG will work in SQLite.
|
||||
But because SQLite supports the union of the disjoint capabilities of
|
||||
MySQL and PG, there will always be -> and ->> operators that work in
|
||||
SQLite that do not work in one of MySQL and PG. This is an unavoidable
|
||||
consequence of the different syntax for -> and ->> in MySQL and PG.
|
||||
|
||||
In the following table, assume that "value1" is a JSON object and
|
||||
"value2" is a JSON array.
|
||||
|
||||
<table border=1 cellpadding=5 cellspacing=0>
|
||||
<tr><th>SQL expression <th>Works in MySQL?<th>Works in PG?<th>Works in SQLite
|
||||
<tr><td>value1->'$.a' <td> yes <td> no <td> yes
|
||||
<tr><td>value1->'a' <td> no <td> yes <td> yes
|
||||
<tr><td>value2->'$[2]' <td> yes <td> no <td> yes
|
||||
<tr><td>value2->2 <td> no <td> yes <td> yes
|
||||
</table>
|
||||
|
||||
The abbreviated JSON path expressions only work for the -> and ->> operators
|
||||
in SQLite. The json_extract() function, and all other built-in SQLite
|
||||
JSON functions, continue to require complete JSON path expressions for their
|
||||
PATH arguments.
|
||||
|
||||
## 3.0 JSON moved into the core
|
||||
|
||||
The JSON interface is now moved into the SQLite core.
|
||||
|
||||
When originally written in 2015, the JSON functions were an extension
|
||||
that could be optionally included at compile-time, or loaded at run-time.
|
||||
The implementation was in a source file named ext/misc/json1.c in the
|
||||
source tree. JSON functions were only compiled in if the
|
||||
-DSQLITE_ENABLE_JSON1 compile-time option was used.
|
||||
|
||||
After these enhancements, the JSON functions are now built-ins.
|
||||
The source file that implements the JSON functions is moved to src/json.c.
|
||||
No special compile-time options are needed to load JSON into the build.
|
||||
Instead, there is a new -DSQLITE_OMIT_JSON compile-time option to leave
|
||||
them out.
|
||||
+174
-404
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
# The new-security-options branch
|
||||
|
||||
## The problem that the [new-security-options](/timeline?r=new-security-options) branch tries to solve
|
||||
|
||||
An attacker might modify the schema of an SQLite database by adding
|
||||
structures that cause code to run when some other application opens and
|
||||
reads the database. For example, the attacker might replace a table
|
||||
definition with a view. Or the attacker might add triggers to tables
|
||||
or views, or add new CHECK constraints or generated columns or indexes
|
||||
with expressions in the index list or in the WHERE clause. If the
|
||||
added features invoke SQL functions or virtual tables with side effects,
|
||||
that might cause harm to the system if run by a high-privilege victim.
|
||||
Or, the added features might exfiltrate information if the database is
|
||||
read by a high-privilege victim.
|
||||
|
||||
The changes in this branch strive to make it easier for high-privilege
|
||||
applications to safely read SQLite database files that might have been
|
||||
maliciously corrupted by an attacker.
|
||||
|
||||
## Overview of changes in [new-security-options](/timeline?r=new-security-options)
|
||||
|
||||
The basic idea is to tag every SQL function and virtual table with one
|
||||
of three risk levels:
|
||||
|
||||
1. Innocuous
|
||||
2. Normal
|
||||
3. Direct-Only
|
||||
|
||||
Innocuous functions/vtabs are safe and can be used at any time.
|
||||
Direct-only elements, in contrast, might have cause side-effects and
|
||||
should only be used from top-level SQL, not from within triggers or views nor
|
||||
in elements of the schema such as CHECK constraint, DEFAULT values,
|
||||
generated columns, index expressions, or in the WHERE clause of a
|
||||
partial index that are potentially under the control of an attacker.
|
||||
Normal elements behave like Innocuous if TRUSTED\_SCHEMA=on
|
||||
and behave like direct-only if TRUSTED\_SCHEMA=off.
|
||||
|
||||
Application-defined functions and virtual tables go in as Normal unless
|
||||
the application takes deliberate steps to change the risk level.
|
||||
|
||||
For backwards compatibility, the default is TRUSTED\_SCHEMA=on. Documentation
|
||||
will be updated to recommend applications turn TRUSTED\_SCHEMA to off.
|
||||
|
||||
An innocuous function or virtual table is one that can only read content
|
||||
from the database file in which it resides, and can only alter the database
|
||||
in which it resides. Most SQL functions are innocuous. For example, there
|
||||
is no harm in an attacker running the abs() function.
|
||||
|
||||
Direct-only elements that have side-effects that go outside the database file
|
||||
in which it lives, or return information from outside of the database file.
|
||||
Examples of direct-only elements include:
|
||||
|
||||
1. The fts3\_tokenizer() function
|
||||
2. The writefile() function
|
||||
3. The readfile() function
|
||||
4. The zipvfs virtual table
|
||||
5. The csv virtual table
|
||||
|
||||
We do not want an attacker to be able to add these kinds of things to
|
||||
the database schema and possibly trick a high-privilege application
|
||||
from performing any of these actions. Therefore, functions and vtabs
|
||||
with side-effects are marked as Direct-Only.
|
||||
|
||||
Legacy applications might add other risky functions or vtabs. Those will
|
||||
go in as "Normal" by default. For optimal security, we want those risky
|
||||
app-defined functions and vtabs to be direct-only, but making that the
|
||||
default might break some legacy applications. Hence, all app-defined
|
||||
functions and vtabs go in as Normal, but the application can switch them
|
||||
over to "Direct-Only" behavior using a single pragma.
|
||||
|
||||
The restrictions on the use of functions and virtual tables do not apply
|
||||
to TEMP. A TEMP VIEW or a TEMP TRIGGER can use any valid SQL function
|
||||
or virtual table. The idea is that TEMP views and triggers must be
|
||||
directly created by the application and are thus under the control of the
|
||||
application. TEMP views and triggers cannot be created by an attacker who
|
||||
corrupts the schema of a persistent database file. Hence TEMP views and
|
||||
triggers are safe.
|
||||
|
||||
## Specific changes
|
||||
|
||||
1. New sqlite3\_db\_config() option SQLITE\_DBCONFIG\_TRUSTED\_SCHEMA for
|
||||
turning TRUSTED\_SCHEMA on and off. It defaults to ON.
|
||||
|
||||
2. Compile-time option -DSQLITE\_TRUSTED\_SCHEMA=0 causes the default
|
||||
TRUSTED\_SCHEMA setting to be off.
|
||||
|
||||
3. New pragma "PRAGMA trusted\_schema=(ON\|OFF);". This provides access
|
||||
to the TRUSTED_SCHEMA setting for application coded using scripting
|
||||
languages or other secondary languages where they are unable to make
|
||||
calls to sqlite3\_db\_config().
|
||||
|
||||
4. New options for the "enc" parameter to sqlite3\_create\_function() and
|
||||
its kin:
|
||||
<ol type="a">
|
||||
<li> _SQLITE\_INNOCUOUS_ → tags the new functions as Innocuous
|
||||
<li> _SQLITE\_DIRECTONLY_ → tags the new functions as Direct-Only
|
||||
</ol>
|
||||
|
||||
5. New options to sqlite3\_vtab\_config():
|
||||
<ol type="a">
|
||||
<li> _SQLITE\_VTAB\_INNOCUOUS_ → tags the vtab as Innocuous
|
||||
<li> _SQLITE\_VTAB\_DIRECTONLY_ → tags the vtab as Direct-Only
|
||||
</ol>
|
||||
|
||||
6. Change many of the functions and virtual tables in the SQLite source
|
||||
tree to use one of the tags above.
|
||||
|
||||
7. Enhanced PRAGMA function\_list and virtual-table "pragma\_function\_list"
|
||||
with additional columns. The columns now are:
|
||||
<ul>
|
||||
<li> _name_ → Name of the function
|
||||
<li> _builtin_ → 1 for built-in functions. 0 otherwise.
|
||||
<li> _type_ → 's'=Scalar, 'a'=Aggregate, 'w'=Window
|
||||
<li> _enc_ → 'utf8', 'utf16le', or 'utf16be'
|
||||
<li> _narg_ → number of argument
|
||||
<li> _flags_ → Bitmask of SQLITE\_INNOCUOUS, SQLITE\_DIRECTONLY,
|
||||
SQLITE\_DETERMINISTIC, SQLITE\_SUBTYPE, and
|
||||
SQLITE\_FUNC\_INTERNAL flags.
|
||||
</ul>
|
||||
<p>The last four columns are new.
|
||||
|
||||
8. The function\_list PRAGMA now also shows all entries for each function.
|
||||
So, for example, if a function can take either 2 or 3 arguments,
|
||||
there are separate rows for the 2-argument and 3-argument versions of
|
||||
the function.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
The function_list enhancements allow the application to query the set
|
||||
of SQL functions that meet various criteria. For example, to see all
|
||||
SQL functions that are never allowed to be used in the schema or in
|
||||
trigger or views:
|
||||
|
||||
~~~
|
||||
SELECT DISTINCT name FROM pragma_function_list
|
||||
WHERE (flags & 0x80000)!=0
|
||||
ORDER BY name;
|
||||
~~~
|
||||
|
||||
Doing the same is not possible for virtual tables, as a virtual table
|
||||
might be Innocuous, Normal, or Direct-Only depending on the arguments
|
||||
passed into the xConnect method.
|
||||
@@ -1,49 +0,0 @@
|
||||
|
||||
20-11-2020
|
||||
|
||||
# Memory Allocation In vdbesort.c
|
||||
|
||||
Memory allocation is slightly different depending on:
|
||||
|
||||
* whether or not SQLITE_CONFIG_SMALL_MALLOC is set, and
|
||||
* whether or not worker threads are enabled.
|
||||
|
||||
## SQLITE_CONFIG_SMALL_MALLOC=0
|
||||
|
||||
Assuming SQLITE_CONFIG_SMALL_MALLOC is not set, keys passed to the sorter are
|
||||
added to an in-memory buffer. This buffer is grown using sqlite3Realloc() as
|
||||
required it reaches the size configured for the main pager cache using "PRAGMA
|
||||
cache_size". i.e. if the user has executed "PRAGMA main.cache_size = -2048",
|
||||
then this buffer is allowed to grow up to 2MB in size.
|
||||
|
||||
Once the buffer has grown to its threshold, keys are sorted and written to
|
||||
a temp file. If worker threads are not enabled, this is the only significant
|
||||
allocation the sorter module makes. After keys are sorted and flushed out to
|
||||
the temp file, the buffer is reused to accumulate the next batch of keys.
|
||||
|
||||
If worker threads are available, then the buffer is passed to a worker thread
|
||||
to sort and flush once it is full, and a new buffer allocated to allow the
|
||||
main thread to continue to accumulate keys. Buffers are reused once they
|
||||
have been flushed, so in this case at most (nWorker+1) buffers are allocated
|
||||
and used, where nWorker is the number of configured worker threads.
|
||||
|
||||
There are no other significant users of heap memory in the sorter module.
|
||||
Once sorted buffers of keys have been flushed to disk, they are read back
|
||||
either by mapping the file (via sqlite3_file.xFetch()) or else read back
|
||||
in one page at a time.
|
||||
|
||||
All buffers are allocated by the main thread. A sorter object is associated
|
||||
with a single database connection, to which it holds a pointer.
|
||||
|
||||
## SQLITE_CONFIG_SMALL_MALLOC=1
|
||||
|
||||
This case is similar to the above, except that instead of accumulating
|
||||
multiple keys in a single large buffer, sqlite3VdbeSorterWrite() stores
|
||||
keys in a regular heap-memory linked list (one allocation per element).
|
||||
List elements are freed as they are flushed to disk, either by the main
|
||||
thread or by a worker thread.
|
||||
|
||||
Each time a key is added the sorter (and an allocation made),
|
||||
sqlite3HeapNearlyFull() is called. If it returns true, the current
|
||||
list of keys is flushed to a temporary file, even if it has not yet
|
||||
reached the size threshold.
|
||||
@@ -1,88 +0,0 @@
|
||||
# Wal-Mode Blocking Locks
|
||||
|
||||
On some Unix-like systems, SQLite may be configured to use POSIX blocking locks
|
||||
by:
|
||||
|
||||
* building the library with SQLITE\_ENABLE\_SETLK\_TIMEOUT defined, and
|
||||
* configuring a timeout in ms using the sqlite3\_busy\_timeout() API.
|
||||
|
||||
Blocking locks may be advantageous as (a) waiting database clients do not
|
||||
need to continuously poll the database lock, and (b) using blocking locks
|
||||
facilitates transfer of OS priority between processes when a high priority
|
||||
process is blocked by a lower priority one.
|
||||
|
||||
Only read/write clients use blocking locks. Clients that have read-only access
|
||||
to the \*-shm file nevery use blocking locks.
|
||||
|
||||
Threads or processes that access a single database at a time never deadlock as
|
||||
a result of blocking database locks. But it is of course possible for threads
|
||||
that lock multiple databases simultaneously to do so. In most cases the OS will
|
||||
detect the deadlock and return an error.
|
||||
|
||||
## Wal Recovery
|
||||
|
||||
Wal database "recovery" is a process required when the number of connected
|
||||
database clients changes from zero to one. In this case, a client is
|
||||
considered to connect to the database when it first reads data from it.
|
||||
Before recovery commences, an exclusive WRITER lock is taken.
|
||||
|
||||
Without blocking locks, if two clients attempt recovery simultaneously, one
|
||||
fails to obtain the WRITER lock and either invokes the busy-handler callback or
|
||||
returns SQLITE\_BUSY to the user. With blocking locks configured, the second
|
||||
client blocks on the WRITER lock.
|
||||
|
||||
## Database Readers
|
||||
|
||||
Usually, read-only are not blocked by any other database clients, so they
|
||||
have no need of blocking locks.
|
||||
|
||||
If a read-only transaction is being opened on a snapshot, the CHECKPOINTER
|
||||
lock is required briefly as part of opening the transaction (to check that a
|
||||
checkpointer is not currently overwriting the snapshot being opened). A
|
||||
blocking lock is used to obtain the CHECKPOINTER lock in this case. A snapshot
|
||||
opener may therefore block on and transfer priority to a checkpointer in some
|
||||
cases.
|
||||
|
||||
## Database Writers
|
||||
|
||||
A database writer must obtain the exclusive WRITER lock. It uses a blocking
|
||||
lock to do so if any of the following are true:
|
||||
|
||||
* the transaction is an implicit one consisting of a single DML or DDL
|
||||
statement, or
|
||||
* the transaction is opened using BEGIN IMMEDIATE or BEGIN EXCLUSIVE, or
|
||||
* the first SQL statement executed following the BEGIN command is a DML or
|
||||
DDL statement (not a read-only statement like a SELECT).
|
||||
|
||||
In other words, in all cases except when an open read-transaction is upgraded
|
||||
to a write-transaction. In that case a non-blocking lock is used.
|
||||
|
||||
## Database Checkpointers
|
||||
|
||||
Database checkpointers takes the following locks, in order:
|
||||
|
||||
* The exclusive CHECKPOINTER lock.
|
||||
* The exclusive WRITER lock (FULL, RESTART and TRUNCATE only).
|
||||
* Exclusive lock on read-mark slots 1-N. These are immediately released after being taken.
|
||||
* Exclusive lock on read-mark 0.
|
||||
* Exclusive lock on read-mark slots 1-N again. These are immediately released
|
||||
after being taken (RESTART and TRUNCATE only).
|
||||
|
||||
All of the above use blocking locks.
|
||||
|
||||
## Summary
|
||||
|
||||
With blocking locks configured, the only cases in which clients should see an
|
||||
SQLITE\_BUSY error are:
|
||||
|
||||
* if the OS does not grant a blocking lock before the configured timeout
|
||||
expires, and
|
||||
* when an open read-transaction is upgraded to a write-transaction.
|
||||
|
||||
In all other cases the blocking locks implementation should prevent clients
|
||||
from having to handle SQLITE\_BUSY errors and facilitate appropriate transfer
|
||||
of priorities between competing clients.
|
||||
|
||||
Clients that lock multiple databases simultaneously must be wary of deadlock.
|
||||
|
||||
|
||||
@@ -1704,3 +1704,4 @@ int sqlite3async_control(int op, ...){
|
||||
}
|
||||
|
||||
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */
|
||||
|
||||
|
||||
@@ -220,3 +220,4 @@ int sqlite3async_control(int op, ...);
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif /* ifndef __SQLITEASYNC_H_ */
|
||||
|
||||
|
||||
+33
-118
@@ -28,7 +28,6 @@ if {[info commands sqlite3_expert_new]==""} {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
set CLI [test_binary_name sqlite3]
|
||||
set CMD [test_binary_name sqlite3_expert]
|
||||
|
||||
@@ -38,9 +37,6 @@ proc squish {txt} {
|
||||
|
||||
proc do_setup_rec_test {tn setup sql res} {
|
||||
reset_db
|
||||
if {[info exists ::set_main_db_name]} {
|
||||
dbconfig_maindbname_icecube db
|
||||
}
|
||||
db eval $setup
|
||||
uplevel [list do_rec_test $tn $sql $res]
|
||||
}
|
||||
@@ -80,10 +76,6 @@ foreach {tn setup} {
|
||||
}
|
||||
}
|
||||
3 {
|
||||
if {[info commands sqlite3_expert_new]==""} { continue }
|
||||
set ::set_main_db_name 1
|
||||
}
|
||||
4 {
|
||||
if {![file executable $CLI]} { continue }
|
||||
|
||||
proc do_rec_test {tn sql res} {
|
||||
@@ -103,7 +95,7 @@ do_setup_rec_test $tn.1 { CREATE TABLE t1(a, b, c) } {
|
||||
SELECT * FROM t1
|
||||
} {
|
||||
(no new indexes)
|
||||
SCAN t1
|
||||
0|0|0|SCAN TABLE t1
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.2 {
|
||||
@@ -112,7 +104,7 @@ do_setup_rec_test $tn.2 {
|
||||
SELECT * FROM t1 WHERE b>?;
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b);
|
||||
SEARCH t1 USING INDEX t1_idx_00000062 (b>?)
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.3 {
|
||||
@@ -121,7 +113,7 @@ do_setup_rec_test $tn.3 {
|
||||
SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ?
|
||||
} {
|
||||
CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE);
|
||||
SEARCH t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.4 {
|
||||
@@ -130,7 +122,7 @@ do_setup_rec_test $tn.4 {
|
||||
SELECT a FROM t1 ORDER BY b;
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b);
|
||||
SCAN t1 USING INDEX t1_idx_00000062
|
||||
0|0|0|SCAN TABLE t1 USING INDEX t1_idx_00000062
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.5 {
|
||||
@@ -139,18 +131,16 @@ do_setup_rec_test $tn.5 {
|
||||
SELECT a FROM t1 WHERE a=? ORDER BY b;
|
||||
} {
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b);
|
||||
SEARCH t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
}
|
||||
|
||||
if 0 {
|
||||
do_setup_rec_test $tn.6 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
} {
|
||||
SELECT min(a) FROM t1
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
SEARCH t1 USING COVERING INDEX t1_idx_00000061
|
||||
}
|
||||
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.7 {
|
||||
@@ -159,7 +149,7 @@ do_setup_rec_test $tn.7 {
|
||||
SELECT * FROM t1 ORDER BY a, b, c;
|
||||
} {
|
||||
CREATE INDEX t1_idx_033e95fe ON t1(a, b, c);
|
||||
SCAN t1 USING COVERING INDEX t1_idx_033e95fe
|
||||
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
|
||||
}
|
||||
|
||||
#do_setup_rec_test $tn.1.8 {
|
||||
@@ -168,7 +158,7 @@ do_setup_rec_test $tn.7 {
|
||||
# SELECT * FROM t1 ORDER BY a ASC, b COLLATE nocase DESC, c ASC;
|
||||
#} {
|
||||
# CREATE INDEX t1_idx_5be6e222 ON t1(a, b COLLATE NOCASE DESC, c);
|
||||
# 0|0|0|SCAN t1 USING COVERING INDEX t1_idx_5be6e222
|
||||
# 0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5be6e222
|
||||
#}
|
||||
|
||||
do_setup_rec_test $tn.8.1 {
|
||||
@@ -177,7 +167,7 @@ do_setup_rec_test $tn.8.1 {
|
||||
SELECT * FROM t1 WHERE a=?
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
SEARCH t1 USING INDEX t1_idx_00000061 (a=?)
|
||||
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
|
||||
}
|
||||
do_setup_rec_test $tn.8.2 {
|
||||
CREATE TABLE t1(a, b COLLATE nocase, c);
|
||||
@@ -185,7 +175,7 @@ do_setup_rec_test $tn.8.2 {
|
||||
SELECT * FROM t1 ORDER BY a ASC, b DESC, c ASC;
|
||||
} {
|
||||
CREATE INDEX t1_idx_5cb97285 ON t1(a, b DESC, c);
|
||||
SCAN t1 USING COVERING INDEX t1_idx_5cb97285
|
||||
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
|
||||
}
|
||||
|
||||
|
||||
@@ -196,8 +186,8 @@ do_setup_rec_test $tn.9.1 {
|
||||
} {
|
||||
SELECT * FROM "t t" WHERE a=?
|
||||
} {
|
||||
CREATE INDEX "t t_idx_00000061" ON "t t"(a);
|
||||
SEARCH t t USING INDEX t t_idx_00000061 (a=?)
|
||||
CREATE INDEX 't t_idx_00000061' ON 't t'(a);
|
||||
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.9.2 {
|
||||
@@ -205,8 +195,8 @@ do_setup_rec_test $tn.9.2 {
|
||||
} {
|
||||
SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
|
||||
} {
|
||||
CREATE INDEX "t t_idx_00000062" ON "t t"(b);
|
||||
SEARCH t t USING INDEX t t_idx_00000062 (b>? AND b<?)
|
||||
CREATE INDEX 't t_idx_00000062' ON 't t'(b);
|
||||
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
|
||||
}
|
||||
|
||||
# Columns with names that require quotes.
|
||||
@@ -217,7 +207,7 @@ do_setup_rec_test $tn.10.1 {
|
||||
SELECT * FROM t3 WHERE "b b" = ?
|
||||
} {
|
||||
CREATE INDEX t3_idx_00050c52 ON t3('b b');
|
||||
SEARCH t3 USING INDEX t3_idx_00050c52 (b b=?)
|
||||
0|0|0|SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.10.2 {
|
||||
@@ -226,7 +216,7 @@ do_setup_rec_test $tn.10.2 {
|
||||
SELECT * FROM t3 ORDER BY "b b"
|
||||
} {
|
||||
CREATE INDEX t3_idx_00050c52 ON t3('b b');
|
||||
SCAN t3 USING INDEX t3_idx_00050c52
|
||||
0|0|0|SCAN TABLE t3 USING INDEX t3_idx_00050c52
|
||||
}
|
||||
|
||||
# Transitive constraints
|
||||
@@ -239,8 +229,8 @@ do_setup_rec_test $tn.11.1 {
|
||||
} {
|
||||
CREATE INDEX t5_idx_000123a7 ON t5(a, b);
|
||||
CREATE INDEX t6_idx_00000063 ON t6(c);
|
||||
SEARCH t6 USING INDEX t6_idx_00000063 (c=?)
|
||||
SEARCH t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
|
||||
0|0|1|SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?)
|
||||
0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
|
||||
}
|
||||
|
||||
# OR terms.
|
||||
@@ -252,11 +242,8 @@ do_setup_rec_test $tn.12.1 {
|
||||
} {
|
||||
CREATE INDEX t7_idx_00000062 ON t7(b);
|
||||
CREATE INDEX t7_idx_00000061 ON t7(a);
|
||||
MULTI-INDEX OR
|
||||
INDEX 1
|
||||
SEARCH t7 USING INDEX t7_idx_00000061 (a=?)
|
||||
INDEX 2
|
||||
SEARCH t7 USING INDEX t7_idx_00000062 (b=?)
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
|
||||
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
|
||||
}
|
||||
|
||||
# rowid terms.
|
||||
@@ -267,7 +254,7 @@ do_setup_rec_test $tn.13.1 {
|
||||
SELECT * FROM t8 WHERE rowid=?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH t8 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
0|0|0|SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
do_setup_rec_test $tn.13.2 {
|
||||
CREATE TABLE t8(a, b);
|
||||
@@ -275,7 +262,7 @@ do_setup_rec_test $tn.13.2 {
|
||||
SELECT * FROM t8 ORDER BY rowid
|
||||
} {
|
||||
(no new indexes)
|
||||
SCAN t8
|
||||
0|0|0|SCAN TABLE t8
|
||||
}
|
||||
do_setup_rec_test $tn.13.3 {
|
||||
CREATE TABLE t8(a, b);
|
||||
@@ -283,7 +270,7 @@ do_setup_rec_test $tn.13.3 {
|
||||
SELECT * FROM t8 WHERE a=? ORDER BY rowid
|
||||
} {
|
||||
CREATE INDEX t8_idx_00000061 ON t8(a);
|
||||
SEARCH t8 USING INDEX t8_idx_00000061 (a=?)
|
||||
0|0|0|SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
|
||||
}
|
||||
|
||||
# Triggers
|
||||
@@ -298,7 +285,7 @@ do_setup_rec_test $tn.14 {
|
||||
INSERT INTO t9 VALUES(?, ?, ?);
|
||||
} {
|
||||
CREATE INDEX t10_idx_00000062 ON t10(b);
|
||||
SEARCH t10 USING INDEX t10_idx_00000062 (b=?)
|
||||
0|0|0|SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.15 {
|
||||
@@ -314,8 +301,8 @@ do_setup_rec_test $tn.15 {
|
||||
SELECT * FROM t2, t1 WHERE b=? AND d=? AND t2.rowid=t1.rowid
|
||||
} {
|
||||
CREATE INDEX t2_idx_00000064 ON t2(d);
|
||||
SEARCH t2 USING INDEX t2_idx_00000064 (d=?)
|
||||
SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
0|0|0|SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?)
|
||||
0|1|1|SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.16 {
|
||||
@@ -324,81 +311,7 @@ do_setup_rec_test $tn.16 {
|
||||
SELECT * FROM t1 WHERE b IS NOT NULL;
|
||||
} {
|
||||
(no new indexes)
|
||||
SCAN t1
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.17.1 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH example USING INDEX sqlite_autoindex_example_1 (A=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.2 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE b=?
|
||||
} {
|
||||
CREATE INDEX example_idx_00000042 ON example(B);
|
||||
SEARCH example USING INDEX example_idx_00000042 (B=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.3 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=? AND b=?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH example USING INDEX sqlite_autoindex_example_1 (A=? AND B=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.4 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=? AND b>?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH example USING INDEX sqlite_autoindex_example_1 (A=? AND B>?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.5 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a>? AND b=?
|
||||
} {
|
||||
CREATE INDEX example_idx_0000cb3f ON example(B, A);
|
||||
SEARCH example USING INDEX example_idx_0000cb3f (B=? AND A>?)
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.18.0 {
|
||||
CREATE TABLE SomeObject (
|
||||
a INTEGER PRIMARY KEY,
|
||||
x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL
|
||||
);
|
||||
} {
|
||||
SELECT x FROM SomeObject;
|
||||
} {
|
||||
(no new indexes)
|
||||
SCAN SomeObject
|
||||
}
|
||||
do_setup_rec_test $tn.18.1 {
|
||||
CREATE TABLE SomeObject (
|
||||
a INTEGER PRIMARY KEY,
|
||||
x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL
|
||||
);
|
||||
} {
|
||||
SELECT * FROM SomeObject WHERE x=?;
|
||||
} {
|
||||
CREATE INDEX SomeObject_idx_00000078 ON SomeObject(x);
|
||||
SEARCH SomeObject USING COVERING INDEX SomeObject_idx_00000078 (x=?)
|
||||
}
|
||||
|
||||
|
||||
do_setup_rec_test $tn.19.0 {
|
||||
CREATE TABLE t1("index");
|
||||
} {
|
||||
SELECT * FROM t1 ORDER BY "index";
|
||||
} {
|
||||
CREATE INDEX t1_idx_01a7214e ON t1('index');
|
||||
SCAN t1 USING COVERING INDEX t1_idx_01a7214e
|
||||
0|0|0|SCAN TABLE t1
|
||||
}
|
||||
|
||||
}
|
||||
@@ -418,7 +331,7 @@ proc do_candidates_test {tn sql res} {
|
||||
|
||||
|
||||
reset_db
|
||||
do_execsql_test 5.0 {
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(c, d);
|
||||
|
||||
@@ -428,7 +341,7 @@ do_execsql_test 5.0 {
|
||||
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
|
||||
INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
|
||||
}
|
||||
do_candidates_test 5.1 {
|
||||
do_candidates_test 3.1 {
|
||||
SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
|
||||
@@ -437,14 +350,14 @@ do_candidates_test 5.1 {
|
||||
CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
|
||||
}
|
||||
|
||||
do_candidates_test 5.2 {
|
||||
do_candidates_test 3.2 {
|
||||
SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=?
|
||||
} {
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17
|
||||
CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
|
||||
}
|
||||
|
||||
do_execsql_test 5.3 {
|
||||
do_execsql_test 3.2 {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50
|
||||
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
|
||||
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16
|
||||
@@ -464,4 +377,6 @@ do_execsql_test 5.3 {
|
||||
t2 t2_idx_0001295b {100 20 5}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+49
-145
@@ -15,23 +15,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(SQLITE_AMALGAMATION)
|
||||
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
|
||||
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
|
||||
#endif
|
||||
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
|
||||
# define ALWAYS(X) (1)
|
||||
# define NEVER(X) (0)
|
||||
#elif !defined(NDEBUG)
|
||||
# define ALWAYS(X) ((X)?1:(assert(0),0))
|
||||
# define NEVER(X) ((X)?(assert(0),1):0)
|
||||
#else
|
||||
# define ALWAYS(X) (X)
|
||||
# define NEVER(X) (X)
|
||||
#endif
|
||||
#endif /* !defined(SQLITE_AMALGAMATION) */
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
typedef sqlite3_int64 i64;
|
||||
@@ -661,7 +644,6 @@ static int idxRegisterVtab(sqlite3expert *p){
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
0, /* xShadowName */
|
||||
};
|
||||
|
||||
return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
|
||||
@@ -697,33 +679,21 @@ static int idxGetTableInfo(
|
||||
){
|
||||
sqlite3_stmt *p1 = 0;
|
||||
int nCol = 0;
|
||||
int nTab;
|
||||
int nByte;
|
||||
int nTab = STRLEN(zTab);
|
||||
int nByte = sizeof(IdxTable) + nTab + 1;
|
||||
IdxTable *pNew = 0;
|
||||
int rc, rc2;
|
||||
char *pCsr = 0;
|
||||
int nPk = 0;
|
||||
|
||||
*ppOut = 0;
|
||||
if( zTab==0 ) return SQLITE_ERROR;
|
||||
nTab = STRLEN(zTab);
|
||||
nByte = sizeof(IdxTable) + nTab + 1;
|
||||
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab);
|
||||
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
|
||||
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
|
||||
const char *zColSeq = 0;
|
||||
if( zCol==0 ){
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
nByte += 1 + STRLEN(zCol);
|
||||
rc = sqlite3_table_column_metadata(
|
||||
db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
|
||||
db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
|
||||
);
|
||||
if( zColSeq==0 ) zColSeq = "binary";
|
||||
nByte += 1 + STRLEN(zColSeq);
|
||||
nByte += 1 + STRLEN(zCol);
|
||||
nCol++;
|
||||
nPk += (sqlite3_column_int(p1, 5)>0);
|
||||
}
|
||||
rc2 = sqlite3_reset(p1);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
@@ -741,23 +711,19 @@ static int idxGetTableInfo(
|
||||
nCol = 0;
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
|
||||
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
|
||||
const char *zColSeq = 0;
|
||||
int nCopy;
|
||||
if( zCol==0 ) continue;
|
||||
nCopy = STRLEN(zCol) + 1;
|
||||
int nCopy = STRLEN(zCol) + 1;
|
||||
pNew->aCol[nCol].zName = pCsr;
|
||||
pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
|
||||
pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
|
||||
memcpy(pCsr, zCol, nCopy);
|
||||
pCsr += nCopy;
|
||||
|
||||
rc = sqlite3_table_column_metadata(
|
||||
db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
|
||||
db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( zColSeq==0 ) zColSeq = "binary";
|
||||
nCopy = STRLEN(zColSeq) + 1;
|
||||
nCopy = STRLEN(zCol) + 1;
|
||||
pNew->aCol[nCol].zColl = pCsr;
|
||||
memcpy(pCsr, zColSeq, nCopy);
|
||||
memcpy(pCsr, zCol, nCopy);
|
||||
pCsr += nCopy;
|
||||
}
|
||||
|
||||
@@ -768,9 +734,9 @@ static int idxGetTableInfo(
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pNew);
|
||||
pNew = 0;
|
||||
}else if( ALWAYS(pNew!=0) ){
|
||||
}else{
|
||||
pNew->zName = pCsr;
|
||||
if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1);
|
||||
memcpy(pNew->zName, zTab, nTab+1);
|
||||
}
|
||||
|
||||
*ppOut = pNew;
|
||||
@@ -820,10 +786,6 @@ static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
|
||||
*/
|
||||
static int idxIdentifierRequiresQuotes(const char *zId){
|
||||
int i;
|
||||
int nId = STRLEN(zId);
|
||||
|
||||
if( sqlite3_keyword_check(zId, nId) ) return 1;
|
||||
|
||||
for(i=0; zId[i]; i++){
|
||||
if( !(zId[i]=='_')
|
||||
&& !(zId[i]>='0' && zId[i]<='9')
|
||||
@@ -900,7 +862,6 @@ static int idxFindCompatible(
|
||||
IdxConstraint *pT = pTail;
|
||||
sqlite3_stmt *pInfo = 0;
|
||||
const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
|
||||
if( zIdx==0 ) continue;
|
||||
|
||||
/* Zero the IdxConstraint.bFlag values in the pEq list */
|
||||
for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
|
||||
@@ -946,19 +907,6 @@ static int idxFindCompatible(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback for sqlite3_exec() with query with leading count(*) column.
|
||||
* The first argument is expected to be an int*, referent to be incremented
|
||||
* if that leading column is not exactly '0'.
|
||||
*/
|
||||
static int countNonzeros(void* pCount, int nc,
|
||||
char* azResults[], char* azColumns[]){
|
||||
(void)azColumns; /* Suppress unused parameter warning */
|
||||
if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){
|
||||
*((int *)pCount) += 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int idxCreateFromCons(
|
||||
sqlite3expert *p,
|
||||
IdxScan *pScan,
|
||||
@@ -985,40 +933,17 @@ static int idxCreateFromCons(
|
||||
if( rc==SQLITE_OK ){
|
||||
/* Hash the list of columns to come up with a name for the index */
|
||||
const char *zTable = pScan->pTab->zName;
|
||||
int quoteTable = idxIdentifierRequiresQuotes(zTable);
|
||||
char *zName = 0; /* Index name */
|
||||
int collisions = 0;
|
||||
do{
|
||||
int i;
|
||||
char *zFind;
|
||||
for(i=0; zCols[i]; i++){
|
||||
h += ((h<<3) + zCols[i]);
|
||||
}
|
||||
sqlite3_free(zName);
|
||||
zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
|
||||
if( zName==0 ) break;
|
||||
/* Is is unique among table, view and index names? */
|
||||
zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q"
|
||||
" AND type in ('index','table','view')";
|
||||
zFind = sqlite3_mprintf(zFmt, zName);
|
||||
i = 0;
|
||||
rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0);
|
||||
assert(rc==SQLITE_OK);
|
||||
sqlite3_free(zFind);
|
||||
if( i==0 ){
|
||||
collisions = 0;
|
||||
break;
|
||||
}
|
||||
++collisions;
|
||||
}while( collisions<50 && zName!=0 );
|
||||
if( collisions ){
|
||||
/* This return means "Gave up trying to find a unique index name." */
|
||||
rc = SQLITE_BUSY_TIMEOUT;
|
||||
}else if( zName==0 ){
|
||||
char *zName; /* Index name */
|
||||
int i;
|
||||
for(i=0; zCols[i]; i++){
|
||||
h += ((h<<3) + zCols[i]);
|
||||
}
|
||||
zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
|
||||
if( zName==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
if( quoteTable ){
|
||||
zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)";
|
||||
if( idxIdentifierRequiresQuotes(zTable) ){
|
||||
zFmt = "CREATE INDEX '%q' ON %Q(%s)";
|
||||
}else{
|
||||
zFmt = "CREATE INDEX %s ON %s(%s)";
|
||||
}
|
||||
@@ -1027,11 +952,7 @@ static int idxCreateFromCons(
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_BUSY_TIMEOUT;
|
||||
}else{
|
||||
idxHashAdd(&rc, &p->hIdx, zName, zIdx);
|
||||
}
|
||||
idxHashAdd(&rc, &p->hIdx, zName, zIdx);
|
||||
}
|
||||
sqlite3_free(zName);
|
||||
sqlite3_free(zIdx);
|
||||
@@ -1183,7 +1104,7 @@ static void idxWriteFree(IdxWrite *pTab){
|
||||
** runs all the queries to see which indexes they prefer, and populates
|
||||
** IdxStatement.zIdx and IdxStatement.zEQP with the results.
|
||||
*/
|
||||
static int idxFindIndexes(
|
||||
int idxFindIndexes(
|
||||
sqlite3expert *p,
|
||||
char **pzErr /* OUT: Error message (sqlite3_malloc) */
|
||||
){
|
||||
@@ -1202,23 +1123,18 @@ static int idxFindIndexes(
|
||||
"EXPLAIN QUERY PLAN %s", pStmt->zSql
|
||||
);
|
||||
while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
|
||||
/* int iId = sqlite3_column_int(pExplain, 0); */
|
||||
/* int iParent = sqlite3_column_int(pExplain, 1); */
|
||||
/* int iNotUsed = sqlite3_column_int(pExplain, 2); */
|
||||
int iSelectid = sqlite3_column_int(pExplain, 0);
|
||||
int iOrder = sqlite3_column_int(pExplain, 1);
|
||||
int iFrom = sqlite3_column_int(pExplain, 2);
|
||||
const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
|
||||
int nDetail;
|
||||
int nDetail = STRLEN(zDetail);
|
||||
int i;
|
||||
|
||||
if( !zDetail ) continue;
|
||||
nDetail = STRLEN(zDetail);
|
||||
|
||||
for(i=0; i<nDetail; i++){
|
||||
const char *zIdx = 0;
|
||||
if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
|
||||
if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
|
||||
zIdx = &zDetail[i+13];
|
||||
}else if( i+22<nDetail
|
||||
&& memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
|
||||
){
|
||||
}else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
|
||||
zIdx = &zDetail[i+22];
|
||||
}
|
||||
if( zIdx ){
|
||||
@@ -1236,9 +1152,9 @@ static int idxFindIndexes(
|
||||
}
|
||||
}
|
||||
|
||||
if( zDetail[0]!='-' ){
|
||||
pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
|
||||
}
|
||||
pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n",
|
||||
iSelectid, iOrder, iFrom, zDetail
|
||||
);
|
||||
}
|
||||
|
||||
for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
|
||||
@@ -1301,7 +1217,7 @@ static int idxProcessOneTrigger(
|
||||
IdxTable *pTab = pWrite->pTab;
|
||||
const char *zTab = pTab->zName;
|
||||
const char *zSql =
|
||||
"SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema "
|
||||
"SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
|
||||
"WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
|
||||
"ORDER BY type;";
|
||||
sqlite3_stmt *pSelect = 0;
|
||||
@@ -1312,7 +1228,6 @@ static int idxProcessOneTrigger(
|
||||
rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
|
||||
const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
|
||||
if( zCreate==0 ) continue;
|
||||
rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
|
||||
}
|
||||
idxFinalize(&rc, pSelect);
|
||||
@@ -1402,12 +1317,12 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
|
||||
** 2) Create the equivalent virtual table in dbv.
|
||||
*/
|
||||
rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
|
||||
"SELECT type, name, sql, 1 FROM sqlite_schema "
|
||||
"SELECT type, name, sql, 1 FROM sqlite_master "
|
||||
"WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
|
||||
" UNION ALL "
|
||||
"SELECT type, name, sql, 2 FROM sqlite_schema "
|
||||
"SELECT type, name, sql, 2 FROM sqlite_master "
|
||||
"WHERE type = 'trigger'"
|
||||
" AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') "
|
||||
" AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
|
||||
"ORDER BY 4, 1"
|
||||
);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
|
||||
@@ -1415,9 +1330,8 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
|
||||
const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
|
||||
const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
|
||||
|
||||
if( zType==0 || zName==0 ) continue;
|
||||
if( zType[0]=='v' || zType[1]=='r' ){
|
||||
if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
|
||||
rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
|
||||
}else{
|
||||
IdxTable *pTab;
|
||||
rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
|
||||
@@ -1554,7 +1468,6 @@ static void idxRemFunc(
|
||||
case SQLITE_BLOB:
|
||||
case SQLITE_TEXT: {
|
||||
int nByte = sqlite3_value_bytes(argv[1]);
|
||||
const void *pData = 0;
|
||||
if( nByte>pSlot->nByte ){
|
||||
char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
|
||||
if( zNew==0 ){
|
||||
@@ -1566,11 +1479,9 @@ static void idxRemFunc(
|
||||
}
|
||||
pSlot->n = nByte;
|
||||
if( pSlot->eType==SQLITE_BLOB ){
|
||||
pData = sqlite3_value_blob(argv[1]);
|
||||
if( pData ) memcpy(pSlot->z, pData, nByte);
|
||||
memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
|
||||
}else{
|
||||
pData = sqlite3_value_text(argv[1]);
|
||||
memcpy(pSlot->z, pData, nByte);
|
||||
memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1581,7 +1492,7 @@ static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
|
||||
int rc = SQLITE_OK;
|
||||
const char *zMax =
|
||||
"SELECT max(i.seqno) FROM "
|
||||
" sqlite_schema AS s, "
|
||||
" sqlite_master AS s, "
|
||||
" pragma_index_list(s.name) AS l, "
|
||||
" pragma_index_info(l.name) AS i "
|
||||
"WHERE s.type = 'table'";
|
||||
@@ -1734,7 +1645,7 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
|
||||
const char *zAllIndex =
|
||||
"SELECT s.rowid, s.name, l.name FROM "
|
||||
" sqlite_schema AS s, "
|
||||
" sqlite_master AS s, "
|
||||
" pragma_index_list(s.name) AS l "
|
||||
"WHERE s.type = 'table'";
|
||||
const char *zIndexXInfo =
|
||||
@@ -1781,7 +1692,6 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
|
||||
const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
|
||||
const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
|
||||
if( zTab==0 || zIdx==0 ) continue;
|
||||
if( p->iSample<100 && iPrev!=iRowid ){
|
||||
samplectx.target = (double)p->iSample / 100.0;
|
||||
samplectx.iTarget = p->iSample;
|
||||
@@ -1803,15 +1713,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
|
||||
idxFinalize(&rc, pIndexXInfo);
|
||||
idxFinalize(&rc, pWrite);
|
||||
|
||||
if( pCtx ){
|
||||
for(i=0; i<pCtx->nSlot; i++){
|
||||
sqlite3_free(pCtx->aSlot[i].z);
|
||||
}
|
||||
sqlite3_free(pCtx);
|
||||
for(i=0; i<pCtx->nSlot; i++){
|
||||
sqlite3_free(pCtx->aSlot[i].z);
|
||||
}
|
||||
sqlite3_free(pCtx);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
|
||||
rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
|
||||
}
|
||||
|
||||
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
|
||||
@@ -1848,14 +1756,14 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
|
||||
|
||||
/* Copy the entire schema of database [db] into [dbm]. */
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pSql = 0;
|
||||
sqlite3_stmt *pSql;
|
||||
rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
|
||||
"SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
|
||||
"SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
|
||||
" AND sql NOT LIKE 'CREATE VIRTUAL %%'"
|
||||
);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
|
||||
const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
|
||||
if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
|
||||
rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
|
||||
}
|
||||
idxFinalize(&rc, pSql);
|
||||
}
|
||||
@@ -1961,10 +1869,6 @@ int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
|
||||
/* Create candidate indexes within the in-memory database file */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = idxCreateCandidates(p);
|
||||
}else if ( rc==SQLITE_BUSY_TIMEOUT ){
|
||||
if( pzErr )
|
||||
*pzErr = sqlite3_mprintf("Cannot find a unique index name to propose.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Generate the stat1 data */
|
||||
@@ -2045,4 +1949,4 @@ void sqlite3_expert_destroy(sqlite3expert *p){
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||||
#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
**
|
||||
*************************************************************************
|
||||
*/
|
||||
#if !defined(SQLITEEXPERT_H)
|
||||
#define SQLITEEXPERT_H 1
|
||||
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
typedef struct sqlite3expert sqlite3expert;
|
||||
@@ -165,4 +165,4 @@ const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
|
||||
*/
|
||||
void sqlite3_expert_destroy(sqlite3expert*);
|
||||
|
||||
#endif /* !defined(SQLITEEXPERT_H) */
|
||||
|
||||
|
||||
@@ -174,3 +174,5 @@ EXTERNAL CONTENT FTS4 TABLES
|
||||
only be useful if the full-text index has somehow become corrupt. It is an
|
||||
error to attempt to rebuild the full-text index maintained by a contentless
|
||||
FTS4 table.
|
||||
|
||||
|
||||
|
||||
@@ -52,10 +52,8 @@
|
||||
|
||||
SECURITY: If the fts3 extension is used in an environment where potentially
|
||||
malicious users may execute arbitrary SQL (i.e. gears), they should be
|
||||
prevented from invoking the fts3_tokenizer() function. The
|
||||
fts3_tokenizer() function is disabled by default. It is only enabled
|
||||
by SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER. Do not enable it in
|
||||
security sensitive environments.
|
||||
prevented from invoking the fts3_tokenizer() function, possibly using the
|
||||
authorisation callback.
|
||||
|
||||
See "Sample code" below for an example of calling the fts3_tokenizer()
|
||||
function from C code.
|
||||
|
||||
+170
-327
File diff suppressed because it is too large
Load Diff
+14
-49
@@ -95,8 +95,6 @@ SQLITE_EXTENSION_INIT3
|
||||
*/
|
||||
#define FTS3_VARINT_MAX 10
|
||||
|
||||
#define FTS3_BUFFER_PADDING 8
|
||||
|
||||
/*
|
||||
** FTS4 virtual tables may maintain multiple indexes - one index of all terms
|
||||
** in the document set and zero or more prefix indexes. All indexes are stored
|
||||
@@ -129,18 +127,6 @@ SQLITE_EXTENSION_INIT3
|
||||
#define POS_COLUMN (1) /* Column-list terminator */
|
||||
#define POS_END (0) /* Position-list terminator */
|
||||
|
||||
/*
|
||||
** The assert_fts3_nc() macro is similar to the assert() macro, except that it
|
||||
** is used for assert() conditions that are true only if it can be
|
||||
** guranteed that the database is not corrupt.
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
extern int sqlite3_fts3_may_be_corrupt;
|
||||
# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x))
|
||||
#else
|
||||
# define assert_fts3_nc(x) assert(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This section provides definitions to allow the
|
||||
** FTS3 extension to be compiled outside of the
|
||||
@@ -151,18 +137,17 @@ extern int sqlite3_fts3_may_be_corrupt;
|
||||
** Macros indicating that conditional expressions are always true or
|
||||
** false.
|
||||
*/
|
||||
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
|
||||
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
|
||||
#endif
|
||||
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
|
||||
# define ALWAYS(X) (1)
|
||||
# define NEVER(X) (0)
|
||||
#elif !defined(NDEBUG)
|
||||
# define ALWAYS(X) ((X)?1:(assert(0),0))
|
||||
# define NEVER(X) ((X)?(assert(0),1):0)
|
||||
#ifdef SQLITE_COVERAGE_TEST
|
||||
# define ALWAYS(x) (1)
|
||||
# define NEVER(X) (0)
|
||||
#elif defined(SQLITE_DEBUG)
|
||||
# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
|
||||
# define NEVER(x) sqlite3Fts3Never((x)!=0)
|
||||
int sqlite3Fts3Always(int b);
|
||||
int sqlite3Fts3Never(int b);
|
||||
#else
|
||||
# define ALWAYS(X) (X)
|
||||
# define NEVER(X) (X)
|
||||
# define ALWAYS(x) (x)
|
||||
# define NEVER(x) (x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -197,11 +182,6 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */
|
||||
# define TESTONLY(X)
|
||||
#endif
|
||||
|
||||
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
|
||||
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
|
||||
|
||||
#define deliberate_fall_through
|
||||
|
||||
#endif /* SQLITE_AMALGAMATION */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -245,7 +225,6 @@ struct Fts3Table {
|
||||
char *zLanguageid; /* languageid=xxx option, or NULL */
|
||||
int nAutoincrmerge; /* Value configured by 'automerge' */
|
||||
u32 nLeafAdd; /* Number of leaf blocks added this trans */
|
||||
int bLock; /* Used to prevent recursive content= tbls */
|
||||
|
||||
/* Precompiled statements used by the implementation. Each of these
|
||||
** statements is run and reset within a single virtual table API call.
|
||||
@@ -304,23 +283,13 @@ struct Fts3Table {
|
||||
int mxSavepoint; /* Largest valid xSavepoint integer */
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
#ifdef SQLITE_TEST
|
||||
/* True to disable the incremental doclist optimization. This is controled
|
||||
** by special insert command 'test-no-incr-doclist'. */
|
||||
int bNoIncrDoclist;
|
||||
|
||||
/* Number of segments in a level */
|
||||
int nMergeCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Macro to find the number of segments to merge */
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
# define MergeCount(P) ((P)->nMergeCount)
|
||||
#else
|
||||
# define MergeCount(P) FTS3_MERGE_COUNT
|
||||
#endif
|
||||
|
||||
/*
|
||||
** When the core wants to read from the virtual table, it creates a
|
||||
** virtual table cursor (an instance of the following structure) using
|
||||
@@ -558,7 +527,7 @@ struct Fts3MultiSegReader {
|
||||
int nAdvance; /* How many seg-readers to advance */
|
||||
Fts3SegFilter *pFilter; /* Pointer to filter object */
|
||||
char *aBuffer; /* Buffer to merge doclists in */
|
||||
i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
|
||||
int nBuffer; /* Allocated size of aBuffer[] in bytes */
|
||||
|
||||
int iColFilter; /* If >=0, filter for this column */
|
||||
int bRestart;
|
||||
@@ -584,8 +553,6 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
|
||||
void sqlite3Fts3ErrMsg(char**,const char*,...);
|
||||
int sqlite3Fts3PutVarint(char *, sqlite3_int64);
|
||||
int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
|
||||
int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *);
|
||||
int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*);
|
||||
int sqlite3Fts3GetVarint32(const char *, int *);
|
||||
int sqlite3Fts3VarintLen(sqlite3_uint64);
|
||||
void sqlite3Fts3Dequote(char *);
|
||||
@@ -594,7 +561,6 @@ int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
|
||||
int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
|
||||
void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
|
||||
int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
|
||||
int sqlite3Fts3ReadInt(const char *z, int *pnOut);
|
||||
|
||||
/* fts3_tokenizer.c */
|
||||
const char *sqlite3Fts3NextToken(const char *, int *);
|
||||
@@ -618,10 +584,9 @@ int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
|
||||
);
|
||||
void sqlite3Fts3ExprFree(Fts3Expr *);
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
|
||||
int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
|
||||
int sqlite3Fts3InitTerm(sqlite3 *db);
|
||||
#endif
|
||||
void *sqlite3Fts3MallocZero(i64 nByte);
|
||||
|
||||
int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
|
||||
sqlite3_tokenizer_cursor **
|
||||
@@ -641,7 +606,7 @@ int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
|
||||
int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
|
||||
|
||||
/* fts3_tokenize_vtab.c */
|
||||
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
|
||||
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
|
||||
|
||||
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
|
||||
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|
||||
|
||||
+7
-13
@@ -66,7 +66,7 @@ static int fts3auxConnectMethod(
|
||||
char const *zFts3; /* Name of fts3 table */
|
||||
int nDb; /* Result of strlen(zDb) */
|
||||
int nFts3; /* Result of strlen(zFts3) */
|
||||
sqlite3_int64 nByte; /* Bytes of space to allocate here */
|
||||
int nByte; /* Bytes of space to allocate here */
|
||||
int rc; /* value returned by declare_vtab() */
|
||||
Fts3auxTable *p; /* Virtual table object to return */
|
||||
|
||||
@@ -98,7 +98,7 @@ static int fts3auxConnectMethod(
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
|
||||
p = (Fts3auxTable *)sqlite3_malloc64(nByte);
|
||||
p = (Fts3auxTable *)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
memset(p, 0, nByte);
|
||||
|
||||
@@ -248,7 +248,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
|
||||
if( nSize>pCsr->nStat ){
|
||||
struct Fts3auxColstats *aNew;
|
||||
aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat,
|
||||
aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat,
|
||||
sizeof(struct Fts3auxColstats) * nSize
|
||||
);
|
||||
if( aNew==0 ) return SQLITE_NOMEM;
|
||||
@@ -297,7 +297,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
|
||||
memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
|
||||
iCol = 0;
|
||||
rc = SQLITE_OK;
|
||||
|
||||
while( i<nDoclist ){
|
||||
sqlite3_int64 v = 0;
|
||||
@@ -341,10 +340,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
/* State 3. The integer just read is a column number. */
|
||||
default: assert( eState==3 );
|
||||
iCol = (int)v;
|
||||
if( iCol<1 ){
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
break;
|
||||
}
|
||||
if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
|
||||
pCsr->aStat[iCol+1].nDoc++;
|
||||
eState = 2;
|
||||
@@ -353,6 +348,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
}
|
||||
|
||||
pCsr->iCol = 0;
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
pCsr->isEof = 1;
|
||||
}
|
||||
@@ -410,7 +406,6 @@ static int fts3auxFilterMethod(
|
||||
sqlite3Fts3SegReaderFinish(&pCsr->csr);
|
||||
sqlite3_free((void *)pCsr->filter.zTerm);
|
||||
sqlite3_free(pCsr->aStat);
|
||||
sqlite3_free(pCsr->zStop);
|
||||
memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr);
|
||||
|
||||
pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY;
|
||||
@@ -421,15 +416,15 @@ static int fts3auxFilterMethod(
|
||||
assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
|
||||
if( zStr ){
|
||||
pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
|
||||
pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
|
||||
if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
|
||||
pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm);
|
||||
}
|
||||
}
|
||||
|
||||
if( iLe>=0 ){
|
||||
pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
|
||||
pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
|
||||
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
|
||||
pCsr->nStop = (int)strlen(pCsr->zStop);
|
||||
}
|
||||
|
||||
if( iLangid>=0 ){
|
||||
@@ -544,8 +539,7 @@ int sqlite3Fts3InitAux(sqlite3 *db){
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
0 /* xShadowName */
|
||||
0 /* xRollbackTo */
|
||||
};
|
||||
int rc; /* Return code */
|
||||
|
||||
|
||||
+69
-53
@@ -122,8 +122,8 @@ static int fts3isspace(char c){
|
||||
** zero the memory before returning a pointer to it. If unsuccessful,
|
||||
** return NULL.
|
||||
*/
|
||||
void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){
|
||||
void *pRet = sqlite3_malloc64(nByte);
|
||||
static void *fts3MallocZero(int nByte){
|
||||
void *pRet = sqlite3_malloc(nByte);
|
||||
if( pRet ) memset(pRet, 0, nByte);
|
||||
return pRet;
|
||||
}
|
||||
@@ -198,12 +198,12 @@ static int getNextToken(
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zToken;
|
||||
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
|
||||
sqlite3_int64 nByte; /* total space to allocate */
|
||||
int nByte; /* total space to allocate */
|
||||
|
||||
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
|
||||
if( rc==SQLITE_OK ){
|
||||
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
|
||||
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
|
||||
pRet = (Fts3Expr *)fts3MallocZero(nByte);
|
||||
if( !pRet ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -252,8 +252,8 @@ static int getNextToken(
|
||||
** Enlarge a memory allocation. If an out-of-memory allocation occurs,
|
||||
** then free the old allocation.
|
||||
*/
|
||||
static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){
|
||||
void *pRet = sqlite3_realloc64(pOrig, nNew);
|
||||
static void *fts3ReallocOrFree(void *pOrig, int nNew){
|
||||
void *pRet = sqlite3_realloc(pOrig, nNew);
|
||||
if( !pRet ){
|
||||
sqlite3_free(pOrig);
|
||||
}
|
||||
@@ -446,7 +446,10 @@ static int getNextNode(
|
||||
if( pKey->eType==FTSQUERY_NEAR ){
|
||||
assert( nKey==4 );
|
||||
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
|
||||
nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
|
||||
nNear = 0;
|
||||
for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
|
||||
nNear = nNear * 10 + (zInput[nKey] - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +461,7 @@ static int getNextNode(
|
||||
if( fts3isspace(cNext)
|
||||
|| cNext=='"' || cNext=='(' || cNext==')' || cNext==0
|
||||
){
|
||||
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr));
|
||||
pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
|
||||
if( !pRet ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -493,12 +496,8 @@ static int getNextNode(
|
||||
if( *zInput=='(' ){
|
||||
int nConsumed = 0;
|
||||
pParse->nNest++;
|
||||
#if !defined(SQLITE_MAX_EXPR_DEPTH)
|
||||
if( pParse->nNest>1000 ) return SQLITE_ERROR;
|
||||
#elif SQLITE_MAX_EXPR_DEPTH>0
|
||||
if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR;
|
||||
#endif
|
||||
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
|
||||
if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
|
||||
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
|
||||
return rc;
|
||||
}else if( *zInput==')' ){
|
||||
@@ -637,7 +636,7 @@ static int fts3ExprParse(
|
||||
&& p->eType==FTSQUERY_PHRASE && pParse->isNot
|
||||
){
|
||||
/* Create an implicit NOT operator. */
|
||||
Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
|
||||
Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
|
||||
if( !pNot ){
|
||||
sqlite3Fts3ExprFree(p);
|
||||
rc = SQLITE_NOMEM;
|
||||
@@ -671,7 +670,7 @@ static int fts3ExprParse(
|
||||
/* Insert an implicit AND operator. */
|
||||
Fts3Expr *pAnd;
|
||||
assert( pRet && pPrev );
|
||||
pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
|
||||
pAnd = fts3MallocZero(sizeof(Fts3Expr));
|
||||
if( !pAnd ){
|
||||
sqlite3Fts3ExprFree(p);
|
||||
rc = SQLITE_NOMEM;
|
||||
@@ -797,7 +796,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
|
||||
if( rc==SQLITE_OK ){
|
||||
if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
|
||||
Fts3Expr **apLeaf;
|
||||
apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
|
||||
apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
|
||||
if( 0==apLeaf ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -1109,6 +1108,34 @@ void sqlite3Fts3ExprFree(Fts3Expr *pDel){
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
** Function to query the hash-table of tokenizers (see README.tokenizers).
|
||||
*/
|
||||
static int queryTestTokenizer(
|
||||
sqlite3 *db,
|
||||
const char *zName,
|
||||
const sqlite3_tokenizer_module **pp
|
||||
){
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
const char zSql[] = "SELECT fts3_tokenizer(?)";
|
||||
|
||||
*pp = 0;
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
|
||||
memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
|
||||
}
|
||||
}
|
||||
|
||||
return sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to a buffer containing a text representation of the
|
||||
** expression passed as the first argument. The buffer is obtained from
|
||||
@@ -1176,12 +1203,12 @@ static char *exprToString(Fts3Expr *pExpr, char *zBuf){
|
||||
**
|
||||
** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
|
||||
*/
|
||||
static void fts3ExprTestCommon(
|
||||
int bRebalance,
|
||||
static void fts3ExprTest(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3_tokenizer_module const *pModule = 0;
|
||||
sqlite3_tokenizer *pTokenizer = 0;
|
||||
int rc;
|
||||
char **azCol = 0;
|
||||
@@ -1191,9 +1218,7 @@ static void fts3ExprTestCommon(
|
||||
int ii;
|
||||
Fts3Expr *pExpr;
|
||||
char *zBuf = 0;
|
||||
Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
|
||||
const char *zTokenizer = 0;
|
||||
char *zErr = 0;
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
|
||||
if( argc<3 ){
|
||||
sqlite3_result_error(context,
|
||||
@@ -1202,22 +1227,28 @@ static void fts3ExprTestCommon(
|
||||
return;
|
||||
}
|
||||
|
||||
zTokenizer = (const char*)sqlite3_value_text(argv[0]);
|
||||
rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
}
|
||||
sqlite3_free(zErr);
|
||||
return;
|
||||
rc = queryTestTokenizer(db,
|
||||
(const char *)sqlite3_value_text(argv[0]), &pModule);
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto exprtest_out;
|
||||
}else if( !pModule ){
|
||||
sqlite3_result_error(context, "No such tokenizer module", -1);
|
||||
goto exprtest_out;
|
||||
}
|
||||
|
||||
rc = pModule->xCreate(0, 0, &pTokenizer);
|
||||
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto exprtest_out;
|
||||
}
|
||||
pTokenizer->pModule = pModule;
|
||||
|
||||
zExpr = (const char *)sqlite3_value_text(argv[1]);
|
||||
nExpr = sqlite3_value_bytes(argv[1]);
|
||||
nCol = argc-2;
|
||||
azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *));
|
||||
azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
|
||||
if( !azCol ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto exprtest_out;
|
||||
@@ -1226,7 +1257,7 @@ static void fts3ExprTestCommon(
|
||||
azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
|
||||
}
|
||||
|
||||
if( bRebalance ){
|
||||
if( sqlite3_user_data(context) ){
|
||||
char *zDummy = 0;
|
||||
rc = sqlite3Fts3ExprParse(
|
||||
pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
|
||||
@@ -1252,38 +1283,23 @@ static void fts3ExprTestCommon(
|
||||
sqlite3Fts3ExprFree(pExpr);
|
||||
|
||||
exprtest_out:
|
||||
if( pTokenizer ){
|
||||
rc = pTokenizer->pModule->xDestroy(pTokenizer);
|
||||
if( pModule && pTokenizer ){
|
||||
rc = pModule->xDestroy(pTokenizer);
|
||||
}
|
||||
sqlite3_free(azCol);
|
||||
}
|
||||
|
||||
static void fts3ExprTest(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
fts3ExprTestCommon(0, context, argc, argv);
|
||||
}
|
||||
static void fts3ExprTestRebalance(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
fts3ExprTestCommon(1, context, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
** Register the query expression parser test function fts3_exprtest()
|
||||
** with database connection db.
|
||||
*/
|
||||
int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
|
||||
int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
|
||||
int rc = sqlite3_create_function(
|
||||
db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
|
||||
db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "fts3_exprtest_rebalance",
|
||||
-1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
|
||||
-1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
|
||||
);
|
||||
}
|
||||
return rc;
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
/*
|
||||
** Malloc and Free functions
|
||||
*/
|
||||
static void *fts3HashMalloc(sqlite3_int64 n){
|
||||
void *p = sqlite3_malloc64(n);
|
||||
static void *fts3HashMalloc(int n){
|
||||
void *p = sqlite3_malloc(n);
|
||||
if( p ){
|
||||
memset(p, 0, n);
|
||||
}
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ static int icuCreate(
|
||||
if( argc>0 ){
|
||||
n = strlen(argv[0])+1;
|
||||
}
|
||||
p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n);
|
||||
p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
|
||||
if( !p ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ static int icuOpen(
|
||||
nInput = strlen(zInput);
|
||||
}
|
||||
nChar = nInput+1;
|
||||
pCsr = (IcuCursor *)sqlite3_malloc64(
|
||||
pCsr = (IcuCursor *)sqlite3_malloc(
|
||||
sizeof(IcuCursor) + /* IcuCursor */
|
||||
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
|
||||
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
|
||||
|
||||
@@ -621,7 +621,7 @@ static int porterNext(
|
||||
if( n>c->nAllocated ){
|
||||
char *pNew;
|
||||
c->nAllocated = n+20;
|
||||
pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
|
||||
pNew = sqlite3_realloc(c->zToken, c->nAllocated);
|
||||
if( !pNew ) return SQLITE_NOMEM;
|
||||
c->zToken = pNew;
|
||||
}
|
||||
|
||||
+65
-110
@@ -17,10 +17,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
typedef sqlite3_int64 i64;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Characters that may appear in the second argument to matchinfo().
|
||||
*/
|
||||
@@ -71,9 +67,9 @@ struct SnippetIter {
|
||||
struct SnippetPhrase {
|
||||
int nToken; /* Number of tokens in phrase */
|
||||
char *pList; /* Pointer to start of phrase position list */
|
||||
i64 iHead; /* Next value in position list */
|
||||
int iHead; /* Next value in position list */
|
||||
char *pHead; /* Position list data following iHead */
|
||||
i64 iTail; /* Next value in trailing position list */
|
||||
int iTail; /* Next value in trailing position list */
|
||||
char *pTail; /* Position list data following iTail */
|
||||
};
|
||||
|
||||
@@ -132,18 +128,17 @@ struct StrBuffer {
|
||||
/*
|
||||
** Allocate a two-slot MatchinfoBuffer object.
|
||||
*/
|
||||
static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
|
||||
static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
|
||||
MatchinfoBuffer *pRet;
|
||||
sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
|
||||
+ sizeof(MatchinfoBuffer);
|
||||
sqlite3_int64 nStr = strlen(zMatchinfo);
|
||||
int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
|
||||
int nStr = (int)strlen(zMatchinfo);
|
||||
|
||||
pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
|
||||
pRet = sqlite3_malloc(nByte + nStr+1);
|
||||
if( pRet ){
|
||||
memset(pRet, 0, nByte);
|
||||
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
|
||||
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
|
||||
+ sizeof(u32)*((int)nElem+1);
|
||||
pRet->nElem = (int)nElem;
|
||||
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
|
||||
pRet->nElem = nElem;
|
||||
pRet->zMatchinfo = ((char*)pRet) + nByte;
|
||||
memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
|
||||
pRet->aRef[0] = 1;
|
||||
@@ -183,7 +178,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
|
||||
aOut = &p->aMatchinfo[p->nElem+2];
|
||||
xRet = fts3MIBufferFree;
|
||||
}else{
|
||||
aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
|
||||
aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
|
||||
if( aOut ){
|
||||
xRet = sqlite3_free;
|
||||
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
|
||||
@@ -237,7 +232,7 @@ void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
|
||||
** After it returns, *piPos contains the value of the next element of the
|
||||
** list and *pp is advanced to the following varint.
|
||||
*/
|
||||
static void fts3GetDeltaPosition(char **pp, i64 *piPos){
|
||||
static void fts3GetDeltaPosition(char **pp, int *piPos){
|
||||
int iVal;
|
||||
*pp += fts3GetVarint32(*pp, &iVal);
|
||||
*piPos += (iVal-2);
|
||||
@@ -346,10 +341,10 @@ static int fts3ExprPhraseCount(Fts3Expr *pExpr){
|
||||
** arguments so that it points to the first element with a value greater
|
||||
** than or equal to parameter iNext.
|
||||
*/
|
||||
static void fts3SnippetAdvance(char **ppIter, i64 *piIter, int iNext){
|
||||
static void fts3SnippetAdvance(char **ppIter, int *piIter, int iNext){
|
||||
char *pIter = *ppIter;
|
||||
if( pIter ){
|
||||
i64 iIter = *piIter;
|
||||
int iIter = *piIter;
|
||||
|
||||
while( iIter<iNext ){
|
||||
if( 0==(*pIter & 0xFE) ){
|
||||
@@ -432,14 +427,13 @@ static void fts3SnippetDetails(
|
||||
SnippetPhrase *pPhrase = &pIter->aPhrase[i];
|
||||
if( pPhrase->pTail ){
|
||||
char *pCsr = pPhrase->pTail;
|
||||
i64 iCsr = pPhrase->iTail;
|
||||
int iCsr = pPhrase->iTail;
|
||||
|
||||
while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
|
||||
while( iCsr<(iStart+pIter->nSnippet) ){
|
||||
int j;
|
||||
u64 mPhrase = (u64)1 << (i%64);
|
||||
u64 mPhrase = (u64)1 << i;
|
||||
u64 mPos = (u64)1 << (iCsr - iStart);
|
||||
assert( iCsr>=iStart && (iCsr - iStart)<=64 );
|
||||
assert( i>=0 );
|
||||
assert( iCsr>=iStart );
|
||||
if( (mCover|mCovered)&mPhrase ){
|
||||
iScore++;
|
||||
}else{
|
||||
@@ -478,17 +472,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||
rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr);
|
||||
assert( rc==SQLITE_OK || pCsr==0 );
|
||||
if( pCsr ){
|
||||
i64 iFirst = 0;
|
||||
int iFirst = 0;
|
||||
pPhrase->pList = pCsr;
|
||||
fts3GetDeltaPosition(&pCsr, &iFirst);
|
||||
if( iFirst<0 ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
}else{
|
||||
pPhrase->pHead = pCsr;
|
||||
pPhrase->pTail = pCsr;
|
||||
pPhrase->iHead = iFirst;
|
||||
pPhrase->iTail = iFirst;
|
||||
}
|
||||
assert( iFirst>=0 );
|
||||
pPhrase->pHead = pCsr;
|
||||
pPhrase->pTail = pCsr;
|
||||
pPhrase->iHead = iFirst;
|
||||
pPhrase->iTail = iFirst;
|
||||
}else{
|
||||
assert( rc!=SQLITE_OK || (
|
||||
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
|
||||
@@ -525,7 +516,7 @@ static int fts3BestSnippet(
|
||||
int rc; /* Return Code */
|
||||
int nList; /* Number of phrases in expression */
|
||||
SnippetIter sIter; /* Iterates through snippet candidates */
|
||||
sqlite3_int64 nByte; /* Number of bytes of space to allocate */
|
||||
int nByte; /* Number of bytes of space to allocate */
|
||||
int iBestScore = -1; /* Best snippet score found so far */
|
||||
int i; /* Loop counter */
|
||||
|
||||
@@ -543,10 +534,11 @@ static int fts3BestSnippet(
|
||||
** the required space using malloc().
|
||||
*/
|
||||
nByte = sizeof(SnippetPhrase) * nList;
|
||||
sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte);
|
||||
sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
|
||||
if( !sIter.aPhrase ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
memset(sIter.aPhrase, 0, nByte);
|
||||
|
||||
/* Initialize the contents of the SnippetIter object. Then iterate through
|
||||
** the set of phrases in the expression to populate the aPhrase[] array.
|
||||
@@ -562,7 +554,7 @@ static int fts3BestSnippet(
|
||||
/* Set the *pmSeen output variable. */
|
||||
for(i=0; i<nList; i++){
|
||||
if( sIter.aPhrase[i].pHead ){
|
||||
*pmSeen |= (u64)1 << (i%64);
|
||||
*pmSeen |= (u64)1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,8 +604,8 @@ static int fts3StringAppend(
|
||||
** appended data.
|
||||
*/
|
||||
if( pStr->n+nAppend+1>=pStr->nAlloc ){
|
||||
sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
|
||||
char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
|
||||
int nAlloc = pStr->nAlloc+nAppend+100;
|
||||
char *zNew = sqlite3_realloc(pStr->z, nAlloc);
|
||||
if( !zNew ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -668,7 +660,6 @@ static int fts3SnippetShift(
|
||||
|
||||
for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
|
||||
for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
|
||||
assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 );
|
||||
nDesired = (nLeft-nRight)/2;
|
||||
|
||||
/* Ideally, the start of the snippet should be pushed forward in the
|
||||
@@ -861,7 +852,7 @@ static int fts3ColumnlistCount(char **ppCollist){
|
||||
/*
|
||||
** This function gathers 'y' or 'b' data for a single phrase.
|
||||
*/
|
||||
static int fts3ExprLHits(
|
||||
static void fts3ExprLHits(
|
||||
Fts3Expr *pExpr, /* Phrase expression node */
|
||||
MatchInfo *p /* Matchinfo context */
|
||||
){
|
||||
@@ -878,7 +869,7 @@ static int fts3ExprLHits(
|
||||
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
|
||||
}
|
||||
|
||||
if( pIter ) while( 1 ){
|
||||
while( 1 ){
|
||||
int nHit = fts3ColumnlistCount(&pIter);
|
||||
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
|
||||
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||
@@ -891,29 +882,25 @@ static int fts3ExprLHits(
|
||||
if( *pIter!=0x01 ) break;
|
||||
pIter++;
|
||||
pIter += fts3GetVarint32(pIter, &iCol);
|
||||
if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Gather the results for matchinfo directives 'y' and 'b'.
|
||||
*/
|
||||
static int fts3ExprLHitGather(
|
||||
static void fts3ExprLHitGather(
|
||||
Fts3Expr *pExpr,
|
||||
MatchInfo *p
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
|
||||
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
|
||||
if( pExpr->pLeft ){
|
||||
rc = fts3ExprLHitGather(pExpr->pLeft, p);
|
||||
if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p);
|
||||
fts3ExprLHitGather(pExpr->pLeft, p);
|
||||
fts3ExprLHitGather(pExpr->pRight, p);
|
||||
}else{
|
||||
rc = fts3ExprLHits(pExpr, p);
|
||||
fts3ExprLHits(pExpr, p);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1003,8 +990,8 @@ static int fts3MatchinfoCheck(
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
size_t nVal; /* Number of integers output by cArg */
|
||||
static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
int nVal; /* Number of integers output by cArg */
|
||||
|
||||
switch( cArg ){
|
||||
case FTS3_MATCHINFO_NDOC:
|
||||
@@ -1040,15 +1027,11 @@ static int fts3MatchinfoSelectDoctotal(
|
||||
Fts3Table *pTab,
|
||||
sqlite3_stmt **ppStmt,
|
||||
sqlite3_int64 *pnDoc,
|
||||
const char **paLen,
|
||||
const char **ppEnd
|
||||
const char **paLen
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
const char *a;
|
||||
const char *pEnd;
|
||||
sqlite3_int64 nDoc;
|
||||
int n;
|
||||
|
||||
|
||||
if( !*ppStmt ){
|
||||
int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt);
|
||||
@@ -1057,20 +1040,12 @@ static int fts3MatchinfoSelectDoctotal(
|
||||
pStmt = *ppStmt;
|
||||
assert( sqlite3_data_count(pStmt)==1 );
|
||||
|
||||
n = sqlite3_column_bytes(pStmt, 0);
|
||||
a = sqlite3_column_blob(pStmt, 0);
|
||||
if( a==0 ){
|
||||
return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
pEnd = a + n;
|
||||
a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc);
|
||||
if( nDoc<=0 || a>pEnd ){
|
||||
return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
*pnDoc = nDoc;
|
||||
a += sqlite3Fts3GetVarint(a, &nDoc);
|
||||
if( nDoc==0 ) return FTS_CORRUPT_VTAB;
|
||||
*pnDoc = (u32)nDoc;
|
||||
|
||||
if( paLen ) *paLen = a;
|
||||
if( ppEnd ) *ppEnd = pEnd;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1110,12 +1085,10 @@ static int fts3MatchinfoLcsCb(
|
||||
** position list for the next column.
|
||||
*/
|
||||
static int fts3LcsIteratorAdvance(LcsIterator *pIter){
|
||||
char *pRead;
|
||||
char *pRead = pIter->pRead;
|
||||
sqlite3_int64 iRead;
|
||||
int rc = 0;
|
||||
|
||||
if( NEVER(pIter==0) ) return 1;
|
||||
pRead = pIter->pRead;
|
||||
pRead += sqlite3Fts3GetVarint(pRead, &iRead);
|
||||
if( iRead==0 || iRead==1 ){
|
||||
pRead = 0;
|
||||
@@ -1144,13 +1117,13 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
|
||||
int i;
|
||||
int iCol;
|
||||
int nToken = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
/* Allocate and populate the array of LcsIterator objects. The array
|
||||
** contains one element for each matchable phrase in the query.
|
||||
**/
|
||||
aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase);
|
||||
aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
|
||||
if( !aIter ) return SQLITE_NOMEM;
|
||||
memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
|
||||
|
||||
for(i=0; i<pInfo->nPhrase; i++){
|
||||
@@ -1164,16 +1137,13 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
|
||||
int nLive = 0; /* Number of iterators in aIter not at EOF */
|
||||
|
||||
for(i=0; i<pInfo->nPhrase; i++){
|
||||
int rc;
|
||||
LcsIterator *pIt = &aIter[i];
|
||||
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
|
||||
if( rc!=SQLITE_OK ) goto matchinfo_lcs_out;
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( pIt->pRead ){
|
||||
pIt->iPos = pIt->iPosOffset;
|
||||
fts3LcsIteratorAdvance(pIt);
|
||||
if( pIt->pRead==0 ){
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
goto matchinfo_lcs_out;
|
||||
}
|
||||
fts3LcsIteratorAdvance(&aIter[i]);
|
||||
nLive++;
|
||||
}
|
||||
}
|
||||
@@ -1205,9 +1175,8 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
|
||||
pInfo->aMatchinfo[iCol] = nLcs;
|
||||
}
|
||||
|
||||
matchinfo_lcs_out:
|
||||
sqlite3_free(aIter);
|
||||
return rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1252,7 +1221,7 @@ static int fts3MatchinfoValues(
|
||||
case FTS3_MATCHINFO_NDOC:
|
||||
if( bGlobal ){
|
||||
sqlite3_int64 nDoc = 0;
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0);
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0);
|
||||
pInfo->aMatchinfo[0] = (u32)nDoc;
|
||||
}
|
||||
break;
|
||||
@@ -1261,19 +1230,14 @@ static int fts3MatchinfoValues(
|
||||
if( bGlobal ){
|
||||
sqlite3_int64 nDoc; /* Number of rows in table */
|
||||
const char *a; /* Aggregate column length array */
|
||||
const char *pEnd; /* First byte past end of length array */
|
||||
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a, &pEnd);
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a);
|
||||
if( rc==SQLITE_OK ){
|
||||
int iCol;
|
||||
for(iCol=0; iCol<pInfo->nCol; iCol++){
|
||||
u32 iVal;
|
||||
sqlite3_int64 nToken;
|
||||
a += sqlite3Fts3GetVarint(a, &nToken);
|
||||
if( a>pEnd ){
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
break;
|
||||
}
|
||||
iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc);
|
||||
pInfo->aMatchinfo[iCol] = iVal;
|
||||
}
|
||||
@@ -1287,14 +1251,9 @@ static int fts3MatchinfoValues(
|
||||
if( rc==SQLITE_OK ){
|
||||
int iCol;
|
||||
const char *a = sqlite3_column_blob(pSelectDocsize, 0);
|
||||
const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0);
|
||||
for(iCol=0; iCol<pInfo->nCol; iCol++){
|
||||
sqlite3_int64 nToken;
|
||||
a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken);
|
||||
if( a>pEnd ){
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
break;
|
||||
}
|
||||
a += sqlite3Fts3GetVarint(a, &nToken);
|
||||
pInfo->aMatchinfo[iCol] = (u32)nToken;
|
||||
}
|
||||
}
|
||||
@@ -1311,9 +1270,9 @@ static int fts3MatchinfoValues(
|
||||
|
||||
case FTS3_MATCHINFO_LHITS_BM:
|
||||
case FTS3_MATCHINFO_LHITS: {
|
||||
size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||
int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||
memset(pInfo->aMatchinfo, 0, nZero);
|
||||
rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
|
||||
fts3ExprLHitGather(pCsr->pExpr, pInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1325,7 +1284,7 @@ static int fts3MatchinfoValues(
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
if( bGlobal ){
|
||||
if( pCsr->pDeferred ){
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0);
|
||||
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
|
||||
@@ -1380,7 +1339,7 @@ static void fts3GetMatchinfo(
|
||||
** initialize those elements that are constant for every row.
|
||||
*/
|
||||
if( pCsr->pMIBuffer==0 ){
|
||||
size_t nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||
int nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||
int i; /* Used to iterate through zArg */
|
||||
|
||||
/* Determine the number of phrases in the query */
|
||||
@@ -1465,10 +1424,6 @@ void sqlite3Fts3Snippet(
|
||||
return;
|
||||
}
|
||||
|
||||
/* Limit the snippet length to 64 tokens. */
|
||||
if( nToken<-64 ) nToken = -64;
|
||||
if( nToken>+64 ) nToken = +64;
|
||||
|
||||
for(nSnippet=1; 1; nSnippet++){
|
||||
|
||||
int iSnip; /* Loop counter 0..nSnippet-1 */
|
||||
@@ -1542,8 +1497,8 @@ typedef struct TermOffsetCtx TermOffsetCtx;
|
||||
|
||||
struct TermOffset {
|
||||
char *pList; /* Position-list */
|
||||
i64 iPos; /* Position just read from pList */
|
||||
i64 iOff; /* Offset of this term from read positions */
|
||||
int iPos; /* Position just read from pList */
|
||||
int iOff; /* Offset of this term from read positions */
|
||||
};
|
||||
|
||||
struct TermOffsetCtx {
|
||||
@@ -1562,7 +1517,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||
int nTerm; /* Number of tokens in phrase */
|
||||
int iTerm; /* For looping through nTerm phrase terms */
|
||||
char *pList; /* Pointer to position list for phrase */
|
||||
i64 iPos = 0; /* First position in position-list */
|
||||
int iPos = 0; /* First position in position-list */
|
||||
int rc;
|
||||
|
||||
UNUSED_PARAMETER(iPhrase);
|
||||
@@ -1570,7 +1525,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||
nTerm = pExpr->pPhrase->nToken;
|
||||
if( pList ){
|
||||
fts3GetDeltaPosition(&pList, &iPos);
|
||||
assert_fts3_nc( iPos>=0 );
|
||||
assert( iPos>=0 );
|
||||
}
|
||||
|
||||
for(iTerm=0; iTerm<nTerm; iTerm++){
|
||||
@@ -1611,7 +1566,7 @@ void sqlite3Fts3Offsets(
|
||||
if( rc!=SQLITE_OK ) goto offsets_out;
|
||||
|
||||
/* Allocate the array of TermOffset iterators. */
|
||||
sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
|
||||
sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken);
|
||||
if( 0==sCtx.aTerm ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto offsets_out;
|
||||
@@ -1632,13 +1587,13 @@ void sqlite3Fts3Offsets(
|
||||
const char *zDoc;
|
||||
int nDoc;
|
||||
|
||||
/* Initialize the contents of sCtx.aTerm[] for column iCol. This
|
||||
** operation may fail if the database contains corrupt records.
|
||||
/* Initialize the contents of sCtx.aTerm[] for column iCol. There is
|
||||
** no way that this operation can fail, so the return code from
|
||||
** fts3ExprIterate() can be discarded.
|
||||
*/
|
||||
sCtx.iCol = iCol;
|
||||
sCtx.iTerm = 0;
|
||||
rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
|
||||
if( rc!=SQLITE_OK ) goto offsets_out;
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
|
||||
|
||||
/* Retreive the text stored in column iCol. If an SQL NULL is stored
|
||||
** in column iCol, jump immediately to the next iteration of the loop.
|
||||
@@ -1680,7 +1635,7 @@ void sqlite3Fts3Offsets(
|
||||
/* All offsets for this column have been gathered. */
|
||||
rc = SQLITE_DONE;
|
||||
}else{
|
||||
assert_fts3_nc( iCurrent<=iMinPos );
|
||||
assert( iCurrent<=iMinPos );
|
||||
if( 0==(0xFE&*pTerm->pList) ){
|
||||
pTerm->pList = 0;
|
||||
}else{
|
||||
|
||||
@@ -68,9 +68,9 @@ static int fts3termConnectMethod(
|
||||
char const *zFts3; /* Name of fts3 table */
|
||||
int nDb; /* Result of strlen(zDb) */
|
||||
int nFts3; /* Result of strlen(zFts3) */
|
||||
sqlite3_int64 nByte; /* Bytes of space to allocate here */
|
||||
int nByte; /* Bytes of space to allocate here */
|
||||
int rc; /* value returned by declare_vtab() */
|
||||
Fts3termTable *p; /* Virtual table object to return */
|
||||
Fts3termTable *p; /* Virtual table object to return */
|
||||
int iIndex = 0;
|
||||
|
||||
UNUSED_PARAMETER(pCtx);
|
||||
@@ -96,9 +96,9 @@ static int fts3termConnectMethod(
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
nByte = sizeof(Fts3termTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
|
||||
p = (Fts3termTable *)sqlite3_malloc64(nByte);
|
||||
p = (Fts3termTable *)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
memset(p, 0, (size_t)nByte);
|
||||
memset(p, 0, nByte);
|
||||
|
||||
p->pFts3Tab = (Fts3Table *)&p[1];
|
||||
p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1];
|
||||
@@ -361,8 +361,7 @@ int sqlite3Fts3InitTerm(sqlite3 *db){
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
0 /* xShadowName */
|
||||
0 /* xRollbackTo */
|
||||
};
|
||||
int rc; /* Return code */
|
||||
|
||||
|
||||
+5
-36
@@ -448,14 +448,14 @@ static int testTokenizerNext(
|
||||
}else{
|
||||
/* Advance to the end of the token */
|
||||
const char *pToken = p;
|
||||
sqlite3_int64 nToken;
|
||||
int nToken;
|
||||
while( p<pEnd && testIsTokenChar(*p) ) p++;
|
||||
nToken = (sqlite3_int64)(p-pToken);
|
||||
nToken = (int)(p-pToken);
|
||||
|
||||
/* Copy the token into the buffer */
|
||||
if( nToken>pCsr->nBuffer ){
|
||||
sqlite3_free(pCsr->aBuffer);
|
||||
pCsr->aBuffer = sqlite3_malloc64(nToken);
|
||||
pCsr->aBuffer = sqlite3_malloc(nToken);
|
||||
}
|
||||
if( pCsr->aBuffer==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
@@ -471,7 +471,7 @@ static int testTokenizerNext(
|
||||
pCsr->iInput = (int)(p - pCsr->aInput);
|
||||
|
||||
*ppToken = pCsr->aBuffer;
|
||||
*pnBytes = (int)nToken;
|
||||
*pnBytes = nToken;
|
||||
*piStartOffset = (int)(pToken - pCsr->aInput);
|
||||
*piEndOffset = (int)(p - pCsr->aInput);
|
||||
*piPosition = pCsr->iToken;
|
||||
@@ -574,35 +574,6 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
|
||||
** End of tokenizer code.
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
** sqlite3_fts3_may_be_corrupt BOOLEAN
|
||||
**
|
||||
** Set or clear the global "may-be-corrupt" flag. Return the old value.
|
||||
*/
|
||||
static int SQLITE_TCLAPI fts3_may_be_corrupt(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#ifdef SQLITE_DEBUG
|
||||
int bOld = sqlite3_fts3_may_be_corrupt;
|
||||
|
||||
if( objc!=2 && objc!=1 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?BOOLEAN?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==2 ){
|
||||
int bNew;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[1], &bNew) ) return TCL_ERROR;
|
||||
sqlite3_fts3_may_be_corrupt = bNew;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(bOld));
|
||||
#endif
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int Sqlitetestfts3_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(interp, "fts3_near_match", fts3_near_match_cmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp,
|
||||
@@ -611,12 +582,10 @@ int Sqlitetestfts3_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(
|
||||
interp, "fts3_test_tokenizer", fts3_test_tokenizer_cmd, 0, 0
|
||||
);
|
||||
|
||||
Tcl_CreateObjCommand(
|
||||
interp, "fts3_test_varint", fts3_test_varint_cmd, 0, 0
|
||||
);
|
||||
Tcl_CreateObjCommand(
|
||||
interp, "sqlite3_fts3_may_be_corrupt", fts3_may_be_corrupt, 0, 0
|
||||
);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_FTS3 || SQLITE_ENABLE_FTS4 */
|
||||
|
||||
@@ -122,7 +122,7 @@ static int fts3tokDequoteArray(
|
||||
nByte += (int)(strlen(argv[i]) + 1);
|
||||
}
|
||||
|
||||
*pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
|
||||
*pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
|
||||
if( azDequote==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -188,8 +188,7 @@ static int fts3tokConnectMethod(
|
||||
|
||||
assert( (rc==SQLITE_OK)==(pMod!=0) );
|
||||
if( rc==SQLITE_OK ){
|
||||
const char * const *azArg = 0;
|
||||
if( nDequote>1 ) azArg = (const char * const *)&azDequote[1];
|
||||
const char * const *azArg = (const char * const *)&azDequote[1];
|
||||
rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok);
|
||||
}
|
||||
|
||||
@@ -347,11 +346,11 @@ static int fts3tokFilterMethod(
|
||||
if( idxNum==1 ){
|
||||
const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
|
||||
int nByte = sqlite3_value_bytes(apVal[0]);
|
||||
pCsr->zInput = sqlite3_malloc64(nByte+1);
|
||||
pCsr->zInput = sqlite3_malloc(nByte+1);
|
||||
if( pCsr->zInput==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
|
||||
memcpy(pCsr->zInput, zByte, nByte);
|
||||
pCsr->zInput[nByte] = 0;
|
||||
rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -420,7 +419,7 @@ static int fts3tokRowidMethod(
|
||||
** Register the fts3tok module with database connection db. Return SQLITE_OK
|
||||
** if successful or an error code if sqlite3_create_module() fails.
|
||||
*/
|
||||
int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){
|
||||
int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
|
||||
static const sqlite3_module fts3tok_module = {
|
||||
0, /* iVersion */
|
||||
fts3tokConnectMethod, /* xCreate */
|
||||
@@ -444,14 +443,11 @@ int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
0 /* xShadowName */
|
||||
0 /* xRollbackTo */
|
||||
};
|
||||
int rc; /* Return code */
|
||||
|
||||
rc = sqlite3_create_module_v2(
|
||||
db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy
|
||||
);
|
||||
rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ static void fts3TokenizerFunc(
|
||||
nName = sqlite3_value_bytes(argv[0])+1;
|
||||
|
||||
if( argc==2 ){
|
||||
if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
|
||||
if( fts3TokenizerEnabled(context) ){
|
||||
void *pOld;
|
||||
int n = sqlite3_value_bytes(argv[1]);
|
||||
if( zName==0 || n!=sizeof(pPtr) ){
|
||||
@@ -106,9 +106,7 @@ static void fts3TokenizerFunc(
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){
|
||||
sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
|
||||
}
|
||||
sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
int sqlite3Fts3IsIdChar(char c){
|
||||
@@ -196,8 +194,8 @@ int sqlite3Fts3InitTokenizer(
|
||||
int iArg = 0;
|
||||
z = &z[n+1];
|
||||
while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){
|
||||
sqlite3_int64 nNew = sizeof(char *)*(iArg+1);
|
||||
char const **aNew = (const char **)sqlite3_realloc64((void *)aArg, nNew);
|
||||
int nNew = sizeof(char *)*(iArg+1);
|
||||
char const **aNew = (const char **)sqlite3_realloc((void *)aArg, nNew);
|
||||
if( !aNew ){
|
||||
sqlite3_free(zCopy);
|
||||
sqlite3_free((void *)aArg);
|
||||
@@ -390,9 +388,7 @@ int queryTokenizer(
|
||||
|
||||
sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB
|
||||
&& sqlite3_column_bytes(pStmt, 0)==sizeof(*pp)
|
||||
){
|
||||
if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
|
||||
memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
|
||||
}
|
||||
}
|
||||
@@ -481,7 +477,7 @@ int sqlite3Fts3InitHashTable(
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
void *p = (void *)pHash;
|
||||
const int any = SQLITE_UTF8|SQLITE_DIRECTONLY;
|
||||
const int any = SQLITE_ANY;
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
char *zTest = 0;
|
||||
|
||||
@@ -185,7 +185,7 @@ static int simpleNext(
|
||||
if( n>c->nTokenAllocated ){
|
||||
char *pNew;
|
||||
c->nTokenAllocated = n+20;
|
||||
pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
|
||||
pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
|
||||
if( !pNew ) return SQLITE_NOMEM;
|
||||
c->pToken = pNew;
|
||||
}
|
||||
|
||||
+7
-11
@@ -82,7 +82,7 @@ typedef struct unicode_cursor unicode_cursor;
|
||||
|
||||
struct unicode_tokenizer {
|
||||
sqlite3_tokenizer base;
|
||||
int eRemoveDiacritic;
|
||||
int bRemoveDiacritic;
|
||||
int nException;
|
||||
int *aiException;
|
||||
};
|
||||
@@ -155,7 +155,7 @@ static int unicodeAddExceptions(
|
||||
int *aNew; /* New aiException[] array */
|
||||
int nNew; /* Number of valid entries in array aNew[] */
|
||||
|
||||
aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int));
|
||||
aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
|
||||
if( aNew==0 ) return SQLITE_NOMEM;
|
||||
nNew = p->nException;
|
||||
|
||||
@@ -227,20 +227,17 @@ static int unicodeCreate(
|
||||
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
|
||||
if( pNew==NULL ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(unicode_tokenizer));
|
||||
pNew->eRemoveDiacritic = 1;
|
||||
pNew->bRemoveDiacritic = 1;
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i++){
|
||||
const char *z = azArg[i];
|
||||
int n = (int)strlen(z);
|
||||
|
||||
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
|
||||
pNew->eRemoveDiacritic = 1;
|
||||
pNew->bRemoveDiacritic = 1;
|
||||
}
|
||||
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
|
||||
pNew->eRemoveDiacritic = 0;
|
||||
}
|
||||
else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){
|
||||
pNew->eRemoveDiacritic = 2;
|
||||
pNew->bRemoveDiacritic = 0;
|
||||
}
|
||||
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
|
||||
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
|
||||
@@ -285,7 +282,6 @@ static int unicodeOpen(
|
||||
pCsr->aInput = (const unsigned char *)aInput;
|
||||
if( aInput==0 ){
|
||||
pCsr->nInput = 0;
|
||||
pCsr->aInput = (const unsigned char*)"";
|
||||
}else if( nInput<0 ){
|
||||
pCsr->nInput = (int)strlen(aInput);
|
||||
}else{
|
||||
@@ -345,7 +341,7 @@ static int unicodeNext(
|
||||
|
||||
/* Grow the output buffer if required. */
|
||||
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
|
||||
char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64);
|
||||
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
|
||||
if( !zNew ) return SQLITE_NOMEM;
|
||||
zOut = &zNew[zOut - pCsr->zToken];
|
||||
pCsr->zToken = zNew;
|
||||
@@ -354,7 +350,7 @@ static int unicodeNext(
|
||||
|
||||
/* Write the folded case of the last character read to the output */
|
||||
zEnd = z;
|
||||
iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic);
|
||||
iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
|
||||
if( iOut ){
|
||||
WRITE_UTF8(zOut, iOut);
|
||||
}
|
||||
|
||||
+26
-45
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** 2012-05-25
|
||||
** 2012 May 25
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
@@ -159,48 +159,32 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
** E"). The resuls of passing a codepoint that corresponds to an
|
||||
** uppercase letter are undefined.
|
||||
*/
|
||||
static int remove_diacritic(int c, int bComplex){
|
||||
static int remove_diacritic(int c){
|
||||
unsigned short aDia[] = {
|
||||
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
|
||||
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
|
||||
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
|
||||
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
|
||||
3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
|
||||
3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
|
||||
4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
|
||||
4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
|
||||
6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
|
||||
61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
|
||||
61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
|
||||
61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
|
||||
62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
|
||||
62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
|
||||
62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
|
||||
63182, 63242, 63274, 63310, 63368, 63390,
|
||||
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
|
||||
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
|
||||
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
|
||||
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
|
||||
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
|
||||
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
|
||||
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
|
||||
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
|
||||
62924, 63050, 63082, 63274, 63390,
|
||||
};
|
||||
#define HIBIT ((unsigned char)0x80)
|
||||
unsigned char aChar[] = {
|
||||
'\0', 'a', 'c', 'e', 'i', 'n',
|
||||
'o', 'u', 'y', 'y', 'a', 'c',
|
||||
'd', 'e', 'e', 'g', 'h', 'i',
|
||||
'j', 'k', 'l', 'n', 'o', 'r',
|
||||
's', 't', 'u', 'u', 'w', 'y',
|
||||
'z', 'o', 'u', 'a', 'i', 'o',
|
||||
'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
|
||||
'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
|
||||
'e', 'i', 'o', 'r', 'u', 's',
|
||||
't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
|
||||
'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', 'a', 'b',
|
||||
'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
|
||||
'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
|
||||
'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
|
||||
'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
|
||||
's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
|
||||
'w', 'x', 'y', 'z', 'h', 't',
|
||||
'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
|
||||
'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
|
||||
'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
|
||||
char aChar[] = {
|
||||
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
|
||||
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
|
||||
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
|
||||
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
|
||||
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
|
||||
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
|
||||
'e', 'i', 'o', 'u', 'y',
|
||||
};
|
||||
|
||||
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
|
||||
@@ -217,8 +201,7 @@ static int remove_diacritic(int c, int bComplex){
|
||||
}
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
|
||||
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,8 +214,8 @@ int sqlite3FtsUnicodeIsdiacritic(int c){
|
||||
unsigned int mask1 = 0x000361F8;
|
||||
if( c<768 || c>817 ) return 0;
|
||||
return (c < 768+32) ?
|
||||
(mask0 & ((unsigned int)1 << (c-768))) :
|
||||
(mask1 & ((unsigned int)1 << (c-768-32)));
|
||||
(mask0 & (1 << (c-768))) :
|
||||
(mask1 & (1 << (c-768-32)));
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +228,7 @@ int sqlite3FtsUnicodeIsdiacritic(int c){
|
||||
** The results are undefined if the value passed to this function
|
||||
** is less than zero.
|
||||
*/
|
||||
int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
|
||||
int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
|
||||
/* Each entry in the following array defines a rule for folding a range
|
||||
** of codepoints to lower case. The rule applies to a range of nRange
|
||||
** codepoints starting at codepoint iCode.
|
||||
@@ -368,9 +351,7 @@ int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
|
||||
assert( ret>0 );
|
||||
}
|
||||
|
||||
if( eRemoveDiacritic ){
|
||||
ret = remove_diacritic(ret, eRemoveDiacritic==2);
|
||||
}
|
||||
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
|
||||
}
|
||||
|
||||
else if( c>=66560 && c<66600 ){
|
||||
|
||||
+155
-284
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/tclsh
|
||||
#
|
||||
# This script builds a single C code file holding all of FTS3 code.
|
||||
# The name of the output file is fts3amal.c. To build this file,
|
||||
# first do:
|
||||
#
|
||||
# make target_source
|
||||
#
|
||||
# The make target above moves all of the source code files into
|
||||
# a subdirectory named "tsrc". (This script expects to find the files
|
||||
# there and will not work if they are not found.)
|
||||
#
|
||||
# After the "tsrc" directory has been created and populated, run
|
||||
# this script:
|
||||
#
|
||||
# tclsh mkfts3amal.tcl
|
||||
#
|
||||
# The amalgamated FTS3 code will be written into fts3amal.c
|
||||
#
|
||||
|
||||
# Open the output file and write a header comment at the beginning
|
||||
# of the file.
|
||||
#
|
||||
set out [open fts3amal.c w]
|
||||
set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
|
||||
puts $out [subst \
|
||||
{/******************************************************************************
|
||||
** This file is an amalgamation of separate C source files from the SQLite
|
||||
** Full Text Search extension 2 (fts3). By combining all the individual C
|
||||
** code files into this single large file, the entire code can be compiled
|
||||
** as a one translation unit. This allows many compilers to do optimizations
|
||||
** that would not be possible if the files were compiled separately. It also
|
||||
** makes the code easier to import into other projects.
|
||||
**
|
||||
** This amalgamation was generated on $today.
|
||||
*/}]
|
||||
|
||||
# These are the header files used by FTS3. The first time any of these
|
||||
# files are seen in a #include statement in the C code, include the complete
|
||||
# text of the file in-line. The file only needs to be included once.
|
||||
#
|
||||
foreach hdr {
|
||||
fts3.h
|
||||
fts3_hash.h
|
||||
fts3_tokenizer.h
|
||||
sqlite3.h
|
||||
sqlite3ext.h
|
||||
} {
|
||||
set available_hdr($hdr) 1
|
||||
}
|
||||
|
||||
# 78 stars used for comment formatting.
|
||||
set s78 \
|
||||
{*****************************************************************************}
|
||||
|
||||
# Insert a comment into the code
|
||||
#
|
||||
proc section_comment {text} {
|
||||
global out s78
|
||||
set n [string length $text]
|
||||
set nstar [expr {60 - $n}]
|
||||
set stars [string range $s78 0 $nstar]
|
||||
puts $out "/************** $text $stars/"
|
||||
}
|
||||
|
||||
# Read the source file named $filename and write it into the
|
||||
# sqlite3.c output file. If any #include statements are seen,
|
||||
# process them approprately.
|
||||
#
|
||||
proc copy_file {filename} {
|
||||
global seen_hdr available_hdr out
|
||||
set tail [file tail $filename]
|
||||
section_comment "Begin file $tail"
|
||||
set in [open $filename r]
|
||||
while {![eof $in]} {
|
||||
set line [gets $in]
|
||||
if {[regexp {^#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
|
||||
if {[info exists available_hdr($hdr)]} {
|
||||
if {$available_hdr($hdr)} {
|
||||
section_comment "Include $hdr in the middle of $tail"
|
||||
copy_file tsrc/$hdr
|
||||
section_comment "Continuing where we left off in $tail"
|
||||
}
|
||||
} elseif {![info exists seen_hdr($hdr)]} {
|
||||
set seen_hdr($hdr) 1
|
||||
puts $out $line
|
||||
}
|
||||
} elseif {[regexp {^#ifdef __cplusplus} $line]} {
|
||||
puts $out "#if 0"
|
||||
} elseif {[regexp {^#line} $line]} {
|
||||
# Skip #line directives.
|
||||
} else {
|
||||
puts $out $line
|
||||
}
|
||||
}
|
||||
close $in
|
||||
section_comment "End of $tail"
|
||||
}
|
||||
|
||||
|
||||
# Process the source files. Process files containing commonly
|
||||
# used subroutines first in order to help the compiler find
|
||||
# inlining opportunities.
|
||||
#
|
||||
foreach file {
|
||||
fts3.c
|
||||
fts3_hash.c
|
||||
fts3_porter.c
|
||||
fts3_tokenizer.c
|
||||
fts3_tokenizer1.c
|
||||
} {
|
||||
copy_file tsrc/$file
|
||||
}
|
||||
|
||||
close $out
|
||||
@@ -93,7 +93,7 @@ static int runSql(sqlite3 *db, const char *zFormat, ...){
|
||||
static void showSchema(sqlite3 *db, const char *zTab){
|
||||
sqlite3_stmt *pStmt;
|
||||
pStmt = prepare(db,
|
||||
"SELECT sql FROM sqlite_schema"
|
||||
"SELECT sql FROM sqlite_master"
|
||||
" WHERE name LIKE '%q%%'"
|
||||
" ORDER BY 1",
|
||||
zTab);
|
||||
@@ -831,7 +831,7 @@ int main(int argc, char **argv){
|
||||
sqlite3_stmt *pStmt;
|
||||
int cnt = 0;
|
||||
pStmt = prepare(db, "SELECT b.sql"
|
||||
" FROM sqlite_schema a, sqlite_schema b"
|
||||
" FROM sqlite_master a, sqlite_master b"
|
||||
" WHERE a.name GLOB '*_segdir'"
|
||||
" AND b.name=substr(a.name,1,length(a.name)-7)"
|
||||
" ORDER BY 1");
|
||||
|
||||
+20
-310
@@ -9,12 +9,11 @@ proc print_rd {map} {
|
||||
set nRange 1
|
||||
set iFirst [lindex $map 0 0]
|
||||
set cPrev [lindex $map 0 1]
|
||||
set fPrev [lindex $map 0 2]
|
||||
|
||||
foreach m [lrange $map 1 end] {
|
||||
foreach {i c f} $m {}
|
||||
foreach {i c} $m {}
|
||||
|
||||
if {$cPrev == $c && $fPrev==$f} {
|
||||
if {$cPrev == $c} {
|
||||
for {set j [expr $iFirst+$nRange]} {$j<$i} {incr j} {
|
||||
if {[info exists tl_lookup_table($j)]==0} break
|
||||
}
|
||||
@@ -30,16 +29,13 @@ proc print_rd {map} {
|
||||
|
||||
lappend lRange [list $iFirst $nRange]
|
||||
lappend aChar $cPrev
|
||||
lappend aFlag $fPrev
|
||||
|
||||
set iFirst $i
|
||||
set cPrev $c
|
||||
set fPrev $f
|
||||
set nRange 1
|
||||
}
|
||||
lappend lRange [list $iFirst $nRange]
|
||||
lappend aChar $cPrev
|
||||
lappend aFlag $fPrev
|
||||
|
||||
puts "/*"
|
||||
puts "** If the argument is a codepoint corresponding to a lowercase letter"
|
||||
@@ -49,7 +45,7 @@ proc print_rd {map} {
|
||||
puts "** E\"). The resuls of passing a codepoint that corresponds to an"
|
||||
puts "** uppercase letter are undefined."
|
||||
puts "*/"
|
||||
puts "static int ${::remove_diacritic}(int c, int bComplex)\{"
|
||||
puts "static int ${::remove_diacritic}(int c)\{"
|
||||
puts " unsigned short aDia\[\] = \{"
|
||||
puts -nonewline " 0, "
|
||||
set i 1
|
||||
@@ -63,19 +59,14 @@ proc print_rd {map} {
|
||||
}
|
||||
puts ""
|
||||
puts " \};"
|
||||
puts "#define HIBIT ((unsigned char)0x80)"
|
||||
puts " unsigned char aChar\[\] = \{"
|
||||
puts -nonewline " '\\0', "
|
||||
puts " char aChar\[\] = \{"
|
||||
puts -nonewline " '\\0', "
|
||||
set i 1
|
||||
foreach c $aChar f $aFlag {
|
||||
if { $f } {
|
||||
set str "'$c'|HIBIT, "
|
||||
} else {
|
||||
set str "'$c', "
|
||||
}
|
||||
if {$c == ""} { set str "'\\0', " }
|
||||
foreach c $aChar {
|
||||
set str "'$c', "
|
||||
if {$c == ""} { set str "'\\0', " }
|
||||
|
||||
if {($i % 6)==0} {puts "" ; puts -nonewline " " }
|
||||
if {($i % 12)==0} {puts "" ; puts -nonewline " " }
|
||||
incr i
|
||||
puts -nonewline "$str"
|
||||
}
|
||||
@@ -96,8 +87,7 @@ proc print_rd {map} {
|
||||
}
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
|
||||
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);}
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);}
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
@@ -105,8 +95,7 @@ proc print_isdiacritic {zFunc map} {
|
||||
|
||||
set lCode [list]
|
||||
foreach m $map {
|
||||
foreach {code char flag} $m {}
|
||||
if {$flag} continue
|
||||
foreach {code char} $m {}
|
||||
if {$code && $char == ""} { lappend lCode $code }
|
||||
}
|
||||
set lCode [lsort -integer $lCode]
|
||||
@@ -135,8 +124,8 @@ proc print_isdiacritic {zFunc map} {
|
||||
|
||||
puts " if( c<$iFirst || c>$iLast ) return 0;"
|
||||
puts " return (c < $iFirst+32) ?"
|
||||
puts " (mask0 & ((unsigned int)1 << (c-$iFirst))) :"
|
||||
puts " (mask1 & ((unsigned int)1 << (c-$iFirst-32)));"
|
||||
puts " (mask0 & (1 << (c-$iFirst))) :"
|
||||
puts " (mask1 & (1 << (c-$iFirst-32)));"
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
@@ -483,7 +472,7 @@ proc print_fold {zFunc} {
|
||||
puts "** The results are undefined if the value passed to this function"
|
||||
puts "** is less than zero."
|
||||
puts "*/"
|
||||
puts "int ${zFunc}\(int c, int eRemoveDiacritic)\{"
|
||||
puts "int ${zFunc}\(int c, int bRemoveDiacritic)\{"
|
||||
|
||||
set liOff [tl_generate_ioff_table $lRecord]
|
||||
tl_print_table_header
|
||||
@@ -527,9 +516,7 @@ proc print_fold {zFunc} {
|
||||
assert( ret>0 );
|
||||
}
|
||||
|
||||
if( eRemoveDiacritic ){
|
||||
ret = ${::remove_diacritic}(ret, eRemoveDiacritic==2);
|
||||
}
|
||||
if( bRemoveDiacritic ) ret = ${::remove_diacritic}(ret);
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -542,260 +529,6 @@ proc print_fold {zFunc} {
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
proc code {txt} {
|
||||
set txt [string trimright $txt]
|
||||
set txt [string trimleft $txt "\n"]
|
||||
set n [expr {[string length $txt] - [string length [string trim $txt]]}]
|
||||
set ret ""
|
||||
foreach L [split $txt "\n"] {
|
||||
append ret "[string range $L $n end]\n"
|
||||
}
|
||||
return [uplevel "subst -nocommands {$ret}"]
|
||||
}
|
||||
|
||||
proc intarray {lInt} {
|
||||
set ret ""
|
||||
set n [llength $lInt]
|
||||
for {set i 0} {$i < $n} {incr i 10} {
|
||||
append ret "\n "
|
||||
foreach int [lrange $lInt $i [expr $i+9]] {
|
||||
append ret [format "%-7s" "$int, "]
|
||||
}
|
||||
}
|
||||
append ret "\n "
|
||||
set ret
|
||||
}
|
||||
|
||||
proc categories_switch {Cvar first lSecond} {
|
||||
upvar $Cvar C
|
||||
set ret ""
|
||||
append ret "case '$first':\n"
|
||||
append ret " switch( zCat\[1\] ){\n"
|
||||
foreach s $lSecond {
|
||||
append ret " case '$s': aArray\[$C($first$s)\] = 1; break;\n"
|
||||
}
|
||||
append ret " case '*': \n"
|
||||
foreach s $lSecond {
|
||||
append ret " aArray\[$C($first$s)\] = 1;\n"
|
||||
}
|
||||
append ret " break;\n"
|
||||
append ret " default: return 1;"
|
||||
append ret " }\n"
|
||||
append ret " break;\n"
|
||||
}
|
||||
|
||||
# Argument is a list. Each element of which is itself a list of two elements:
|
||||
#
|
||||
# * the codepoint
|
||||
# * the category
|
||||
#
|
||||
# List elements are sorted in order of codepoint.
|
||||
#
|
||||
proc print_categories {lMap} {
|
||||
set categories {
|
||||
Cc Cf Cn Cs
|
||||
Ll Lm Lo Lt Lu
|
||||
Mc Me Mn
|
||||
Nd Nl No
|
||||
Pc Pd Pe Pf Pi Po Ps
|
||||
Sc Sk Sm So
|
||||
Zl Zp Zs
|
||||
|
||||
LC Co
|
||||
}
|
||||
|
||||
for {set i 0} {$i < [llength $categories]} {incr i} {
|
||||
set C([lindex $categories $i]) [expr 1+$i]
|
||||
}
|
||||
|
||||
set caseC [categories_switch C C {c f n s o}]
|
||||
set caseL [categories_switch C L {l m o t u C}]
|
||||
set caseM [categories_switch C M {c e n}]
|
||||
set caseN [categories_switch C N {d l o}]
|
||||
set caseP [categories_switch C P {c d e f i o s}]
|
||||
set caseS [categories_switch C S {c k m o}]
|
||||
set caseZ [categories_switch C Z {l p s}]
|
||||
|
||||
set nCat [expr [llength [array names C]] + 1]
|
||||
puts [code {
|
||||
int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
|
||||
aArray[0] = 1;
|
||||
switch( zCat[0] ){
|
||||
$caseC
|
||||
$caseL
|
||||
$caseM
|
||||
$caseN
|
||||
$caseP
|
||||
$caseS
|
||||
$caseZ
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}]
|
||||
|
||||
set nRepeat 0
|
||||
set first [lindex $lMap 0 0]
|
||||
set class [lindex $lMap 0 1]
|
||||
set prev -1
|
||||
|
||||
set CASE(0) "Lu"
|
||||
set CASE(1) "Ll"
|
||||
|
||||
foreach m $lMap {
|
||||
foreach {codepoint cl} $m {}
|
||||
set codepoint [expr "0x$codepoint"]
|
||||
if {$codepoint>=(1<<20)} continue
|
||||
|
||||
set bNew 0
|
||||
if {$codepoint!=($prev+1)} {
|
||||
set bNew 1
|
||||
} elseif {
|
||||
$cl==$class || ($class=="LC" && $cl==$CASE([expr $nRepeat & 0x01]))
|
||||
} {
|
||||
incr nRepeat
|
||||
} elseif {$class=="Lu" && $nRepeat==1 && $cl=="Ll"} {
|
||||
set class LC
|
||||
incr nRepeat
|
||||
} else {
|
||||
set bNew 1
|
||||
}
|
||||
if {$bNew} {
|
||||
lappend lEntries [list $first $class $nRepeat]
|
||||
set nRepeat 1
|
||||
set first $codepoint
|
||||
set class $cl
|
||||
}
|
||||
set prev $codepoint
|
||||
}
|
||||
if {$nRepeat>0} {
|
||||
lappend lEntries [list $first $class $nRepeat]
|
||||
}
|
||||
|
||||
set aBlock [list 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
|
||||
set aMap [list]
|
||||
foreach e $lEntries {
|
||||
foreach {cp class nRepeat} $e {}
|
||||
set block [expr ($cp>>16)]
|
||||
if {$block>0 && [lindex $aBlock $block]==0} {
|
||||
for {set i 1} {$i<=$block} {incr i} {
|
||||
if {[lindex $aBlock $i]==0} {
|
||||
lset aBlock $i [llength $aMap]
|
||||
}
|
||||
}
|
||||
}
|
||||
lappend aMap [expr {$cp & 0xFFFF}]
|
||||
lappend aData [expr {($nRepeat << 5) + $C($class)}]
|
||||
}
|
||||
for {set i 1} {$i<[llength $aBlock]} {incr i} {
|
||||
if {[lindex $aBlock $i]==0} {
|
||||
lset aBlock $i [llength $aMap]
|
||||
}
|
||||
}
|
||||
|
||||
set aBlockArray [intarray $aBlock]
|
||||
set aMapArray [intarray $aMap]
|
||||
set aDataArray [intarray $aData]
|
||||
puts [code {
|
||||
static u16 aFts5UnicodeBlock[] = {$aBlockArray};
|
||||
static u16 aFts5UnicodeMap[] = {$aMapArray};
|
||||
static u16 aFts5UnicodeData[] = {$aDataArray};
|
||||
|
||||
int sqlite3Fts5UnicodeCategory(u32 iCode) {
|
||||
int iRes = -1;
|
||||
int iHi;
|
||||
int iLo;
|
||||
int ret;
|
||||
u16 iKey;
|
||||
|
||||
if( iCode>=(1<<20) ){
|
||||
return 0;
|
||||
}
|
||||
iLo = aFts5UnicodeBlock[(iCode>>16)];
|
||||
iHi = aFts5UnicodeBlock[1+(iCode>>16)];
|
||||
iKey = (iCode & 0xFFFF);
|
||||
while( iHi>iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
assert( iTest>=iLo && iTest<iHi );
|
||||
if( iKey>=aFts5UnicodeMap[iTest] ){
|
||||
iRes = iTest;
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest;
|
||||
}
|
||||
}
|
||||
|
||||
if( iRes<0 ) return 0;
|
||||
if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
|
||||
ret = aFts5UnicodeData[iRes] & 0x1F;
|
||||
if( ret!=$C(LC) ) return ret;
|
||||
return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? $C(Ll) : $C(Lu);
|
||||
}
|
||||
|
||||
void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
|
||||
int i = 0;
|
||||
int iTbl = 0;
|
||||
while( i<128 ){
|
||||
int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
|
||||
int n = (aFts5UnicodeData[iTbl] >> 5) + i;
|
||||
for(; i<128 && i<n; i++){
|
||||
aAscii[i] = (u8)bToken;
|
||||
}
|
||||
iTbl++;
|
||||
}
|
||||
aAscii[0] = 0; /* 0x00 is never a token character */
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
proc print_test_categories {lMap} {
|
||||
|
||||
set lCP [list]
|
||||
foreach e $lMap {
|
||||
foreach {cp cat} $e {}
|
||||
if {[expr 0x$cp] < (1<<20)} {
|
||||
lappend lCP "{0x$cp, \"$cat\"}, "
|
||||
}
|
||||
}
|
||||
|
||||
set aCP "\n"
|
||||
for {set i 0} {$i < [llength $lCP]} {incr i 4} {
|
||||
append aCP " [join [lrange $lCP $i $i+3]]\n"
|
||||
}
|
||||
|
||||
|
||||
puts [code {
|
||||
static int categories_test (int *piCode){
|
||||
struct Codepoint {
|
||||
int iCode;
|
||||
const char *zCat;
|
||||
} aCP[] = {$aCP};
|
||||
int i;
|
||||
int iCP = 0;
|
||||
|
||||
for(i=0; i<1000000; i++){
|
||||
u8 aArray[40];
|
||||
int cat = 0;
|
||||
int c = 0;
|
||||
memset(aArray, 0, sizeof(aArray));
|
||||
if( aCP[iCP].iCode==i ){
|
||||
sqlite3Fts5UnicodeCatParse(aCP[iCP].zCat, aArray);
|
||||
iCP++;
|
||||
}else{
|
||||
aArray[0] = 1;
|
||||
}
|
||||
|
||||
c = sqlite3Fts5UnicodeCategory((u32)i);
|
||||
if( aArray[c]==0 ){
|
||||
*piCode = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
proc print_fold_test {zFunc mappings} {
|
||||
global tl_lookup_table
|
||||
|
||||
@@ -839,7 +572,7 @@ proc print_fold_test {zFunc mappings} {
|
||||
proc print_fileheader {} {
|
||||
puts [string trim {
|
||||
/*
|
||||
** 2012-05-25
|
||||
** 2012 May 25
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
@@ -872,21 +605,15 @@ proc print_test_main {} {
|
||||
puts "#include <stdio.h>"
|
||||
puts ""
|
||||
puts "int main(int argc, char **argv)\{"
|
||||
puts " int r1, r2, r3;"
|
||||
puts " int r1, r2;"
|
||||
puts " int code;"
|
||||
puts " r3 = 0;"
|
||||
puts " r1 = isalnum_test(&code);"
|
||||
puts " if( r1 ) printf(\"isalnum(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"isalnum(): test passed\\n\");"
|
||||
puts " r2 = fold_test(&code);"
|
||||
puts " if( r2 ) printf(\"fold(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"fold(): test passed\\n\");"
|
||||
if {$::generate_fts5_code} {
|
||||
puts " r3 = categories_test(&code);"
|
||||
puts " if( r3 ) printf(\"categories(): Problem with code %d\\n\",code);"
|
||||
puts " else printf(\"categories(): test passed\\n\");"
|
||||
}
|
||||
puts " return (r1 || r2 || r3);"
|
||||
puts " return (r1 || r2);"
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
@@ -924,18 +651,10 @@ for {set i 0} {$i < [llength $argv]-2} {incr i} {
|
||||
|
||||
print_fileheader
|
||||
|
||||
if {$::generate_test_code} {
|
||||
puts "typedef unsigned short int u16;"
|
||||
puts "typedef unsigned char u8;"
|
||||
puts "#include <string.h>"
|
||||
}
|
||||
|
||||
# Print the isalnum() function to stdout.
|
||||
#
|
||||
set lRange [an_load_separator_ranges]
|
||||
if {$generate_fts5_code==0} {
|
||||
print_isalnum ${function_prefix}UnicodeIsalnum $lRange
|
||||
}
|
||||
print_isalnum ${function_prefix}UnicodeIsalnum $lRange
|
||||
|
||||
# Leave a gap between the two generated C functions.
|
||||
#
|
||||
@@ -958,21 +677,12 @@ puts ""
|
||||
#
|
||||
print_fold ${function_prefix}UnicodeFold
|
||||
|
||||
if {$generate_fts5_code} {
|
||||
puts ""
|
||||
puts ""
|
||||
print_categories [cc_load_unicodedata_text ${unicodedata.txt}]
|
||||
}
|
||||
|
||||
# Print the test routines and main() function to stdout, if -test
|
||||
# was specified.
|
||||
#
|
||||
if {$::generate_test_code} {
|
||||
if {$generate_fts5_code==0} {
|
||||
print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange
|
||||
}
|
||||
print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange
|
||||
print_fold_test ${function_prefix}UnicodeFold $mappings
|
||||
print_test_categories [cc_load_unicodedata_text ${unicodedata.txt}]
|
||||
print_test_main
|
||||
}
|
||||
|
||||
|
||||
@@ -7,24 +7,12 @@
|
||||
# character that it should be replaced with, or an empty string if the
|
||||
# codepoint should simply be removed from the input. Examples:
|
||||
#
|
||||
# { 224 a 0 } (replace codepoint 224 to "a")
|
||||
# { 769 "" 0 } (remove codepoint 769 from input)
|
||||
# { 224 a } (replace codepoint 224 to "a")
|
||||
# { 769 "" } (remove codepoint 769 from input)
|
||||
#
|
||||
# Mappings are only returned for non-upper case codepoints. It is assumed
|
||||
# that the input has already been folded to lower case.
|
||||
#
|
||||
# The third value in the list is always either 0 or 1. 0 if the
|
||||
# UnicodeData.txt file maps the codepoint to a single ASCII character and
|
||||
# a diacritic, or 1 if the mapping is indirect. For example, consider the
|
||||
# two entries:
|
||||
#
|
||||
# 1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
|
||||
# 1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
|
||||
#
|
||||
# The first codepoint is a direct mapping (as 006F is ASCII and 0323 is a
|
||||
# diacritic). The second is an indirect mapping, as it maps to the
|
||||
# first codepoint plus 0302 (a diacritic).
|
||||
#
|
||||
proc rd_load_unicodedata_text {zName} {
|
||||
global tl_lookup_table
|
||||
|
||||
@@ -65,29 +53,18 @@ proc rd_load_unicodedata_text {zName} {
|
||||
set iAscii [expr "0x[lindex $character_decomposition_mapping 0]"]
|
||||
set iDia [expr "0x[lindex $character_decomposition_mapping 1]"]
|
||||
|
||||
# Filter out upper-case characters, as they will be mapped to their
|
||||
# lower-case equivalents before this data is used.
|
||||
if {[info exists tl_lookup_table($iCode)]} continue
|
||||
|
||||
# Check if this is an indirect mapping. If so, set bIndirect to true
|
||||
# and change $iAscii to the indirectly mappped ASCII character.
|
||||
set bIndirect 0
|
||||
if {[info exists dia($iDia)] && [info exists mapping($iAscii)]} {
|
||||
set iAscii $mapping($iAscii)
|
||||
set bIndirect 1
|
||||
}
|
||||
|
||||
if { ($iAscii >= 97 && $iAscii <= 122)
|
||||
|| ($iAscii >= 65 && $iAscii <= 90)
|
||||
} {
|
||||
lappend lRet [list $iCode [string tolower [format %c $iAscii]] $bIndirect]
|
||||
set mapping($iCode) $iAscii
|
||||
lappend lRet [list $iCode [string tolower [format %c $iAscii]]]
|
||||
set dia($iDia) 1
|
||||
}
|
||||
}
|
||||
|
||||
foreach d [array names dia] {
|
||||
lappend lRet [list $d "" 0]
|
||||
lappend lRet [list $d ""]
|
||||
}
|
||||
set lRet [lsort -integer -index 0 $lRet]
|
||||
|
||||
@@ -166,40 +143,4 @@ proc tl_load_casefolding_txt {zName} {
|
||||
}
|
||||
}
|
||||
|
||||
proc cc_load_unicodedata_text {zName} {
|
||||
set fd [open $zName]
|
||||
set lField {
|
||||
code
|
||||
character_name
|
||||
general_category
|
||||
canonical_combining_classes
|
||||
bidirectional_category
|
||||
character_decomposition_mapping
|
||||
decimal_digit_value
|
||||
digit_value
|
||||
numeric_value
|
||||
mirrored
|
||||
unicode_1_name
|
||||
iso10646_comment_field
|
||||
uppercase_mapping
|
||||
lowercase_mapping
|
||||
titlecase_mapping
|
||||
}
|
||||
set lRet [list]
|
||||
|
||||
while { ![eof $fd] } {
|
||||
set line [gets $fd]
|
||||
if {$line == ""} continue
|
||||
|
||||
set fields [split $line ";"]
|
||||
if {[llength $fields] != [llength $lField]} { error "parse error: $line" }
|
||||
foreach $lField $fields {}
|
||||
|
||||
lappend lRet [list $code $general_category]
|
||||
}
|
||||
|
||||
close $fd
|
||||
set lRet
|
||||
}
|
||||
|
||||
|
||||
|
||||
+19
-15
@@ -120,8 +120,12 @@ struct Fts5PhraseIter {
|
||||
**
|
||||
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
|
||||
** to the column in which it occurs and *piOff the token offset of the
|
||||
** first token of the phrase. Returns SQLITE_OK if successful, or an error
|
||||
** code (i.e. SQLITE_NOMEM) if an error occurs.
|
||||
** first token of the phrase. The exception is if the table was created
|
||||
** with the offsets=0 option specified. In this case *piOff is always
|
||||
** set to -1.
|
||||
**
|
||||
** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
|
||||
** if an error occurs.
|
||||
**
|
||||
** This API can be quite slow if used with an FTS5 table created with the
|
||||
** "detail=none" or "detail=column" option.
|
||||
@@ -159,10 +163,10 @@ struct Fts5PhraseIter {
|
||||
**
|
||||
** xSetAuxdata(pFts5, pAux, xDelete)
|
||||
**
|
||||
** Save the pointer passed as the second argument as the extension function's
|
||||
** Save the pointer passed as the second argument as the extension functions
|
||||
** "auxiliary data". The pointer may then be retrieved by the current or any
|
||||
** future invocation of the same fts5 extension function made as part of
|
||||
** the same MATCH query using the xGetAuxdata() API.
|
||||
** of the same MATCH query using the xGetAuxdata() API.
|
||||
**
|
||||
** Each extension function is allocated a single auxiliary data slot for
|
||||
** each FTS query (MATCH expression). If the extension function is invoked
|
||||
@@ -177,7 +181,7 @@ struct Fts5PhraseIter {
|
||||
** The xDelete callback, if one is specified, is also invoked on the
|
||||
** auxiliary data pointer after the FTS5 query has finished.
|
||||
**
|
||||
** If an error (e.g. an OOM condition) occurs within this function,
|
||||
** If an error (e.g. an OOM condition) occurs within this function, an
|
||||
** the auxiliary data is set to NULL and an error code returned. If the
|
||||
** xDelete parameter was not NULL, it is invoked on the auxiliary data
|
||||
** pointer before returning.
|
||||
@@ -401,8 +405,8 @@ struct Fts5ExtensionApi {
|
||||
**
|
||||
** There are several ways to approach this in FTS5:
|
||||
**
|
||||
** <ol><li> By mapping all synonyms to a single token. In this case, using
|
||||
** the above example, this means that the tokenizer returns the
|
||||
** <ol><li> By mapping all synonyms to a single token. In this case, the
|
||||
** In the above example, this means that the tokenizer returns the
|
||||
** same token for inputs "first" and "1st". Say that token is in
|
||||
** fact "first", so that when the user inserts the document "I won
|
||||
** 1st place" entries are added to the index for tokens "i", "won",
|
||||
@@ -410,11 +414,11 @@ struct Fts5ExtensionApi {
|
||||
** the tokenizer substitutes "first" for "1st" and the query works
|
||||
** as expected.
|
||||
**
|
||||
** <li> By querying the index for all synonyms of each query term
|
||||
** separately. In this case, when tokenizing query text, the
|
||||
** tokenizer may provide multiple synonyms for a single term
|
||||
** within the document. FTS5 then queries the index for each
|
||||
** synonym individually. For example, faced with the query:
|
||||
** <li> By adding multiple synonyms for a single term to the FTS index.
|
||||
** In this case, when tokenizing query text, the tokenizer may
|
||||
** provide multiple synonyms for a single term within the document.
|
||||
** FTS5 then queries the index for each synonym individually. For
|
||||
** example, faced with the query:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH 'first place'</codeblock>
|
||||
@@ -438,9 +442,9 @@ struct Fts5ExtensionApi {
|
||||
** "place".
|
||||
**
|
||||
** This way, even if the tokenizer does not provide synonyms
|
||||
** when tokenizing query text (it should not - to do so would be
|
||||
** when tokenizing query text (it should not - to do would be
|
||||
** inefficient), it doesn't matter if the user queries for
|
||||
** 'first + place' or '1st + place', as there are entries in the
|
||||
** 'first + place' or '1st + place', as there are entires in the
|
||||
** FTS index corresponding to both forms of the first token.
|
||||
** </ol>
|
||||
**
|
||||
@@ -468,7 +472,7 @@ struct Fts5ExtensionApi {
|
||||
** extra data to the FTS index or require FTS5 to query for multiple terms,
|
||||
** so it is efficient in terms of disk space and query speed. However, it
|
||||
** does not support prefix queries very well. If, as suggested above, the
|
||||
** token "first" is substituted for "1st" by the tokenizer, then the query:
|
||||
** token "first" is subsituted for "1st" by the tokenizer, then the query:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH '1s*'</codeblock>
|
||||
|
||||
+18
-81
@@ -35,20 +35,8 @@ typedef sqlite3_uint64 u64;
|
||||
#endif
|
||||
|
||||
#define testcase(x)
|
||||
|
||||
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
|
||||
# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
|
||||
#endif
|
||||
#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
|
||||
# define ALWAYS(X) (1)
|
||||
# define NEVER(X) (0)
|
||||
#elif !defined(NDEBUG)
|
||||
# define ALWAYS(X) ((X)?1:(assert(0),0))
|
||||
# define NEVER(X) ((X)?(assert(0),1):0)
|
||||
#else
|
||||
# define ALWAYS(X) (X)
|
||||
# define NEVER(X) (X)
|
||||
#endif
|
||||
#define ALWAYS(x) 1
|
||||
#define NEVER(x) 0
|
||||
|
||||
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
|
||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||
@@ -73,11 +61,6 @@ typedef sqlite3_uint64 u64;
|
||||
*/
|
||||
#define FTS5_MAX_PREFIX_INDEXES 31
|
||||
|
||||
/*
|
||||
** Maximum segments permitted in a single index
|
||||
*/
|
||||
#define FTS5_MAX_SEGMENT 2000
|
||||
|
||||
#define FTS5_DEFAULT_NEARDIST 10
|
||||
#define FTS5_DEFAULT_RANK "bm25"
|
||||
|
||||
@@ -104,12 +87,6 @@ extern int sqlite3_fts5_may_be_corrupt;
|
||||
# define assert_nc(x) assert(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A version of memcmp() that does not cause asan errors if one of the pointer
|
||||
** parameters is NULL and the number of bytes to compare is zero.
|
||||
*/
|
||||
#define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n)))
|
||||
|
||||
/* Mark a function parameter as unused, to suppress nuisance compiler
|
||||
** warnings. */
|
||||
#ifndef UNUSED_PARAM
|
||||
@@ -195,8 +172,6 @@ struct Fts5Config {
|
||||
char *zContentExprlist;
|
||||
Fts5Tokenizer *pTok;
|
||||
fts5_tokenizer *pTokApi;
|
||||
int bLock; /* True when table is preparing statement */
|
||||
int ePattern; /* FTS_PATTERN_XXX constant */
|
||||
|
||||
/* Values loaded from the %_config table */
|
||||
int iCookie; /* Incremented when %_config is modified */
|
||||
@@ -217,19 +192,17 @@ struct Fts5Config {
|
||||
};
|
||||
|
||||
/* Current expected value of %_config table 'version' field */
|
||||
#define FTS5_CURRENT_VERSION 4
|
||||
#define FTS5_CURRENT_VERSION 4
|
||||
|
||||
#define FTS5_CONTENT_NORMAL 0
|
||||
#define FTS5_CONTENT_NONE 1
|
||||
#define FTS5_CONTENT_EXTERNAL 2
|
||||
|
||||
#define FTS5_DETAIL_FULL 0
|
||||
#define FTS5_DETAIL_NONE 1
|
||||
#define FTS5_DETAIL_COLUMNS 2
|
||||
#define FTS5_DETAIL_FULL 0
|
||||
#define FTS5_DETAIL_NONE 1
|
||||
#define FTS5_DETAIL_COLUMNS 2
|
||||
|
||||
|
||||
#define FTS5_PATTERN_NONE 0
|
||||
#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */
|
||||
#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */
|
||||
|
||||
int sqlite3Fts5ConfigParse(
|
||||
Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
|
||||
@@ -286,7 +259,7 @@ void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
|
||||
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
|
||||
|
||||
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
|
||||
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c)
|
||||
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
|
||||
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
|
||||
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
|
||||
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
|
||||
@@ -301,7 +274,7 @@ void sqlite3Fts5Put32(u8*, int);
|
||||
int sqlite3Fts5Get32(const u8*);
|
||||
|
||||
#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
|
||||
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
|
||||
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
|
||||
|
||||
typedef struct Fts5PoslistReader Fts5PoslistReader;
|
||||
struct Fts5PoslistReader {
|
||||
@@ -336,7 +309,7 @@ int sqlite3Fts5PoslistNext64(
|
||||
);
|
||||
|
||||
/* Malloc utility */
|
||||
void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte);
|
||||
void *sqlite3Fts5MallocZero(int *pRc, int nByte);
|
||||
char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
|
||||
|
||||
/* Character set tests (like isspace(), isalpha() etc.) */
|
||||
@@ -437,19 +410,11 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
|
||||
*/
|
||||
void sqlite3Fts5IterClose(Fts5IndexIter*);
|
||||
|
||||
/*
|
||||
** Close the reader blob handle, if it is open.
|
||||
*/
|
||||
void sqlite3Fts5IndexCloseReader(Fts5Index*);
|
||||
|
||||
/*
|
||||
** This interface is used by the fts5vocab module.
|
||||
*/
|
||||
const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
|
||||
int sqlite3Fts5IterNextScan(Fts5IndexIter*);
|
||||
void *sqlite3Fts5StructureRef(Fts5Index*);
|
||||
void sqlite3Fts5StructureRelease(void*);
|
||||
int sqlite3Fts5StructureTest(Fts5Index*, void*);
|
||||
|
||||
|
||||
/*
|
||||
@@ -502,7 +467,7 @@ int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
|
||||
/*
|
||||
** Functions called by the storage module as part of integrity-check.
|
||||
*/
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum);
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
|
||||
|
||||
/*
|
||||
** Called during virtual module initialization to register UDF
|
||||
@@ -555,30 +520,19 @@ int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** Interface to code in fts5_main.c.
|
||||
** Interface to code in fts5.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Virtual-table object.
|
||||
*/
|
||||
typedef struct Fts5Table Fts5Table;
|
||||
struct Fts5Table {
|
||||
sqlite3_vtab base; /* Base class used by SQLite core */
|
||||
Fts5Config *pConfig; /* Virtual table configuration */
|
||||
Fts5Index *pIndex; /* Full-text index */
|
||||
};
|
||||
|
||||
int sqlite3Fts5GetTokenizer(
|
||||
Fts5Global*,
|
||||
const char **azArg,
|
||||
int nArg,
|
||||
Fts5Config*,
|
||||
Fts5Tokenizer**,
|
||||
fts5_tokenizer**,
|
||||
char **pzErr
|
||||
);
|
||||
|
||||
Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
|
||||
|
||||
int sqlite3Fts5FlushToDisk(Fts5Table*);
|
||||
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
|
||||
|
||||
/*
|
||||
** End of interface to code in fts5.c.
|
||||
@@ -611,9 +565,8 @@ void sqlite3Fts5HashClear(Fts5Hash*);
|
||||
|
||||
int sqlite3Fts5HashQuery(
|
||||
Fts5Hash*, /* Hash table to query */
|
||||
int nPre,
|
||||
const char *pTerm, int nTerm, /* Query term */
|
||||
void **ppObj, /* OUT: Pointer to doclist for pTerm */
|
||||
const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||||
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||||
);
|
||||
|
||||
@@ -656,7 +609,7 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
|
||||
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
|
||||
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
|
||||
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
|
||||
|
||||
int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
|
||||
void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
|
||||
@@ -701,19 +654,11 @@ struct Fts5Token {
|
||||
/* Parse a MATCH expression. */
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig,
|
||||
int bPhraseToAnd,
|
||||
int iCol, /* Column on LHS of MATCH operator */
|
||||
const char *zExpr,
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
);
|
||||
int sqlite3Fts5ExprPattern(
|
||||
Fts5Config *pConfig,
|
||||
int bGlob,
|
||||
int iCol,
|
||||
const char *zText,
|
||||
Fts5Expr **pp
|
||||
);
|
||||
|
||||
/*
|
||||
** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
|
||||
@@ -730,7 +675,6 @@ int sqlite3Fts5ExprEof(Fts5Expr*);
|
||||
i64 sqlite3Fts5ExprRowid(Fts5Expr*);
|
||||
|
||||
void sqlite3Fts5ExprFree(Fts5Expr*);
|
||||
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);
|
||||
|
||||
/* Called during startup to register a UDF with SQLite */
|
||||
int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
|
||||
@@ -822,10 +766,6 @@ int sqlite3Fts5AuxInit(fts5_api*);
|
||||
*/
|
||||
|
||||
int sqlite3Fts5TokenizerInit(fts5_api*);
|
||||
int sqlite3Fts5TokenizerPattern(
|
||||
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
||||
Fts5Tokenizer *pTok
|
||||
);
|
||||
/*
|
||||
** End of interface to code in fts5_tokenizer.c.
|
||||
**************************************************************************/
|
||||
@@ -844,12 +784,9 @@ int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
|
||||
/**************************************************************************
|
||||
** Interface to automatically generated code in fts5_unicode2.c.
|
||||
*/
|
||||
int sqlite3Fts5UnicodeIsalnum(int c);
|
||||
int sqlite3Fts5UnicodeIsdiacritic(int c);
|
||||
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
|
||||
|
||||
int sqlite3Fts5UnicodeCatParse(const char*, u8*);
|
||||
int sqlite3Fts5UnicodeCategory(u32 iCode);
|
||||
void sqlite3Fts5UnicodeAscii(u8*, u8*);
|
||||
/*
|
||||
** End of interface to code in fts5_unicode2.c.
|
||||
**************************************************************************/
|
||||
|
||||
+23
-23
@@ -136,7 +136,7 @@ static void fts5HighlightAppend(
|
||||
HighlightContext *p,
|
||||
const char *z, int n
|
||||
){
|
||||
if( *pRc==SQLITE_OK && z ){
|
||||
if( *pRc==SQLITE_OK ){
|
||||
if( n<0 ) n = (int)strlen(z);
|
||||
p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
|
||||
if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
|
||||
@@ -268,7 +268,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
|
||||
int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
|
||||
int *aNew;
|
||||
|
||||
aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int));
|
||||
aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
|
||||
if( aNew==0 ) return SQLITE_NOMEM;
|
||||
p->aFirst = aNew;
|
||||
p->nFirstAlloc = nNew;
|
||||
@@ -335,12 +335,11 @@ static int fts5SnippetScore(
|
||||
int nInst;
|
||||
int nScore = 0;
|
||||
int iLast = 0;
|
||||
sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken;
|
||||
|
||||
rc = pApi->xInstCount(pFts, &nInst);
|
||||
for(i=0; i<nInst && rc==SQLITE_OK; i++){
|
||||
rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
|
||||
if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){
|
||||
if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
|
||||
nScore += (aSeen[ip] ? 1 : 1000);
|
||||
aSeen[ip] = 1;
|
||||
if( iFirst<0 ) iFirst = iOff;
|
||||
@@ -350,10 +349,10 @@ static int fts5SnippetScore(
|
||||
|
||||
*pnScore = nScore;
|
||||
if( piPos ){
|
||||
sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
|
||||
int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
|
||||
if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
|
||||
if( iAdj<0 ) iAdj = 0;
|
||||
*piPos = (int)iAdj;
|
||||
*piPos = iAdj;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -443,9 +442,7 @@ static void fts5SnippetFunction(
|
||||
int jj;
|
||||
|
||||
rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
|
||||
if( ic!=i ) continue;
|
||||
if( io>nDocsize ) rc = FTS5_CORRUPT;
|
||||
if( rc!=SQLITE_OK ) continue;
|
||||
if( ic!=i || rc!=SQLITE_OK ) continue;
|
||||
memset(aSeen, 0, nPhrase);
|
||||
rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
|
||||
io, nToken, &nScore, &iAdj
|
||||
@@ -566,22 +563,22 @@ static int fts5Bm25GetData(
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Fts5Bm25Data *p; /* Object to return */
|
||||
|
||||
p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0);
|
||||
p = pApi->xGetAuxdata(pFts, 0);
|
||||
if( p==0 ){
|
||||
int nPhrase; /* Number of phrases in query */
|
||||
sqlite3_int64 nRow = 0; /* Number of rows in table */
|
||||
sqlite3_int64 nToken = 0; /* Number of tokens in table */
|
||||
sqlite3_int64 nByte; /* Bytes of space to allocate */
|
||||
int nByte; /* Bytes of space to allocate */
|
||||
int i;
|
||||
|
||||
/* Allocate the Fts5Bm25Data object */
|
||||
nPhrase = pApi->xPhraseCount(pFts);
|
||||
nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
|
||||
p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
|
||||
p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
|
||||
if( p==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(p, 0, (size_t)nByte);
|
||||
memset(p, 0, nByte);
|
||||
p->nPhrase = nPhrase;
|
||||
p->aIDF = (double*)&p[1];
|
||||
p->aFreq = &p->aIDF[nPhrase];
|
||||
@@ -589,7 +586,6 @@ static int fts5Bm25GetData(
|
||||
|
||||
/* Calculate the average document length for this FTS5 table */
|
||||
if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
|
||||
assert( rc!=SQLITE_OK || nRow>0 );
|
||||
if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
|
||||
if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
|
||||
|
||||
@@ -640,7 +636,7 @@ static void fts5Bm25Function(
|
||||
){
|
||||
const double k1 = 1.2; /* Constant "k1" from BM25 formula */
|
||||
const double b = 0.75; /* Constant "b" from BM25 formula */
|
||||
int rc; /* Error code */
|
||||
int rc = SQLITE_OK; /* Error code */
|
||||
double score = 0.0; /* SQL function return value */
|
||||
Fts5Bm25Data *pData; /* Values allocated/calculated once only */
|
||||
int i; /* Iterator variable */
|
||||
@@ -672,15 +668,17 @@ static void fts5Bm25Function(
|
||||
D = (double)nTok;
|
||||
}
|
||||
|
||||
/* Determine and return the BM25 score for the current row. Or, if an
|
||||
** error has occurred, throw an exception. */
|
||||
/* Determine the BM25 score for the current row. */
|
||||
for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){
|
||||
score += pData->aIDF[i] * (
|
||||
( aFreq[i] * (k1 + 1.0) ) /
|
||||
( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
|
||||
);
|
||||
}
|
||||
|
||||
/* If no error has occurred, return the calculated score. Otherwise,
|
||||
** throw an SQL exception. */
|
||||
if( rc==SQLITE_OK ){
|
||||
for(i=0; i<pData->nPhrase; i++){
|
||||
score += pData->aIDF[i] * (
|
||||
( aFreq[i] * (k1 + 1.0) ) /
|
||||
( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
|
||||
);
|
||||
}
|
||||
sqlite3_result_double(pCtx, -1.0 * score);
|
||||
}else{
|
||||
sqlite3_result_error_code(pCtx, rc);
|
||||
@@ -712,3 +710,5 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+18
-32
@@ -17,17 +17,17 @@
|
||||
|
||||
int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
|
||||
if( (u32)pBuf->nSpace<nByte ){
|
||||
u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
|
||||
u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
|
||||
u8 *pNew;
|
||||
while( nNew<nByte ){
|
||||
nNew = nNew * 2;
|
||||
}
|
||||
pNew = sqlite3_realloc64(pBuf->p, nNew);
|
||||
pNew = sqlite3_realloc(pBuf->p, nNew);
|
||||
if( pNew==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}else{
|
||||
pBuf->nSpace = (int)nNew;
|
||||
pBuf->nSpace = nNew;
|
||||
pBuf->p = pNew;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ void sqlite3Fts5Put32(u8 *aBuf, int iVal){
|
||||
}
|
||||
|
||||
int sqlite3Fts5Get32(const u8 *aBuf){
|
||||
return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]);
|
||||
return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -66,6 +66,7 @@ void sqlite3Fts5BufferAppendBlob(
|
||||
u32 nData,
|
||||
const u8 *pData
|
||||
){
|
||||
assert_nc( *pRc || nData>=0 );
|
||||
if( nData ){
|
||||
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
|
||||
memcpy(&pBuf->p[pBuf->n], pData, nData);
|
||||
@@ -175,28 +176,15 @@ int sqlite3Fts5PoslistNext64(
|
||||
return 1;
|
||||
}else{
|
||||
i64 iOff = *piOff;
|
||||
u32 iVal;
|
||||
int iVal;
|
||||
fts5FastGetVarint32(a, i, iVal);
|
||||
if( iVal<=1 ){
|
||||
if( iVal==0 ){
|
||||
*pi = i;
|
||||
return 0;
|
||||
}
|
||||
if( iVal==1 ){
|
||||
fts5FastGetVarint32(a, i, iVal);
|
||||
iOff = ((i64)iVal) << 32;
|
||||
assert( iOff>=0 );
|
||||
fts5FastGetVarint32(a, i, iVal);
|
||||
if( iVal<2 ){
|
||||
/* This is a corrupt record. So stop parsing it here. */
|
||||
*piOff = -1;
|
||||
return 1;
|
||||
}
|
||||
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
|
||||
}else{
|
||||
*piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF);
|
||||
}
|
||||
*piOff = iOff + (iVal-2);
|
||||
*pi = i;
|
||||
assert_nc( *piOff>=iOff );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -235,16 +223,14 @@ void sqlite3Fts5PoslistSafeAppend(
|
||||
i64 *piPrev,
|
||||
i64 iPos
|
||||
){
|
||||
if( iPos>=*piPrev ){
|
||||
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
|
||||
if( (iPos & colmask) != (*piPrev & colmask) ){
|
||||
pBuf->p[pBuf->n++] = 1;
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
|
||||
*piPrev = (iPos & colmask);
|
||||
}
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
|
||||
*piPrev = iPos;
|
||||
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
|
||||
if( (iPos & colmask) != (*piPrev & colmask) ){
|
||||
pBuf->p[pBuf->n++] = 1;
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
|
||||
*piPrev = (iPos & colmask);
|
||||
}
|
||||
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
|
||||
*piPrev = iPos;
|
||||
}
|
||||
|
||||
int sqlite3Fts5PoslistWriterAppend(
|
||||
@@ -258,14 +244,14 @@ int sqlite3Fts5PoslistWriterAppend(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){
|
||||
void *sqlite3Fts5MallocZero(int *pRc, int nByte){
|
||||
void *pRet = 0;
|
||||
if( *pRc==SQLITE_OK ){
|
||||
pRet = sqlite3_malloc64(nByte);
|
||||
pRet = sqlite3_malloc(nByte);
|
||||
if( pRet==0 ){
|
||||
if( nByte>0 ) *pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pRet, 0, (size_t)nByte);
|
||||
memset(pRet, 0, nByte);
|
||||
}
|
||||
}
|
||||
return pRet;
|
||||
|
||||
+15
-19
@@ -23,7 +23,7 @@
|
||||
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
|
||||
|
||||
/* Maximum allowed page size */
|
||||
#define FTS5_MAX_PAGE_SIZE (64*1024)
|
||||
#define FTS5_MAX_PAGE_SIZE (128*1024)
|
||||
|
||||
static int fts5_iswhitespace(char x){
|
||||
return (x==' ');
|
||||
@@ -150,7 +150,7 @@ static int fts5Dequote(char *z){
|
||||
assert( q=='[' || q=='\'' || q=='"' || q=='`' );
|
||||
if( q=='[' ) q = ']';
|
||||
|
||||
while( z[iIn] ){
|
||||
while( ALWAYS(z[iIn]) ){
|
||||
if( z[iIn]==q ){
|
||||
if( z[iIn+1]!=q ){
|
||||
/* Character iIn was the close quote. */
|
||||
@@ -295,7 +295,7 @@ static int fts5ConfigParseSpecial(
|
||||
|
||||
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
|
||||
const char *p = (const char*)zArg;
|
||||
sqlite3_int64 nArg = strlen(zArg) + 1;
|
||||
int nArg = (int)strlen(zArg) + 1;
|
||||
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
|
||||
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
|
||||
char *pSpace = pDel;
|
||||
@@ -325,7 +325,7 @@ static int fts5ConfigParseSpecial(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = sqlite3Fts5GetTokenizer(pGlobal,
|
||||
(const char**)azArg, (int)nArg, pConfig,
|
||||
(const char**)azArg, nArg, &pConfig->pTok, &pConfig->pTokApi,
|
||||
pzErr
|
||||
);
|
||||
}
|
||||
@@ -397,7 +397,9 @@ static int fts5ConfigParseSpecial(
|
||||
*/
|
||||
static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
|
||||
assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
|
||||
return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
|
||||
return sqlite3Fts5GetTokenizer(
|
||||
pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -423,8 +425,8 @@ static const char *fts5ConfigGobbleWord(
|
||||
){
|
||||
const char *zRet = 0;
|
||||
|
||||
sqlite3_int64 nIn = strlen(zIn);
|
||||
char *zOut = sqlite3_malloc64(nIn+1);
|
||||
int nIn = (int)strlen(zIn);
|
||||
char *zOut = sqlite3_malloc(nIn+1);
|
||||
|
||||
assert( *pRc==SQLITE_OK );
|
||||
*pbQuoted = 0;
|
||||
@@ -433,7 +435,7 @@ static const char *fts5ConfigGobbleWord(
|
||||
if( zOut==0 ){
|
||||
*pRc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memcpy(zOut, zIn, (size_t)(nIn+1));
|
||||
memcpy(zOut, zIn, nIn+1);
|
||||
if( fts5_isopenquote(zOut[0]) ){
|
||||
int ii = fts5Dequote(zOut);
|
||||
zRet = &zIn[ii];
|
||||
@@ -527,7 +529,7 @@ int sqlite3Fts5ConfigParse(
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Fts5Config *pRet; /* New object to return */
|
||||
int i;
|
||||
sqlite3_int64 nByte;
|
||||
int nByte;
|
||||
|
||||
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
|
||||
if( pRet==0 ) return SQLITE_NOMEM;
|
||||
@@ -537,7 +539,7 @@ int sqlite3Fts5ConfigParse(
|
||||
|
||||
nByte = nArg * (sizeof(char*) + sizeof(u8));
|
||||
pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
pRet->abUnindexed = pRet->azCol ? (u8*)&pRet->azCol[nArg] : 0;
|
||||
pRet->abUnindexed = (u8*)&pRet->azCol[nArg];
|
||||
pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
|
||||
pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
|
||||
pRet->bColumnsize = 1;
|
||||
@@ -562,7 +564,6 @@ int sqlite3Fts5ConfigParse(
|
||||
z = fts5ConfigSkipWhitespace(z);
|
||||
if( z && *z=='=' ){
|
||||
bOption = 1;
|
||||
assert( zOne!=0 );
|
||||
z++;
|
||||
if( bMustBeCol ) z = 0;
|
||||
}
|
||||
@@ -579,11 +580,7 @@ int sqlite3Fts5ConfigParse(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
if( bOption ){
|
||||
rc = fts5ConfigParseSpecial(pGlobal, pRet,
|
||||
ALWAYS(zOne)?zOne:"",
|
||||
zTwo?zTwo:"",
|
||||
pzErr
|
||||
);
|
||||
rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
|
||||
}else{
|
||||
rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
|
||||
zOne = 0;
|
||||
@@ -686,7 +683,7 @@ int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
|
||||
rc = sqlite3_declare_vtab(pConfig->db, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -831,7 +828,7 @@ int sqlite3Fts5ConfigSetValue(
|
||||
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
|
||||
pgsz = sqlite3_value_int(pVal);
|
||||
}
|
||||
if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){
|
||||
if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){
|
||||
*pbBadkey = 1;
|
||||
}else{
|
||||
pConfig->pgsz = pgsz;
|
||||
@@ -884,7 +881,6 @@ int sqlite3Fts5ConfigSetValue(
|
||||
*pbBadkey = 1;
|
||||
}else{
|
||||
if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
|
||||
if( nCrisisMerge>=FTS5_MAX_SEGMENT ) nCrisisMerge = FTS5_MAX_SEGMENT-1;
|
||||
pConfig->nCrisisMerge = nCrisisMerge;
|
||||
}
|
||||
}
|
||||
|
||||
+91
-320
@@ -36,7 +36,6 @@ void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
|
||||
#include <stdio.h>
|
||||
void sqlite3Fts5ParserTrace(FILE*, char*);
|
||||
#endif
|
||||
int sqlite3Fts5ParserFallback(int);
|
||||
|
||||
|
||||
struct Fts5Expr {
|
||||
@@ -128,14 +127,12 @@ struct Fts5Parse {
|
||||
int nPhrase; /* Size of apPhrase array */
|
||||
Fts5ExprPhrase **apPhrase; /* Array of all phrases */
|
||||
Fts5ExprNode *pExpr; /* Result of a successful parse */
|
||||
int bPhraseToAnd; /* Convert "a+b" to "a AND b" */
|
||||
};
|
||||
|
||||
void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
|
||||
va_list ap;
|
||||
va_start(ap, zFmt);
|
||||
if( pParse->rc==SQLITE_OK ){
|
||||
assert( pParse->zErr==0 );
|
||||
pParse->zErr = sqlite3_vmprintf(zFmt, ap);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
@@ -213,12 +210,11 @@ static int fts5ExprGetToken(
|
||||
return tok;
|
||||
}
|
||||
|
||||
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
|
||||
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
|
||||
static void fts5ParseFree(void *p){ sqlite3_free(p); }
|
||||
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig, /* FTS5 Configuration */
|
||||
int bPhraseToAnd,
|
||||
int iCol,
|
||||
const char *zExpr, /* Expression text */
|
||||
Fts5Expr **ppNew,
|
||||
@@ -234,7 +230,6 @@ int sqlite3Fts5ExprNew(
|
||||
*ppNew = 0;
|
||||
*pzErr = 0;
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
sParse.bPhraseToAnd = bPhraseToAnd;
|
||||
pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
|
||||
if( pEngine==0 ){ return SQLITE_NOMEM; }
|
||||
sParse.pConfig = pConfig;
|
||||
@@ -277,7 +272,6 @@ int sqlite3Fts5ExprNew(
|
||||
pNew->pConfig = pConfig;
|
||||
pNew->apExprPhrase = sParse.apPhrase;
|
||||
pNew->nPhrase = sParse.nPhrase;
|
||||
pNew->bDesc = 0;
|
||||
sParse.apPhrase = 0;
|
||||
}
|
||||
}else{
|
||||
@@ -289,81 +283,6 @@ int sqlite3Fts5ExprNew(
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is only called when using the special 'trigram' tokenizer.
|
||||
** Argument zText contains the text of a LIKE or GLOB pattern matched
|
||||
** against column iCol. This function creates and compiles an FTS5 MATCH
|
||||
** expression that will match a superset of the rows matched by the LIKE or
|
||||
** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
|
||||
** code.
|
||||
*/
|
||||
int sqlite3Fts5ExprPattern(
|
||||
Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp
|
||||
){
|
||||
i64 nText = strlen(zText);
|
||||
char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1);
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( zExpr==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
char aSpec[3];
|
||||
int iOut = 0;
|
||||
int i = 0;
|
||||
int iFirst = 0;
|
||||
|
||||
if( bGlob==0 ){
|
||||
aSpec[0] = '_';
|
||||
aSpec[1] = '%';
|
||||
aSpec[2] = 0;
|
||||
}else{
|
||||
aSpec[0] = '*';
|
||||
aSpec[1] = '?';
|
||||
aSpec[2] = '[';
|
||||
}
|
||||
|
||||
while( i<=nText ){
|
||||
if( i==nText
|
||||
|| zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2]
|
||||
){
|
||||
if( i-iFirst>=3 ){
|
||||
int jj;
|
||||
zExpr[iOut++] = '"';
|
||||
for(jj=iFirst; jj<i; jj++){
|
||||
zExpr[iOut++] = zText[jj];
|
||||
if( zText[jj]=='"' ) zExpr[iOut++] = '"';
|
||||
}
|
||||
zExpr[iOut++] = '"';
|
||||
zExpr[iOut++] = ' ';
|
||||
}
|
||||
if( zText[i]==aSpec[2] ){
|
||||
i += 2;
|
||||
if( zText[i-1]=='^' ) i++;
|
||||
while( i<nText && zText[i]!=']' ) i++;
|
||||
}
|
||||
iFirst = i+1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if( iOut>0 ){
|
||||
int bAnd = 0;
|
||||
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
bAnd = 1;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
iCol = pConfig->nCol;
|
||||
}
|
||||
}
|
||||
zExpr[iOut] = '\0';
|
||||
rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg);
|
||||
}else{
|
||||
*pp = 0;
|
||||
}
|
||||
sqlite3_free(zExpr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the expression node object passed as the only argument.
|
||||
*/
|
||||
@@ -389,42 +308,6 @@ void sqlite3Fts5ExprFree(Fts5Expr *p){
|
||||
}
|
||||
}
|
||||
|
||||
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
|
||||
Fts5Parse sParse;
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
|
||||
if( *pp1 ){
|
||||
Fts5Expr *p1 = *pp1;
|
||||
int nPhrase = p1->nPhrase + p2->nPhrase;
|
||||
|
||||
p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
|
||||
p2->pRoot = 0;
|
||||
|
||||
if( sParse.rc==SQLITE_OK ){
|
||||
Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
|
||||
p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
|
||||
);
|
||||
if( ap==0 ){
|
||||
sParse.rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
|
||||
for(i=0; i<p2->nPhrase; i++){
|
||||
ap[i] = p2->apExprPhrase[i];
|
||||
}
|
||||
p1->nPhrase = nPhrase;
|
||||
p1->apExprPhrase = ap;
|
||||
}
|
||||
}
|
||||
sqlite3_free(p2->apExprPhrase);
|
||||
sqlite3_free(p2);
|
||||
}else{
|
||||
*pp1 = p2;
|
||||
}
|
||||
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument pTerm must be a synonym iterator. Return the current rowid
|
||||
** that it points to.
|
||||
@@ -434,7 +317,6 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
|
||||
int bRetValid = 0;
|
||||
Fts5ExprTerm *p;
|
||||
|
||||
assert( pTerm );
|
||||
assert( pTerm->pSynonym );
|
||||
assert( bDesc==0 || bDesc==1 );
|
||||
for(p=pTerm; p; p=p->pSynonym){
|
||||
@@ -473,8 +355,8 @@ static int fts5ExprSynonymList(
|
||||
if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
|
||||
if( pIter->nData==0 ) continue;
|
||||
if( nIter==nAlloc ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
|
||||
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
|
||||
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
|
||||
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||
if( aNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto synonym_poslist_out;
|
||||
@@ -554,8 +436,8 @@ static int fts5ExprPhraseIsMatch(
|
||||
/* If the aStatic[] array is not large enough, allocate a large array
|
||||
** using sqlite3_malloc(). This approach could be improved upon. */
|
||||
if( pPhrase->nTerm>ArraySize(aStatic) ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
|
||||
aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
|
||||
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
|
||||
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
|
||||
if( !aIter ) return SQLITE_NOMEM;
|
||||
}
|
||||
memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
|
||||
@@ -689,7 +571,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
|
||||
/* If the aStatic[] array is not large enough, allocate a large array
|
||||
** using sqlite3_malloc(). This approach could be improved upon. */
|
||||
if( pNear->nPhrase>ArraySize(aStatic) ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
|
||||
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
|
||||
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
}else{
|
||||
memset(aStatic, 0, sizeof(aStatic));
|
||||
@@ -1502,8 +1384,8 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
|
||||
}
|
||||
|
||||
/* If the iterator is not at a real match, skip forward until it is. */
|
||||
while( pRoot->bNomatch && rc==SQLITE_OK ){
|
||||
assert( pRoot->bEof==0 );
|
||||
while( pRoot->bNomatch ){
|
||||
assert( pRoot->bEof==0 && rc==SQLITE_OK );
|
||||
rc = fts5ExprNodeNext(p, pRoot, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
@@ -1598,20 +1480,18 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
|
||||
return pNear;
|
||||
}
|
||||
if( pNear==0 ){
|
||||
sqlite3_int64 nByte;
|
||||
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
|
||||
pRet = sqlite3_malloc64(nByte);
|
||||
int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
|
||||
pRet = sqlite3_malloc(nByte);
|
||||
if( pRet==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pRet, 0, (size_t)nByte);
|
||||
memset(pRet, 0, nByte);
|
||||
}
|
||||
}else if( (pNear->nPhrase % SZALLOC)==0 ){
|
||||
int nNew = pNear->nPhrase + SZALLOC;
|
||||
sqlite3_int64 nByte;
|
||||
int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
|
||||
|
||||
nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
|
||||
pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
|
||||
pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
|
||||
if( pRet==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}
|
||||
@@ -1627,9 +1507,6 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
|
||||
}else{
|
||||
if( pRet->nPhrase>0 ){
|
||||
Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
|
||||
assert( pParse!=0 );
|
||||
assert( pParse->apPhrase!=0 );
|
||||
assert( pParse->nPhrase>=2 );
|
||||
assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
|
||||
if( pPhrase->nTerm==0 ){
|
||||
fts5ExprPhraseFree(pPhrase);
|
||||
@@ -1678,12 +1555,12 @@ static int fts5ParseTokenize(
|
||||
|
||||
if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
|
||||
Fts5ExprTerm *pSyn;
|
||||
sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
|
||||
pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
|
||||
int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
|
||||
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
|
||||
if( pSyn==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pSyn, 0, (size_t)nByte);
|
||||
memset(pSyn, 0, nByte);
|
||||
pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
|
||||
memcpy(pSyn->zTerm, pToken, nToken);
|
||||
pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
|
||||
@@ -1695,7 +1572,7 @@ static int fts5ParseTokenize(
|
||||
Fts5ExprPhrase *pNew;
|
||||
int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
|
||||
|
||||
pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
|
||||
pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
|
||||
sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
|
||||
);
|
||||
if( pNew==0 ){
|
||||
@@ -1745,20 +1622,6 @@ void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
|
||||
pParse->pExpr = p;
|
||||
}
|
||||
|
||||
static int parseGrowPhraseArray(Fts5Parse *pParse){
|
||||
if( (pParse->nPhrase % 8)==0 ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
|
||||
Fts5ExprPhrase **apNew;
|
||||
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
|
||||
if( apNew==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pParse->apPhrase = apNew;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called by the parser to process a string token. The
|
||||
** string may or may not be quoted. In any case it is tokenized and a
|
||||
@@ -1794,9 +1657,16 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
}else{
|
||||
|
||||
if( pAppend==0 ){
|
||||
if( parseGrowPhraseArray(pParse) ){
|
||||
fts5ExprPhraseFree(sCtx.pPhrase);
|
||||
return 0;
|
||||
if( (pParse->nPhrase % 8)==0 ){
|
||||
int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
|
||||
Fts5ExprPhrase **apNew;
|
||||
apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
|
||||
if( apNew==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
fts5ExprPhraseFree(sCtx.pPhrase);
|
||||
return 0;
|
||||
}
|
||||
pParse->apPhrase = apNew;
|
||||
}
|
||||
pParse->nPhrase++;
|
||||
}
|
||||
@@ -1845,12 +1715,10 @@ int sqlite3Fts5ExprClonePhrase(
|
||||
if( rc==SQLITE_OK ){
|
||||
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
|
||||
if( pColsetOrig ){
|
||||
sqlite3_int64 nByte;
|
||||
Fts5Colset *pColset;
|
||||
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
|
||||
pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
|
||||
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
if( pColset ){
|
||||
memcpy(pColset, pColsetOrig, (size_t)nByte);
|
||||
memcpy(pColset, pColsetOrig, nByte);
|
||||
}
|
||||
pNew->pRoot->pNear->pColset = pColset;
|
||||
}
|
||||
@@ -1878,7 +1746,7 @@ int sqlite3Fts5ExprClonePhrase(
|
||||
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
|
||||
if( rc==SQLITE_OK ){
|
||||
/* All the allocations succeeded. Put the expression object together. */
|
||||
pNew->pIndex = pExpr->pIndex;
|
||||
pNew->pConfig = pExpr->pConfig;
|
||||
@@ -1968,7 +1836,7 @@ static Fts5Colset *fts5ParseColset(
|
||||
assert( pParse->rc==SQLITE_OK );
|
||||
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
|
||||
|
||||
pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
|
||||
pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
|
||||
if( pNew==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -2064,10 +1932,10 @@ Fts5Colset *sqlite3Fts5ParseColset(
|
||||
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
|
||||
Fts5Colset *pRet;
|
||||
if( pOrig ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
|
||||
int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
|
||||
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
|
||||
if( pRet ){
|
||||
memcpy(pRet, pOrig, (size_t)nByte);
|
||||
memcpy(pRet, pOrig, nByte);
|
||||
}
|
||||
}else{
|
||||
pRet = 0;
|
||||
@@ -2149,8 +2017,9 @@ void sqlite3Fts5ParseSetColset(
|
||||
){
|
||||
Fts5Colset *pFree = pColset;
|
||||
if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
sqlite3Fts5ParseError(pParse,
|
||||
"fts5: column queries are not supported (detail=none)"
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: column queries are not supported (detail=none)"
|
||||
);
|
||||
}else{
|
||||
fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
|
||||
@@ -2202,67 +2071,6 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used when parsing LIKE or GLOB patterns against
|
||||
** trigram indexes that specify either detail=column or detail=none.
|
||||
** It converts a phrase:
|
||||
**
|
||||
** abc + def + ghi
|
||||
**
|
||||
** into an AND tree:
|
||||
**
|
||||
** abc AND def AND ghi
|
||||
*/
|
||||
static Fts5ExprNode *fts5ParsePhraseToAnd(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNearset *pNear
|
||||
){
|
||||
int nTerm = pNear->apPhrase[0]->nTerm;
|
||||
int ii;
|
||||
int nByte;
|
||||
Fts5ExprNode *pRet;
|
||||
|
||||
assert( pNear->nPhrase==1 );
|
||||
assert( pParse->bPhraseToAnd );
|
||||
|
||||
nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
if( pRet ){
|
||||
pRet->eType = FTS5_AND;
|
||||
pRet->nChild = nTerm;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
pParse->nPhrase--;
|
||||
for(ii=0; ii<nTerm; ii++){
|
||||
Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
|
||||
&pParse->rc, sizeof(Fts5ExprPhrase)
|
||||
);
|
||||
if( pPhrase ){
|
||||
if( parseGrowPhraseArray(pParse) ){
|
||||
fts5ExprPhraseFree(pPhrase);
|
||||
}else{
|
||||
pParse->apPhrase[pParse->nPhrase++] = pPhrase;
|
||||
pPhrase->nTerm = 1;
|
||||
pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
|
||||
&pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
|
||||
);
|
||||
pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
|
||||
0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pParse->rc ){
|
||||
sqlite3Fts5ParseNodeFree(pRet);
|
||||
pRet = 0;
|
||||
}else{
|
||||
sqlite3Fts5ParseNearsetFree(pNear);
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and return a new expression object. If anything goes wrong (i.e.
|
||||
** OOM error), leave an error code in pParse and return NULL.
|
||||
@@ -2278,7 +2086,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
|
||||
|
||||
if( pParse->rc==SQLITE_OK ){
|
||||
int nChild = 0; /* Number of children of returned node */
|
||||
sqlite3_int64 nByte; /* Bytes of space to allocate for this node */
|
||||
int nByte; /* Bytes of space to allocate for this node */
|
||||
|
||||
assert( (eType!=FTS5_STRING && !pNear)
|
||||
|| (eType==FTS5_STRING && !pLeft && !pRight)
|
||||
@@ -2287,55 +2095,51 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
|
||||
if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
|
||||
if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
|
||||
|
||||
if( eType==FTS5_STRING
|
||||
&& pParse->bPhraseToAnd
|
||||
&& pNear->apPhrase[0]->nTerm>1
|
||||
){
|
||||
pRet = fts5ParsePhraseToAnd(pParse, pNear);
|
||||
}else{
|
||||
if( eType==FTS5_NOT ){
|
||||
nChild = 2;
|
||||
}else if( eType==FTS5_AND || eType==FTS5_OR ){
|
||||
nChild = 2;
|
||||
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
|
||||
if( pRight->eType==eType ) nChild += pRight->nChild-1;
|
||||
}
|
||||
if( eType==FTS5_NOT ){
|
||||
nChild = 2;
|
||||
}else if( eType==FTS5_AND || eType==FTS5_OR ){
|
||||
nChild = 2;
|
||||
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
|
||||
if( pRight->eType==eType ) nChild += pRight->nChild-1;
|
||||
}
|
||||
|
||||
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
|
||||
if( pRet ){
|
||||
pRet->eType = eType;
|
||||
pRet->pNear = pNear;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
if( eType==FTS5_STRING ){
|
||||
int iPhrase;
|
||||
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
|
||||
pNear->apPhrase[iPhrase]->pNode = pRet;
|
||||
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
|
||||
pRet->xNext = 0;
|
||||
pRet->eType = FTS5_EOF;
|
||||
}
|
||||
if( pRet ){
|
||||
pRet->eType = eType;
|
||||
pRet->pNear = pNear;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
if( eType==FTS5_STRING ){
|
||||
int iPhrase;
|
||||
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
|
||||
pNear->apPhrase[iPhrase]->pNode = pRet;
|
||||
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
|
||||
pRet->xNext = 0;
|
||||
pRet->eType = FTS5_EOF;
|
||||
}
|
||||
|
||||
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
||||
if( pNear->nPhrase!=1
|
||||
|| pPhrase->nTerm>1
|
||||
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
|
||||
){
|
||||
sqlite3Fts5ParseError(pParse,
|
||||
"fts5: %s queries are not supported (detail!=full)",
|
||||
pNear->nPhrase==1 ? "phrase": "NEAR"
|
||||
);
|
||||
sqlite3_free(pRet);
|
||||
pRet = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
fts5ExprAddChildren(pRet, pLeft);
|
||||
fts5ExprAddChildren(pRet, pRight);
|
||||
}
|
||||
|
||||
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
||||
if( pNear->nPhrase!=1
|
||||
|| pPhrase->nTerm>1
|
||||
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
|
||||
){
|
||||
assert( pParse->rc==SQLITE_OK );
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
assert( pParse->zErr==0 );
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: %s queries are not supported (detail!=full)",
|
||||
pNear->nPhrase==1 ? "phrase": "NEAR"
|
||||
);
|
||||
sqlite3_free(pRet);
|
||||
pRet = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
fts5ExprAddChildren(pRet, pLeft);
|
||||
fts5ExprAddChildren(pRet, pRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2413,9 +2217,8 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
|
||||
return pRet;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
|
||||
sqlite3_int64 nByte = 0;
|
||||
int nByte = 0;
|
||||
Fts5ExprTerm *p;
|
||||
char *zQuoted;
|
||||
|
||||
@@ -2423,7 +2226,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
|
||||
for(p=pTerm; p; p=p->pSynonym){
|
||||
nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
|
||||
}
|
||||
zQuoted = sqlite3_malloc64(nByte);
|
||||
zQuoted = sqlite3_malloc(nByte);
|
||||
|
||||
if( zQuoted ){
|
||||
int i = 0;
|
||||
@@ -2557,17 +2360,8 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
|
||||
int iTerm;
|
||||
|
||||
if( pNear->pColset ){
|
||||
int ii;
|
||||
Fts5Colset *pColset = pNear->pColset;
|
||||
if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
|
||||
for(ii=0; ii<pColset->nCol; ii++){
|
||||
zRet = fts5PrintfAppend(zRet, "%s%s",
|
||||
pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " "
|
||||
);
|
||||
}
|
||||
if( zRet ){
|
||||
zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
|
||||
}
|
||||
int iCol = pNear->pColset->aiCol[0];
|
||||
zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
|
||||
if( zRet==0 ) return 0;
|
||||
}
|
||||
|
||||
@@ -2672,7 +2466,7 @@ static void fts5ExprFunction(
|
||||
}
|
||||
|
||||
nConfig = 3 + (nArg-iArg);
|
||||
azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
|
||||
azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
|
||||
if( azConfig==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return;
|
||||
@@ -2681,16 +2475,14 @@ static void fts5ExprFunction(
|
||||
azConfig[1] = "main";
|
||||
azConfig[2] = "tbl";
|
||||
for(i=3; iArg<nArg; iArg++){
|
||||
const char *z = (const char*)sqlite3_value_text(apVal[iArg]);
|
||||
azConfig[i++] = (z ? z : "");
|
||||
azConfig[i++] = (const char*)sqlite3_value_text(apVal[iArg]);
|
||||
}
|
||||
|
||||
zExpr = (const char*)sqlite3_value_text(apVal[0]);
|
||||
if( zExpr==0 ) zExpr = "";
|
||||
|
||||
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zText;
|
||||
@@ -2748,19 +2540,14 @@ static void fts5ExprIsAlnum(
|
||||
sqlite3_value **apVal /* Function arguments */
|
||||
){
|
||||
int iCode;
|
||||
u8 aArr[32];
|
||||
if( nArg!=1 ){
|
||||
sqlite3_result_error(pCtx,
|
||||
"wrong number of arguments to function fts5_isalnum", -1
|
||||
);
|
||||
return;
|
||||
}
|
||||
memset(aArr, 0, sizeof(aArr));
|
||||
sqlite3Fts5UnicodeCatParse("L*", aArr);
|
||||
sqlite3Fts5UnicodeCatParse("N*", aArr);
|
||||
sqlite3Fts5UnicodeCatParse("Co", aArr);
|
||||
iCode = sqlite3_value_int(apVal[0]);
|
||||
sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
|
||||
sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
|
||||
}
|
||||
|
||||
static void fts5ExprFold(
|
||||
@@ -2780,14 +2567,12 @@ static void fts5ExprFold(
|
||||
sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
|
||||
}
|
||||
}
|
||||
#endif /* ifdef SQLITE_TEST */
|
||||
|
||||
/*
|
||||
** This is called during initialization to register the fts5_expr() scalar
|
||||
** UDF with the SQLite handle passed as the only argument.
|
||||
*/
|
||||
int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
|
||||
#ifdef SQLITE_TEST
|
||||
struct Fts5ExprFunc {
|
||||
const char *z;
|
||||
void (*x)(sqlite3_context*,int,sqlite3_value**);
|
||||
@@ -2805,17 +2590,11 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
|
||||
struct Fts5ExprFunc *p = &aFunc[i];
|
||||
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
|
||||
}
|
||||
#else
|
||||
int rc = SQLITE_OK;
|
||||
UNUSED_PARAM2(pGlobal,db);
|
||||
#endif
|
||||
|
||||
/* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
|
||||
** sqlite3Fts5ParserFallback() are unused */
|
||||
/* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
|
||||
#ifndef NDEBUG
|
||||
(void)sqlite3Fts5ParserTrace;
|
||||
#endif
|
||||
(void)sqlite3Fts5ParserFallback;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -2859,25 +2638,16 @@ struct Fts5PoslistPopulator {
|
||||
int bMiss;
|
||||
};
|
||||
|
||||
/*
|
||||
** Clear the position lists associated with all phrases in the expression
|
||||
** passed as the first argument. Argument bLive is true if the expression
|
||||
** might be pointing to a real entry, otherwise it has just been reset.
|
||||
**
|
||||
** At present this function is only used for detail=col and detail=none
|
||||
** fts5 tables. This implies that all phrases must be at most 1 token
|
||||
** in size, as phrase matches are not supported without detail=full.
|
||||
*/
|
||||
Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
|
||||
Fts5PoslistPopulator *pRet;
|
||||
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
|
||||
pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
|
||||
if( pRet ){
|
||||
int i;
|
||||
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
|
||||
for(i=0; i<pExpr->nPhrase; i++){
|
||||
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
|
||||
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
|
||||
assert( pExpr->apExprPhrase[i]->nTerm<=1 );
|
||||
assert( pExpr->apExprPhrase[i]->nTerm==1 );
|
||||
if( bLive &&
|
||||
(pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
|
||||
){
|
||||
@@ -3069,3 +2839,4 @@ int sqlite3Fts5ExprPhraseCollist(
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+34
-57
@@ -90,20 +90,20 @@ int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
sqlite3_int64 nByte;
|
||||
int nByte;
|
||||
memset(pNew, 0, sizeof(Fts5Hash));
|
||||
pNew->pnByte = pnByte;
|
||||
pNew->eDetail = pConfig->eDetail;
|
||||
|
||||
pNew->nSlot = 1024;
|
||||
nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
|
||||
pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte);
|
||||
pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
|
||||
if( pNew->aSlot==0 ){
|
||||
sqlite3_free(pNew);
|
||||
*ppNew = 0;
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pNew->aSlot, 0, (size_t)nByte);
|
||||
memset(pNew->aSlot, 0, nByte);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@@ -165,7 +165,7 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||||
Fts5HashEntry **apNew;
|
||||
Fts5HashEntry **apOld = pHash->aSlot;
|
||||
|
||||
apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*));
|
||||
apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
|
||||
if( !apNew ) return SQLITE_NOMEM;
|
||||
memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
|
||||
|
||||
@@ -187,25 +187,19 @@ static int fts5HashResize(Fts5Hash *pHash){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fts5HashAddPoslistSize(
|
||||
Fts5Hash *pHash,
|
||||
Fts5HashEntry *p,
|
||||
Fts5HashEntry *p2
|
||||
){
|
||||
int nRet = 0;
|
||||
static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
|
||||
if( p->iSzPoslist ){
|
||||
u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
|
||||
int nData = p->nData;
|
||||
u8 *pPtr = (u8*)p;
|
||||
if( pHash->eDetail==FTS5_DETAIL_NONE ){
|
||||
assert( nData==p->iSzPoslist );
|
||||
assert( p->nData==p->iSzPoslist );
|
||||
if( p->bDel ){
|
||||
pPtr[nData++] = 0x00;
|
||||
pPtr[p->nData++] = 0x00;
|
||||
if( p->bContent ){
|
||||
pPtr[nData++] = 0x00;
|
||||
pPtr[p->nData++] = 0x00;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
int nSz = (nData - p->iSzPoslist - 1); /* Size in bytes */
|
||||
int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes */
|
||||
int nPos = nSz*2 + p->bDel; /* Value of nPos field */
|
||||
|
||||
assert( p->bDel==0 || p->bDel==1 );
|
||||
@@ -215,19 +209,14 @@ static int fts5HashAddPoslistSize(
|
||||
int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
|
||||
memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
|
||||
sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
|
||||
nData += (nByte-1);
|
||||
p->nData += (nByte-1);
|
||||
}
|
||||
}
|
||||
|
||||
nRet = nData - p->nData;
|
||||
if( p2==0 ){
|
||||
p->iSzPoslist = 0;
|
||||
p->bDel = 0;
|
||||
p->bContent = 0;
|
||||
p->nData = nData;
|
||||
}
|
||||
p->iSzPoslist = 0;
|
||||
p->bDel = 0;
|
||||
p->bContent = 0;
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,7 +259,7 @@ int sqlite3Fts5HashWrite(
|
||||
if( p==0 ){
|
||||
/* Figure out how much space to allocate */
|
||||
char *zKey;
|
||||
sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
|
||||
int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
|
||||
if( nByte<128 ) nByte = 128;
|
||||
|
||||
/* Grow the Fts5Hash.aSlot[] array if necessary. */
|
||||
@@ -281,10 +270,10 @@ int sqlite3Fts5HashWrite(
|
||||
}
|
||||
|
||||
/* Allocate new Fts5HashEntry and add it to the hash table. */
|
||||
p = (Fts5HashEntry*)sqlite3_malloc64(nByte);
|
||||
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
memset(p, 0, sizeof(Fts5HashEntry));
|
||||
p->nAlloc = (int)nByte;
|
||||
p->nAlloc = nByte;
|
||||
zKey = fts5EntryKey(p);
|
||||
zKey[0] = bByte;
|
||||
memcpy(&zKey[1], pToken, nToken);
|
||||
@@ -306,6 +295,7 @@ int sqlite3Fts5HashWrite(
|
||||
p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
|
||||
}
|
||||
|
||||
nIncr += p->nData;
|
||||
}else{
|
||||
|
||||
/* Appending to an existing hash-entry. Check that there is enough
|
||||
@@ -319,12 +309,12 @@ int sqlite3Fts5HashWrite(
|
||||
** + 5 bytes for the new position offset (32-bit max).
|
||||
*/
|
||||
if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
|
||||
sqlite3_int64 nNew = p->nAlloc * 2;
|
||||
int nNew = p->nAlloc * 2;
|
||||
Fts5HashEntry *pNew;
|
||||
Fts5HashEntry **pp;
|
||||
pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
|
||||
pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
pNew->nAlloc = (int)nNew;
|
||||
pNew->nAlloc = nNew;
|
||||
for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
|
||||
*pp = pNew;
|
||||
p = pNew;
|
||||
@@ -338,9 +328,8 @@ int sqlite3Fts5HashWrite(
|
||||
/* If this is a new rowid, append the 4-byte size field for the previous
|
||||
** entry, and the new rowid for this entry. */
|
||||
if( iRowid!=p->iRowid ){
|
||||
u64 iDiff = (u64)iRowid - (u64)p->iRowid;
|
||||
fts5HashAddPoslistSize(pHash, p, 0);
|
||||
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff);
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
|
||||
p->iRowid = iRowid;
|
||||
bNew = 1;
|
||||
p->iSzPoslist = p->nData;
|
||||
@@ -356,7 +345,7 @@ int sqlite3Fts5HashWrite(
|
||||
p->bContent = 1;
|
||||
}else{
|
||||
/* Append a new column value, if necessary */
|
||||
assert_nc( iCol>=p->iCol );
|
||||
assert( iCol>=p->iCol );
|
||||
if( iCol!=p->iCol ){
|
||||
if( pHash->eDetail==FTS5_DETAIL_FULL ){
|
||||
pPtr[p->nData++] = 0x01;
|
||||
@@ -449,16 +438,14 @@ static int fts5HashEntrySort(
|
||||
int i;
|
||||
|
||||
*ppSorted = 0;
|
||||
ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot);
|
||||
ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
|
||||
if( !ap ) return SQLITE_NOMEM;
|
||||
memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
|
||||
|
||||
for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
|
||||
Fts5HashEntry *pIter;
|
||||
for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
|
||||
if( pTerm==0
|
||||
|| (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
|
||||
){
|
||||
if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
|
||||
Fts5HashEntry *pEntry = pIter;
|
||||
pEntry->pScanNext = 0;
|
||||
for(i=0; ap[i]; i++){
|
||||
@@ -486,9 +473,8 @@ static int fts5HashEntrySort(
|
||||
*/
|
||||
int sqlite3Fts5HashQuery(
|
||||
Fts5Hash *pHash, /* Hash table to query */
|
||||
int nPre,
|
||||
const char *pTerm, int nTerm, /* Query term */
|
||||
void **ppOut, /* OUT: Pointer to new object */
|
||||
const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
|
||||
int *pnDoclist /* OUT: Size of doclist in bytes */
|
||||
){
|
||||
unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
|
||||
@@ -497,25 +483,15 @@ int sqlite3Fts5HashQuery(
|
||||
|
||||
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
|
||||
zKey = fts5EntryKey(p);
|
||||
assert( p->nKey+1==(int)strlen(zKey) );
|
||||
if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
|
||||
if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
|
||||
}
|
||||
|
||||
if( p ){
|
||||
int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
|
||||
int nList = p->nData - nHashPre;
|
||||
u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
|
||||
if( pRet ){
|
||||
Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
|
||||
memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
|
||||
nList += fts5HashAddPoslistSize(pHash, p, pFaux);
|
||||
*pnDoclist = nList;
|
||||
}else{
|
||||
*pnDoclist = 0;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
}else{
|
||||
*ppOut = 0;
|
||||
*ppDoclist = 0;
|
||||
*pnDoclist = 0;
|
||||
}
|
||||
|
||||
@@ -548,7 +524,7 @@ void sqlite3Fts5HashScanEntry(
|
||||
if( (p = pHash->pScan) ){
|
||||
char *zKey = fts5EntryKey(p);
|
||||
int nTerm = (int)strlen(zKey);
|
||||
fts5HashAddPoslistSize(pHash, p, 0);
|
||||
fts5HashAddPoslistSize(pHash, p);
|
||||
*pzTerm = zKey;
|
||||
*ppDoclist = (const u8*)&zKey[nTerm+1];
|
||||
*pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
|
||||
@@ -558,3 +534,4 @@ void sqlite3Fts5HashScanEntry(
|
||||
*pnDoclist = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+379
-696
File diff suppressed because it is too large
Load Diff
+287
-467
File diff suppressed because it is too large
Load Diff
+79
-115
@@ -115,7 +115,7 @@ static int fts5StorageGetStmt(
|
||||
char *zBind;
|
||||
int i;
|
||||
|
||||
zBind = sqlite3_malloc64(1 + nCol*2);
|
||||
zBind = sqlite3_malloc(1 + nCol*2);
|
||||
if( zBind ){
|
||||
for(i=0; i<nCol; i++){
|
||||
zBind[i*2] = '?';
|
||||
@@ -136,11 +136,8 @@ static int fts5StorageGetStmt(
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int f = SQLITE_PREPARE_PERSISTENT;
|
||||
if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
|
||||
p->pConfig->bLock++;
|
||||
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
|
||||
p->pConfig->bLock--;
|
||||
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));
|
||||
@@ -284,14 +281,14 @@ int sqlite3Fts5StorageOpen(
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
Fts5Storage *p; /* New object */
|
||||
sqlite3_int64 nByte; /* Bytes of space to allocate */
|
||||
int nByte; /* Bytes of space to allocate */
|
||||
|
||||
nByte = sizeof(Fts5Storage) /* Fts5Storage object */
|
||||
+ pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
|
||||
*pp = p = (Fts5Storage*)sqlite3_malloc64(nByte);
|
||||
*pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
|
||||
memset(p, 0, (size_t)nByte);
|
||||
memset(p, 0, nByte);
|
||||
p->aTotalSize = (i64*)&p[1];
|
||||
p->pConfig = pConfig;
|
||||
p->pIndex = pIndex;
|
||||
@@ -299,7 +296,7 @@ int sqlite3Fts5StorageOpen(
|
||||
if( bCreate ){
|
||||
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
int nDefn = 32 + pConfig->nCol*10;
|
||||
char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
|
||||
char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
|
||||
if( zDefn==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -417,32 +414,21 @@ static int fts5StorageDeleteFromIndex(
|
||||
if( pConfig->abUnindexed[iCol-1]==0 ){
|
||||
const char *zText;
|
||||
int nText;
|
||||
assert( pSeek==0 || apVal==0 );
|
||||
assert( pSeek!=0 || apVal!=0 );
|
||||
if( pSeek ){
|
||||
zText = (const char*)sqlite3_column_text(pSeek, iCol);
|
||||
nText = sqlite3_column_bytes(pSeek, iCol);
|
||||
}else if( ALWAYS(apVal) ){
|
||||
}else{
|
||||
zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
|
||||
nText = sqlite3_value_bytes(apVal[iCol-1]);
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
ctx.szCol = 0;
|
||||
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText, (void*)&ctx, fts5StorageInsertCallback
|
||||
);
|
||||
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
|
||||
if( p->aTotalSize[iCol-1]<0 ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && p->nTotalRow<1 ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}else{
|
||||
p->nTotalRow--;
|
||||
}
|
||||
p->nTotalRow--;
|
||||
|
||||
rc2 = sqlite3_reset(pSeek);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
@@ -571,8 +557,6 @@ int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
int rc;
|
||||
|
||||
p->bTotalsValid = 0;
|
||||
|
||||
/* Delete the contents of the %_data and %_docsize tables. */
|
||||
rc = fts5ExecPrintf(pConfig->db, 0,
|
||||
"DELETE FROM %Q.'%q_data';"
|
||||
@@ -603,7 +587,7 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
sqlite3_stmt *pScan = 0;
|
||||
Fts5InsertCtx ctx;
|
||||
int rc, rc2;
|
||||
int rc;
|
||||
|
||||
memset(&ctx, 0, sizeof(Fts5InsertCtx));
|
||||
ctx.pStorage = p;
|
||||
@@ -624,11 +608,10 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
|
||||
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->abUnindexed[ctx.iCol]==0 ){
|
||||
const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
|
||||
int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText,
|
||||
(const char*)sqlite3_column_text(pScan, ctx.iCol+1),
|
||||
sqlite3_column_bytes(pScan, ctx.iCol+1),
|
||||
(void*)&ctx,
|
||||
fts5StorageInsertCallback
|
||||
);
|
||||
@@ -643,8 +626,6 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
|
||||
}
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
rc2 = sqlite3_reset(pScan);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -750,11 +731,10 @@ int sqlite3Fts5StorageIndexInsert(
|
||||
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->abUnindexed[ctx.iCol]==0 ){
|
||||
const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
|
||||
int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText,
|
||||
(const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
|
||||
sqlite3_value_bytes(apVal[ctx.iCol+2]),
|
||||
(void*)&ctx,
|
||||
fts5StorageInsertCallback
|
||||
);
|
||||
@@ -885,104 +865,97 @@ static int fts5StorageIntegrityCallback(
|
||||
** some other SQLite error code if an error occurs while attempting to
|
||||
** determine this.
|
||||
*/
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int rc; /* Return code */
|
||||
int *aColSize; /* Array of size pConfig->nCol */
|
||||
i64 *aTotalSize; /* Array of size pConfig->nCol */
|
||||
Fts5IntegrityCtx ctx;
|
||||
sqlite3_stmt *pScan;
|
||||
int bUseCksum;
|
||||
|
||||
memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
|
||||
ctx.pConfig = p->pConfig;
|
||||
aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
|
||||
aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
|
||||
if( !aTotalSize ) return SQLITE_NOMEM;
|
||||
aColSize = (int*)&aTotalSize[pConfig->nCol];
|
||||
memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
|
||||
|
||||
bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL
|
||||
|| (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg)
|
||||
);
|
||||
if( bUseCksum ){
|
||||
/* Generate the expected index checksum based on the contents of the
|
||||
** %_content table. This block stores the checksum in ctx.cksum. */
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
while( SQLITE_ROW==sqlite3_step(pScan) ){
|
||||
int i;
|
||||
ctx.iRowid = sqlite3_column_int64(pScan, 0);
|
||||
/* Generate the expected index checksum based on the contents of the
|
||||
** %_content table. This block stores the checksum in ctx.cksum. */
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
while( SQLITE_ROW==sqlite3_step(pScan) ){
|
||||
int i;
|
||||
ctx.iRowid = sqlite3_column_int64(pScan, 0);
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->bColumnsize ){
|
||||
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( pConfig->abUnindexed[i] ) continue;
|
||||
ctx.iCol = i;
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->bColumnsize ){
|
||||
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( pConfig->abUnindexed[i] ) continue;
|
||||
ctx.iCol = i;
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
|
||||
int nText = sqlite3_column_bytes(pScan, i+1);
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText,
|
||||
(void*)&ctx,
|
||||
fts5StorageIntegrityCallback
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
aTotalSize[i] += ctx.szCol;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
(const char*)sqlite3_column_text(pScan, i+1),
|
||||
sqlite3_column_bytes(pScan, i+1),
|
||||
(void*)&ctx,
|
||||
fts5StorageIntegrityCallback
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
aTotalSize[i] += ctx.szCol;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
}
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
rc2 = sqlite3_reset(pScan);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
|
||||
/* Test that the "totals" (sometimes called "averages") record looks Ok */
|
||||
if( rc==SQLITE_OK ){
|
||||
int i;
|
||||
rc = fts5StorageLoadTotals(p, 0);
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
rc2 = sqlite3_reset(pScan);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
|
||||
/* Check that the %_docsize and %_content tables contain the expected
|
||||
** number of rows. */
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "content", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "docsize", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
/* Test that the "totals" (sometimes called "averages") record looks Ok */
|
||||
if( rc==SQLITE_OK ){
|
||||
int i;
|
||||
rc = fts5StorageLoadTotals(p, 0);
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the %_docsize and %_content tables contain the expected
|
||||
** number of rows. */
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "content", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "docsize", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
|
||||
/* Pass the expected checksum down to the FTS index module. It will
|
||||
** verify, amongst other things, that it matches the checksum generated by
|
||||
** inspecting the index itself. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum);
|
||||
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
|
||||
}
|
||||
|
||||
sqlite3_free(aTotalSize);
|
||||
@@ -1062,9 +1035,8 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
|
||||
|
||||
assert( p->pConfig->bColumnsize );
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
|
||||
if( pLookup ){
|
||||
if( rc==SQLITE_OK ){
|
||||
int bCorrupt = 1;
|
||||
assert( rc==SQLITE_OK );
|
||||
sqlite3_bind_int64(pLookup, 1, iRowid);
|
||||
if( SQLITE_ROW==sqlite3_step(pLookup) ){
|
||||
const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
|
||||
@@ -1077,8 +1049,6 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
|
||||
if( bCorrupt && rc==SQLITE_OK ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
}else{
|
||||
assert( rc!=SQLITE_OK );
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -1105,13 +1075,7 @@ int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
|
||||
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
|
||||
int rc = fts5StorageLoadTotals(p, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
/* nTotalRow being zero does not necessarily indicate a corrupt
|
||||
** database - it might be that the FTS5 table really does contain zero
|
||||
** rows. However this function is only called from the xRowCount() API,
|
||||
** and there is no way for that API to be invoked if the table contains
|
||||
** no rows. Hence the FTS5_CORRUPT return. */
|
||||
*pnRow = p->nTotalRow;
|
||||
if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
extern int sqlite3_fts5_may_be_corrupt;
|
||||
#endif
|
||||
extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
|
||||
extern int sqlite3Fts5TestRegisterTok(sqlite3*, fts5_api*);
|
||||
|
||||
@@ -1013,7 +1011,6 @@ static int SQLITE_TCLAPI f5tMayBeCorrupt(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#ifdef SQLITE_DEBUG
|
||||
int bOld = sqlite3_fts5_may_be_corrupt;
|
||||
|
||||
if( objc!=2 && objc!=1 ){
|
||||
@@ -1027,7 +1024,6 @@ static int SQLITE_TCLAPI f5tMayBeCorrupt(
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(bOld));
|
||||
#endif
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ static Fts5MatchinfoCtx *fts5MatchinfoNew(
|
||||
int nPhrase;
|
||||
int i;
|
||||
int nInt;
|
||||
sqlite3_int64 nByte;
|
||||
int nByte;
|
||||
int rc;
|
||||
|
||||
nCol = pApi->xColumnCount(pFts);
|
||||
@@ -330,7 +330,7 @@ static Fts5MatchinfoCtx *fts5MatchinfoNew(
|
||||
nByte = sizeof(Fts5MatchinfoCtx) /* The struct itself */
|
||||
+ sizeof(u32) * nInt /* The p->aRet[] array */
|
||||
+ (i+1); /* The p->zArg string */
|
||||
p = (Fts5MatchinfoCtx*)sqlite3_malloc64(nByte);
|
||||
p = (Fts5MatchinfoCtx*)sqlite3_malloc(nByte);
|
||||
if( p==0 ){
|
||||
sqlite3_result_error_nomem(pCtx);
|
||||
return 0;
|
||||
|
||||
@@ -137,7 +137,7 @@ static int fts5tokDequoteArray(
|
||||
nByte += (int)(strlen(argv[i]) + 1);
|
||||
}
|
||||
|
||||
*pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
|
||||
*pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
|
||||
if( azDequote==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -211,7 +211,7 @@ static int fts5tokConnectMethod(
|
||||
|
||||
rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok);
|
||||
if( rc==SQLITE_OK ){
|
||||
const char **azArg = (nDequote>1 ? (const char **)&azDequote[1] : 0);
|
||||
const char **azArg = (const char **)&azDequote[1];
|
||||
int nArg = nDequote>0 ? nDequote-1 : 0;
|
||||
rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok);
|
||||
}
|
||||
@@ -335,7 +335,7 @@ static int fts5tokCb(
|
||||
if( (pCsr->nRow & (pCsr->nRow-1))==0 ){
|
||||
int nNew = pCsr->nRow ? pCsr->nRow*2 : 32;
|
||||
Fts5tokRow *aNew;
|
||||
aNew = (Fts5tokRow*)sqlite3_realloc64(pCsr->aRow, nNew*sizeof(Fts5tokRow));
|
||||
aNew = (Fts5tokRow*)sqlite3_realloc(pCsr->aRow, nNew*sizeof(Fts5tokRow));
|
||||
if( aNew==0 ) return SQLITE_NOMEM;
|
||||
memset(&aNew[pCsr->nRow], 0, sizeof(Fts5tokRow)*(nNew-pCsr->nRow));
|
||||
pCsr->aRow = aNew;
|
||||
@@ -378,7 +378,7 @@ static int fts5tokFilterMethod(
|
||||
if( pCsr->zInput==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
|
||||
memcpy(pCsr->zInput, zByte, nByte);
|
||||
pCsr->zInput[nByte] = 0;
|
||||
rc = pTab->tok.xTokenize(
|
||||
pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
|
||||
@@ -471,8 +471,7 @@ int sqlite3Fts5TestRegisterTok(sqlite3 *db, fts5_api *pApi){
|
||||
0, /* xRename */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0, /* xRollbackTo */
|
||||
0 /* xShadowName */
|
||||
0 /* xRollbackTo */
|
||||
};
|
||||
int rc; /* Return code */
|
||||
|
||||
|
||||
+18
-191
@@ -152,7 +152,7 @@ static int fts5AsciiTokenize(
|
||||
nByte = ie-is;
|
||||
if( nByte>nFold ){
|
||||
if( pFold!=aFold ) sqlite3_free(pFold);
|
||||
pFold = sqlite3_malloc64((sqlite3_int64)nByte*2);
|
||||
pFold = sqlite3_malloc(nByte*2);
|
||||
if( pFold==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
@@ -234,18 +234,11 @@ struct Unicode61Tokenizer {
|
||||
unsigned char aTokenChar[128]; /* ASCII range token characters */
|
||||
char *aFold; /* Buffer to fold text into */
|
||||
int nFold; /* Size of aFold[] in bytes */
|
||||
int eRemoveDiacritic; /* True if remove_diacritics=1 is set */
|
||||
int bRemoveDiacritic; /* True if remove_diacritics=1 is set */
|
||||
int nException;
|
||||
int *aiException;
|
||||
|
||||
unsigned char aCategory[32]; /* True for token char categories */
|
||||
};
|
||||
|
||||
/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */
|
||||
#define FTS5_REMOVE_DIACRITICS_NONE 0
|
||||
#define FTS5_REMOVE_DIACRITICS_SIMPLE 1
|
||||
#define FTS5_REMOVE_DIACRITICS_COMPLEX 2
|
||||
|
||||
static int fts5UnicodeAddExceptions(
|
||||
Unicode61Tokenizer *p, /* Tokenizer object */
|
||||
const char *z, /* Characters to treat as exceptions */
|
||||
@@ -256,26 +249,25 @@ static int fts5UnicodeAddExceptions(
|
||||
int *aNew;
|
||||
|
||||
if( n>0 ){
|
||||
aNew = (int*)sqlite3_realloc64(p->aiException,
|
||||
(n+p->nException)*sizeof(int));
|
||||
aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
|
||||
if( aNew ){
|
||||
int nNew = p->nException;
|
||||
const unsigned char *zCsr = (const unsigned char*)z;
|
||||
const unsigned char *zTerm = (const unsigned char*)&z[n];
|
||||
while( zCsr<zTerm ){
|
||||
u32 iCode;
|
||||
int iCode;
|
||||
int bToken;
|
||||
READ_UTF8(zCsr, zTerm, iCode);
|
||||
if( iCode<128 ){
|
||||
p->aTokenChar[iCode] = (unsigned char)bTokenChars;
|
||||
}else{
|
||||
bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
|
||||
bToken = sqlite3Fts5UnicodeIsalnum(iCode);
|
||||
assert( (bToken==0 || bToken==1) );
|
||||
assert( (bTokenChars==0 || bTokenChars==1) );
|
||||
if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
|
||||
int i;
|
||||
for(i=0; i<nNew; i++){
|
||||
if( (u32)aNew[i]>iCode ) break;
|
||||
if( aNew[i]>iCode ) break;
|
||||
}
|
||||
memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
|
||||
aNew[i] = iCode;
|
||||
@@ -330,21 +322,6 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
|
||||
return;
|
||||
}
|
||||
|
||||
static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
|
||||
const char *z = zCat;
|
||||
|
||||
while( *z ){
|
||||
while( *z==' ' || *z=='\t' ) z++;
|
||||
if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
while( *z!=' ' && *z!='\t' && *z!='\0' ) z++;
|
||||
}
|
||||
|
||||
sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a "unicode61" tokenizer.
|
||||
*/
|
||||
@@ -363,54 +340,32 @@ static int fts5UnicodeCreate(
|
||||
}else{
|
||||
p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
|
||||
if( p ){
|
||||
const char *zCat = "L* N* Co";
|
||||
int i;
|
||||
memset(p, 0, sizeof(Unicode61Tokenizer));
|
||||
|
||||
p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
|
||||
memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
|
||||
p->bRemoveDiacritic = 1;
|
||||
p->nFold = 64;
|
||||
p->aFold = sqlite3_malloc64(p->nFold * sizeof(char));
|
||||
p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
|
||||
if( p->aFold==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* Search for a "categories" argument */
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
|
||||
zCat = azArg[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = unicodeSetCategories(p, zCat);
|
||||
}
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
p->eRemoveDiacritic = (zArg[0] - '0');
|
||||
assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE
|
||||
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE
|
||||
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX
|
||||
);
|
||||
}
|
||||
p->bRemoveDiacritic = (zArg[0]=='1');
|
||||
}else
|
||||
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
|
||||
rc = fts5UnicodeAddExceptions(p, zArg, 1);
|
||||
}else
|
||||
if( 0==sqlite3_stricmp(azArg[i], "separators") ){
|
||||
rc = fts5UnicodeAddExceptions(p, zArg, 0);
|
||||
}else
|
||||
if( 0==sqlite3_stricmp(azArg[i], "categories") ){
|
||||
/* no-op */
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@@ -429,10 +384,8 @@ static int fts5UnicodeCreate(
|
||||
** character (not a separator).
|
||||
*/
|
||||
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
|
||||
return (
|
||||
p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
|
||||
^ fts5UnicodeIsException(p, iCode)
|
||||
);
|
||||
assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
|
||||
return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
|
||||
}
|
||||
|
||||
static int fts5UnicodeTokenize(
|
||||
@@ -459,7 +412,7 @@ static int fts5UnicodeTokenize(
|
||||
/* Each iteration of this loop gobbles up a contiguous run of separators,
|
||||
** then the next token. */
|
||||
while( rc==SQLITE_OK ){
|
||||
u32 iCode; /* non-ASCII codepoint read from input */
|
||||
int iCode; /* non-ASCII codepoint read from input */
|
||||
char *zOut = aFold;
|
||||
int is;
|
||||
int ie;
|
||||
@@ -491,7 +444,7 @@ static int fts5UnicodeTokenize(
|
||||
/* Grow the output buffer so that there is sufficient space to fit the
|
||||
** largest possible utf-8 character. */
|
||||
if( zOut>pEnd ){
|
||||
aFold = sqlite3_malloc64((sqlite3_int64)nFold*2);
|
||||
aFold = sqlite3_malloc(nFold*2);
|
||||
if( aFold==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto tokenize_done;
|
||||
@@ -510,7 +463,7 @@ static int fts5UnicodeTokenize(
|
||||
READ_UTF8(zCsr, zTerm, iCode);
|
||||
if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
|
||||
non_ascii_tokenchar:
|
||||
iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic);
|
||||
iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
|
||||
if( iCode ) WRITE_UTF8(zOut, iCode);
|
||||
}else{
|
||||
break;
|
||||
@@ -1258,133 +1211,6 @@ static int fts5PorterTokenize(
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
** Start of trigram implementation.
|
||||
*/
|
||||
typedef struct TrigramTokenizer TrigramTokenizer;
|
||||
struct TrigramTokenizer {
|
||||
int bFold; /* True to fold to lower-case */
|
||||
};
|
||||
|
||||
/*
|
||||
** Free a trigram tokenizer.
|
||||
*/
|
||||
static void fts5TriDelete(Fts5Tokenizer *p){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a trigram tokenizer.
|
||||
*/
|
||||
static int fts5TriCreate(
|
||||
void *pUnused,
|
||||
const char **azArg,
|
||||
int nArg,
|
||||
Fts5Tokenizer **ppOut
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
|
||||
UNUSED_PARAM(pUnused);
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
pNew->bFold = 1;
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
pNew->bFold = (zArg[0]=='0');
|
||||
}
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
fts5TriDelete((Fts5Tokenizer*)pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
}
|
||||
*ppOut = (Fts5Tokenizer*)pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Trigram tokenizer tokenize routine.
|
||||
*/
|
||||
static int fts5TriTokenize(
|
||||
Fts5Tokenizer *pTok,
|
||||
void *pCtx,
|
||||
int unusedFlags,
|
||||
const char *pText, int nText,
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
|
||||
int rc = SQLITE_OK;
|
||||
char aBuf[32];
|
||||
const unsigned char *zIn = (const unsigned char*)pText;
|
||||
const unsigned char *zEof = &zIn[nText];
|
||||
u32 iCode;
|
||||
|
||||
UNUSED_PARAM(unusedFlags);
|
||||
while( 1 ){
|
||||
char *zOut = aBuf;
|
||||
int iStart = zIn - (const unsigned char*)pText;
|
||||
const unsigned char *zNext;
|
||||
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
zNext = zIn;
|
||||
if( zIn<zEof ){
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
if( zIn<zEof ){
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
zIn = zNext;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument xCreate is a pointer to a constructor function for a tokenizer.
|
||||
** pTok is a tokenizer previously created using the same method. This function
|
||||
** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB
|
||||
** indicating the style of pattern matching that the tokenizer can support.
|
||||
** In practice, this is:
|
||||
**
|
||||
** "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB
|
||||
** "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE
|
||||
** all other tokenizers - FTS5_PATTERN_NONE
|
||||
*/
|
||||
int sqlite3Fts5TokenizerPattern(
|
||||
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
||||
Fts5Tokenizer *pTok
|
||||
){
|
||||
if( xCreate==fts5TriCreate ){
|
||||
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
|
||||
return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
|
||||
}
|
||||
return FTS5_PATTERN_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
** Register all built-in tokenizers with FTS5.
|
||||
*/
|
||||
@@ -1396,7 +1222,6 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
|
||||
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
|
||||
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
|
||||
{ "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
|
||||
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
|
||||
};
|
||||
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
@@ -1413,3 +1238,5 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+155
-573
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** 2012-05-25
|
||||
** 2012 May 25
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
@@ -18,6 +18,135 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
** Return true if the argument corresponds to a unicode codepoint
|
||||
** classified as either a letter or a number. Otherwise false.
|
||||
**
|
||||
** The results are undefined if the value passed to this function
|
||||
** is less than zero.
|
||||
*/
|
||||
int sqlite3Fts5UnicodeIsalnum(int c){
|
||||
/* Each unsigned integer in the following array corresponds to a contiguous
|
||||
** range of unicode codepoints that are not either letters or numbers (i.e.
|
||||
** codepoints for which this function should return 0).
|
||||
**
|
||||
** The most significant 22 bits in each 32-bit value contain the first
|
||||
** codepoint in the range. The least significant 10 bits are used to store
|
||||
** the size of the range (always at least 1). In other words, the value
|
||||
** ((C<<22) + N) represents a range of N codepoints starting with codepoint
|
||||
** C. It is not possible to represent a range larger than 1023 codepoints
|
||||
** using this format.
|
||||
*/
|
||||
static const unsigned int aEntry[] = {
|
||||
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
|
||||
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
|
||||
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
|
||||
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
|
||||
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
|
||||
0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
|
||||
0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
|
||||
0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
|
||||
0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
|
||||
0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
|
||||
0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
|
||||
0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
|
||||
0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
|
||||
0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
|
||||
0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
|
||||
0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
|
||||
0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
|
||||
0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
|
||||
0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
|
||||
0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
|
||||
0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
|
||||
0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
|
||||
0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
|
||||
0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
|
||||
0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
|
||||
0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
|
||||
0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
|
||||
0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
|
||||
0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
|
||||
0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
|
||||
0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
|
||||
0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
|
||||
0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
|
||||
0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
|
||||
0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
|
||||
0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
|
||||
0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
|
||||
0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
|
||||
0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
|
||||
0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
|
||||
0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
|
||||
0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
|
||||
0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
|
||||
0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
|
||||
0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
|
||||
0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
|
||||
0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
|
||||
0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
|
||||
0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
|
||||
0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
|
||||
0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
|
||||
0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
|
||||
0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
|
||||
0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
|
||||
0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
|
||||
0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
|
||||
0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
|
||||
0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
|
||||
0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
|
||||
0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
|
||||
0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
|
||||
0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
|
||||
0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
|
||||
0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
|
||||
0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
|
||||
0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
|
||||
0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
|
||||
0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
|
||||
0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
|
||||
0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
|
||||
0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
|
||||
0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
|
||||
0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
|
||||
0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
|
||||
0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
|
||||
0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
|
||||
0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
|
||||
0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
|
||||
0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
|
||||
0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
|
||||
0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
|
||||
0x380400F0,
|
||||
};
|
||||
static const unsigned int aAscii[4] = {
|
||||
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
|
||||
};
|
||||
|
||||
if( (unsigned int)c<128 ){
|
||||
return ( (aAscii[c >> 5] & (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;
|
||||
int iLo = 0;
|
||||
while( iHi>=iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
if( key >= aEntry[iTest] ){
|
||||
iRes = iTest;
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest-1;
|
||||
}
|
||||
}
|
||||
assert( aEntry[0]<key );
|
||||
assert( key>=aEntry[iRes] );
|
||||
return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -28,48 +157,32 @@
|
||||
** E"). The resuls of passing a codepoint that corresponds to an
|
||||
** uppercase letter are undefined.
|
||||
*/
|
||||
static int fts5_remove_diacritic(int c, int bComplex){
|
||||
static int fts5_remove_diacritic(int c){
|
||||
unsigned short aDia[] = {
|
||||
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
|
||||
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
|
||||
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
|
||||
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
|
||||
3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
|
||||
3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
|
||||
4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
|
||||
4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
|
||||
6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
|
||||
61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
|
||||
61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
|
||||
61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
|
||||
62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
|
||||
62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
|
||||
62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
|
||||
63182, 63242, 63274, 63310, 63368, 63390,
|
||||
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
|
||||
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
|
||||
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
|
||||
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
|
||||
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
|
||||
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
|
||||
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
|
||||
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
|
||||
62924, 63050, 63082, 63274, 63390,
|
||||
};
|
||||
#define HIBIT ((unsigned char)0x80)
|
||||
unsigned char aChar[] = {
|
||||
'\0', 'a', 'c', 'e', 'i', 'n',
|
||||
'o', 'u', 'y', 'y', 'a', 'c',
|
||||
'd', 'e', 'e', 'g', 'h', 'i',
|
||||
'j', 'k', 'l', 'n', 'o', 'r',
|
||||
's', 't', 'u', 'u', 'w', 'y',
|
||||
'z', 'o', 'u', 'a', 'i', 'o',
|
||||
'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
|
||||
'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
|
||||
'e', 'i', 'o', 'r', 'u', 's',
|
||||
't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
|
||||
'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', 'a', 'b',
|
||||
'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
|
||||
'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
|
||||
'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
|
||||
'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
|
||||
's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
|
||||
'w', 'x', 'y', 'z', 'h', 't',
|
||||
'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
|
||||
'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
|
||||
'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
|
||||
char aChar[] = {
|
||||
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
|
||||
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
|
||||
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
|
||||
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
|
||||
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
|
||||
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
|
||||
'e', 'i', 'o', 'u', 'y',
|
||||
};
|
||||
|
||||
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
|
||||
@@ -86,8 +199,7 @@ static int fts5_remove_diacritic(int c, int bComplex){
|
||||
}
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
|
||||
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +212,8 @@ int sqlite3Fts5UnicodeIsdiacritic(int c){
|
||||
unsigned int mask1 = 0x000361F8;
|
||||
if( c<768 || c>817 ) return 0;
|
||||
return (c < 768+32) ?
|
||||
(mask0 & ((unsigned int)1 << (c-768))) :
|
||||
(mask1 & ((unsigned int)1 << (c-768-32)));
|
||||
(mask0 & (1 << (c-768))) :
|
||||
(mask1 & (1 << (c-768-32)));
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +226,7 @@ int sqlite3Fts5UnicodeIsdiacritic(int c){
|
||||
** The results are undefined if the value passed to this function
|
||||
** is less than zero.
|
||||
*/
|
||||
int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
|
||||
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
|
||||
/* Each entry in the following array defines a rule for folding a range
|
||||
** of codepoints to lower case. The rule applies to a range of nRange
|
||||
** codepoints starting at codepoint iCode.
|
||||
@@ -237,9 +349,7 @@ int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
|
||||
assert( ret>0 );
|
||||
}
|
||||
|
||||
if( eRemoveDiacritic ){
|
||||
ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2);
|
||||
}
|
||||
if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret);
|
||||
}
|
||||
|
||||
else if( c>=66560 && c<66600 ){
|
||||
@@ -248,531 +358,3 @@ int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
|
||||
aArray[0] = 1;
|
||||
switch( zCat[0] ){
|
||||
case 'C':
|
||||
switch( zCat[1] ){
|
||||
case 'c': aArray[1] = 1; break;
|
||||
case 'f': aArray[2] = 1; break;
|
||||
case 'n': aArray[3] = 1; break;
|
||||
case 's': aArray[4] = 1; break;
|
||||
case 'o': aArray[31] = 1; break;
|
||||
case '*':
|
||||
aArray[1] = 1;
|
||||
aArray[2] = 1;
|
||||
aArray[3] = 1;
|
||||
aArray[4] = 1;
|
||||
aArray[31] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
switch( zCat[1] ){
|
||||
case 'l': aArray[5] = 1; break;
|
||||
case 'm': aArray[6] = 1; break;
|
||||
case 'o': aArray[7] = 1; break;
|
||||
case 't': aArray[8] = 1; break;
|
||||
case 'u': aArray[9] = 1; break;
|
||||
case 'C': aArray[30] = 1; break;
|
||||
case '*':
|
||||
aArray[5] = 1;
|
||||
aArray[6] = 1;
|
||||
aArray[7] = 1;
|
||||
aArray[8] = 1;
|
||||
aArray[9] = 1;
|
||||
aArray[30] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
switch( zCat[1] ){
|
||||
case 'c': aArray[10] = 1; break;
|
||||
case 'e': aArray[11] = 1; break;
|
||||
case 'n': aArray[12] = 1; break;
|
||||
case '*':
|
||||
aArray[10] = 1;
|
||||
aArray[11] = 1;
|
||||
aArray[12] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
switch( zCat[1] ){
|
||||
case 'd': aArray[13] = 1; break;
|
||||
case 'l': aArray[14] = 1; break;
|
||||
case 'o': aArray[15] = 1; break;
|
||||
case '*':
|
||||
aArray[13] = 1;
|
||||
aArray[14] = 1;
|
||||
aArray[15] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
switch( zCat[1] ){
|
||||
case 'c': aArray[16] = 1; break;
|
||||
case 'd': aArray[17] = 1; break;
|
||||
case 'e': aArray[18] = 1; break;
|
||||
case 'f': aArray[19] = 1; break;
|
||||
case 'i': aArray[20] = 1; break;
|
||||
case 'o': aArray[21] = 1; break;
|
||||
case 's': aArray[22] = 1; break;
|
||||
case '*':
|
||||
aArray[16] = 1;
|
||||
aArray[17] = 1;
|
||||
aArray[18] = 1;
|
||||
aArray[19] = 1;
|
||||
aArray[20] = 1;
|
||||
aArray[21] = 1;
|
||||
aArray[22] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
switch( zCat[1] ){
|
||||
case 'c': aArray[23] = 1; break;
|
||||
case 'k': aArray[24] = 1; break;
|
||||
case 'm': aArray[25] = 1; break;
|
||||
case 'o': aArray[26] = 1; break;
|
||||
case '*':
|
||||
aArray[23] = 1;
|
||||
aArray[24] = 1;
|
||||
aArray[25] = 1;
|
||||
aArray[26] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
switch( zCat[1] ){
|
||||
case 'l': aArray[27] = 1; break;
|
||||
case 'p': aArray[28] = 1; break;
|
||||
case 's': aArray[29] = 1; break;
|
||||
case '*':
|
||||
aArray[27] = 1;
|
||||
aArray[28] = 1;
|
||||
aArray[29] = 1;
|
||||
break;
|
||||
default: return 1; }
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 aFts5UnicodeBlock[] = {
|
||||
0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760,
|
||||
1760, 1760, 1760, 1760, 1760, 1763, 1765,
|
||||
};
|
||||
static u16 aFts5UnicodeMap[] = {
|
||||
0, 32, 33, 36, 37, 40, 41, 42, 43, 44,
|
||||
45, 46, 48, 58, 60, 63, 65, 91, 92, 93,
|
||||
94, 95, 96, 97, 123, 124, 125, 126, 127, 160,
|
||||
161, 162, 166, 167, 168, 169, 170, 171, 172, 173,
|
||||
174, 175, 176, 177, 178, 180, 181, 182, 184, 185,
|
||||
186, 187, 188, 191, 192, 215, 216, 223, 247, 248,
|
||||
256, 312, 313, 329, 330, 377, 383, 385, 387, 388,
|
||||
391, 394, 396, 398, 402, 403, 405, 406, 409, 412,
|
||||
414, 415, 417, 418, 423, 427, 428, 431, 434, 436,
|
||||
437, 440, 442, 443, 444, 446, 448, 452, 453, 454,
|
||||
455, 456, 457, 458, 459, 460, 461, 477, 478, 496,
|
||||
497, 498, 499, 500, 503, 505, 506, 564, 570, 572,
|
||||
573, 575, 577, 580, 583, 584, 592, 660, 661, 688,
|
||||
706, 710, 722, 736, 741, 748, 749, 750, 751, 768,
|
||||
880, 884, 885, 886, 890, 891, 894, 900, 902, 903,
|
||||
904, 908, 910, 912, 913, 931, 940, 975, 977, 978,
|
||||
981, 984, 1008, 1012, 1014, 1015, 1018, 1020, 1021, 1072,
|
||||
1120, 1154, 1155, 1160, 1162, 1217, 1231, 1232, 1329, 1369,
|
||||
1370, 1377, 1417, 1418, 1423, 1425, 1470, 1471, 1472, 1473,
|
||||
1475, 1476, 1478, 1479, 1488, 1520, 1523, 1536, 1542, 1545,
|
||||
1547, 1548, 1550, 1552, 1563, 1566, 1568, 1600, 1601, 1611,
|
||||
1632, 1642, 1646, 1648, 1649, 1748, 1749, 1750, 1757, 1758,
|
||||
1759, 1765, 1767, 1769, 1770, 1774, 1776, 1786, 1789, 1791,
|
||||
1792, 1807, 1808, 1809, 1810, 1840, 1869, 1958, 1969, 1984,
|
||||
1994, 2027, 2036, 2038, 2039, 2042, 2048, 2070, 2074, 2075,
|
||||
2084, 2085, 2088, 2089, 2096, 2112, 2137, 2142, 2208, 2210,
|
||||
2276, 2304, 2307, 2308, 2362, 2363, 2364, 2365, 2366, 2369,
|
||||
2377, 2381, 2382, 2384, 2385, 2392, 2402, 2404, 2406, 2416,
|
||||
2417, 2418, 2425, 2433, 2434, 2437, 2447, 2451, 2474, 2482,
|
||||
2486, 2492, 2493, 2494, 2497, 2503, 2507, 2509, 2510, 2519,
|
||||
2524, 2527, 2530, 2534, 2544, 2546, 2548, 2554, 2555, 2561,
|
||||
2563, 2565, 2575, 2579, 2602, 2610, 2613, 2616, 2620, 2622,
|
||||
2625, 2631, 2635, 2641, 2649, 2654, 2662, 2672, 2674, 2677,
|
||||
2689, 2691, 2693, 2703, 2707, 2730, 2738, 2741, 2748, 2749,
|
||||
2750, 2753, 2759, 2761, 2763, 2765, 2768, 2784, 2786, 2790,
|
||||
2800, 2801, 2817, 2818, 2821, 2831, 2835, 2858, 2866, 2869,
|
||||
2876, 2877, 2878, 2879, 2880, 2881, 2887, 2891, 2893, 2902,
|
||||
2903, 2908, 2911, 2914, 2918, 2928, 2929, 2930, 2946, 2947,
|
||||
2949, 2958, 2962, 2969, 2972, 2974, 2979, 2984, 2990, 3006,
|
||||
3008, 3009, 3014, 3018, 3021, 3024, 3031, 3046, 3056, 3059,
|
||||
3065, 3066, 3073, 3077, 3086, 3090, 3114, 3125, 3133, 3134,
|
||||
3137, 3142, 3146, 3157, 3160, 3168, 3170, 3174, 3192, 3199,
|
||||
3202, 3205, 3214, 3218, 3242, 3253, 3260, 3261, 3262, 3263,
|
||||
3264, 3270, 3271, 3274, 3276, 3285, 3294, 3296, 3298, 3302,
|
||||
3313, 3330, 3333, 3342, 3346, 3389, 3390, 3393, 3398, 3402,
|
||||
3405, 3406, 3415, 3424, 3426, 3430, 3440, 3449, 3450, 3458,
|
||||
3461, 3482, 3507, 3517, 3520, 3530, 3535, 3538, 3542, 3544,
|
||||
3570, 3572, 3585, 3633, 3634, 3636, 3647, 3648, 3654, 3655,
|
||||
3663, 3664, 3674, 3713, 3716, 3719, 3722, 3725, 3732, 3737,
|
||||
3745, 3749, 3751, 3754, 3757, 3761, 3762, 3764, 3771, 3773,
|
||||
3776, 3782, 3784, 3792, 3804, 3840, 3841, 3844, 3859, 3860,
|
||||
3861, 3864, 3866, 3872, 3882, 3892, 3893, 3894, 3895, 3896,
|
||||
3897, 3898, 3899, 3900, 3901, 3902, 3904, 3913, 3953, 3967,
|
||||
3968, 3973, 3974, 3976, 3981, 3993, 4030, 4038, 4039, 4046,
|
||||
4048, 4053, 4057, 4096, 4139, 4141, 4145, 4146, 4152, 4153,
|
||||
4155, 4157, 4159, 4160, 4170, 4176, 4182, 4184, 4186, 4190,
|
||||
4193, 4194, 4197, 4199, 4206, 4209, 4213, 4226, 4227, 4229,
|
||||
4231, 4237, 4238, 4239, 4240, 4250, 4253, 4254, 4256, 4295,
|
||||
4301, 4304, 4347, 4348, 4349, 4682, 4688, 4696, 4698, 4704,
|
||||
4746, 4752, 4786, 4792, 4800, 4802, 4808, 4824, 4882, 4888,
|
||||
4957, 4960, 4969, 4992, 5008, 5024, 5120, 5121, 5741, 5743,
|
||||
5760, 5761, 5787, 5788, 5792, 5867, 5870, 5888, 5902, 5906,
|
||||
5920, 5938, 5941, 5952, 5970, 5984, 5998, 6002, 6016, 6068,
|
||||
6070, 6071, 6078, 6086, 6087, 6089, 6100, 6103, 6104, 6107,
|
||||
6108, 6109, 6112, 6128, 6144, 6150, 6151, 6155, 6158, 6160,
|
||||
6176, 6211, 6212, 6272, 6313, 6314, 6320, 6400, 6432, 6435,
|
||||
6439, 6441, 6448, 6450, 6451, 6457, 6464, 6468, 6470, 6480,
|
||||
6512, 6528, 6576, 6593, 6600, 6608, 6618, 6622, 6656, 6679,
|
||||
6681, 6686, 6688, 6741, 6742, 6743, 6744, 6752, 6753, 6754,
|
||||
6755, 6757, 6765, 6771, 6783, 6784, 6800, 6816, 6823, 6824,
|
||||
6912, 6916, 6917, 6964, 6965, 6966, 6971, 6972, 6973, 6978,
|
||||
6979, 6981, 6992, 7002, 7009, 7019, 7028, 7040, 7042, 7043,
|
||||
7073, 7074, 7078, 7080, 7082, 7083, 7084, 7086, 7088, 7098,
|
||||
7142, 7143, 7144, 7146, 7149, 7150, 7151, 7154, 7164, 7168,
|
||||
7204, 7212, 7220, 7222, 7227, 7232, 7245, 7248, 7258, 7288,
|
||||
7294, 7360, 7376, 7379, 7380, 7393, 7394, 7401, 7405, 7406,
|
||||
7410, 7412, 7413, 7424, 7468, 7531, 7544, 7545, 7579, 7616,
|
||||
7676, 7680, 7830, 7838, 7936, 7944, 7952, 7960, 7968, 7976,
|
||||
7984, 7992, 8000, 8008, 8016, 8025, 8027, 8029, 8031, 8033,
|
||||
8040, 8048, 8064, 8072, 8080, 8088, 8096, 8104, 8112, 8118,
|
||||
8120, 8124, 8125, 8126, 8127, 8130, 8134, 8136, 8140, 8141,
|
||||
8144, 8150, 8152, 8157, 8160, 8168, 8173, 8178, 8182, 8184,
|
||||
8188, 8189, 8192, 8203, 8208, 8214, 8216, 8217, 8218, 8219,
|
||||
8221, 8222, 8223, 8224, 8232, 8233, 8234, 8239, 8240, 8249,
|
||||
8250, 8251, 8255, 8257, 8260, 8261, 8262, 8263, 8274, 8275,
|
||||
8276, 8277, 8287, 8288, 8298, 8304, 8305, 8308, 8314, 8317,
|
||||
8318, 8319, 8320, 8330, 8333, 8334, 8336, 8352, 8400, 8413,
|
||||
8417, 8418, 8421, 8448, 8450, 8451, 8455, 8456, 8458, 8459,
|
||||
8462, 8464, 8467, 8468, 8469, 8470, 8472, 8473, 8478, 8484,
|
||||
8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495, 8496, 8500,
|
||||
8501, 8505, 8506, 8508, 8510, 8512, 8517, 8519, 8522, 8523,
|
||||
8524, 8526, 8527, 8528, 8544, 8579, 8581, 8585, 8592, 8597,
|
||||
8602, 8604, 8608, 8609, 8611, 8612, 8614, 8615, 8622, 8623,
|
||||
8654, 8656, 8658, 8659, 8660, 8661, 8692, 8960, 8968, 8972,
|
||||
8992, 8994, 9001, 9002, 9003, 9084, 9085, 9115, 9140, 9180,
|
||||
9186, 9216, 9280, 9312, 9372, 9450, 9472, 9655, 9656, 9665,
|
||||
9666, 9720, 9728, 9839, 9840, 9985, 10088, 10089, 10090, 10091,
|
||||
10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101,
|
||||
10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217,
|
||||
10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627,
|
||||
10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637,
|
||||
10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647,
|
||||
10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750,
|
||||
11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365,
|
||||
11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393,
|
||||
11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520,
|
||||
11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696,
|
||||
11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780,
|
||||
11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800,
|
||||
11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812,
|
||||
11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904,
|
||||
11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296,
|
||||
12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306,
|
||||
12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317,
|
||||
12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347,
|
||||
12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449,
|
||||
12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736,
|
||||
12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938,
|
||||
12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981,
|
||||
40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528,
|
||||
42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624,
|
||||
42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800,
|
||||
42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912,
|
||||
43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043,
|
||||
43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136,
|
||||
43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264,
|
||||
43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395,
|
||||
43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472,
|
||||
43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588,
|
||||
43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643,
|
||||
43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713,
|
||||
43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762,
|
||||
43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003,
|
||||
44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203,
|
||||
55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112,
|
||||
64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320,
|
||||
64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020,
|
||||
65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075,
|
||||
65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086,
|
||||
65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097,
|
||||
65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118,
|
||||
65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279,
|
||||
65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294,
|
||||
65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343,
|
||||
65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378,
|
||||
65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490,
|
||||
65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529,
|
||||
65532, 0, 13, 40, 60, 63, 80, 128, 256, 263,
|
||||
311, 320, 373, 377, 394, 400, 464, 509, 640, 672,
|
||||
768, 800, 816, 833, 834, 842, 896, 927, 928, 968,
|
||||
976, 977, 1024, 1064, 1104, 1184, 2048, 2056, 2058, 2103,
|
||||
2108, 2111, 2135, 2136, 2304, 2326, 2335, 2336, 2367, 2432,
|
||||
2494, 2560, 2561, 2565, 2572, 2576, 2581, 2585, 2616, 2623,
|
||||
2624, 2640, 2656, 2685, 2687, 2816, 2873, 2880, 2904, 2912,
|
||||
2936, 3072, 3680, 4096, 4097, 4098, 4099, 4152, 4167, 4178,
|
||||
4198, 4224, 4226, 4227, 4272, 4275, 4279, 4281, 4283, 4285,
|
||||
4286, 4304, 4336, 4352, 4355, 4391, 4396, 4397, 4406, 4416,
|
||||
4480, 4482, 4483, 4531, 4534, 4543, 4545, 4549, 4560, 5760,
|
||||
5803, 5804, 5805, 5806, 5808, 5814, 5815, 5824, 8192, 9216,
|
||||
9328, 12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248,
|
||||
53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637,
|
||||
53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298,
|
||||
54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441,
|
||||
54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541,
|
||||
54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662,
|
||||
54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922,
|
||||
54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062,
|
||||
55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178,
|
||||
55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961,
|
||||
60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003,
|
||||
61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028,
|
||||
61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099,
|
||||
61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744,
|
||||
61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368,
|
||||
62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971,
|
||||
63045, 63104, 63232, 0, 42710, 42752, 46900, 46912, 47133, 63488,
|
||||
1, 32, 256, 0, 65533,
|
||||
};
|
||||
static u16 aFts5UnicodeData[] = {
|
||||
1025, 61, 117, 55, 117, 54, 50, 53, 57, 53,
|
||||
49, 85, 333, 85, 121, 85, 841, 54, 53, 50,
|
||||
56, 48, 56, 837, 54, 57, 50, 57, 1057, 61,
|
||||
53, 151, 58, 53, 56, 58, 39, 52, 57, 34,
|
||||
58, 56, 58, 57, 79, 56, 37, 85, 56, 47,
|
||||
39, 51, 111, 53, 745, 57, 233, 773, 57, 261,
|
||||
1822, 37, 542, 37, 1534, 222, 69, 73, 37, 126,
|
||||
126, 73, 69, 137, 37, 73, 37, 105, 101, 73,
|
||||
37, 73, 37, 190, 158, 37, 126, 126, 73, 37,
|
||||
126, 94, 37, 39, 94, 69, 135, 41, 40, 37,
|
||||
41, 40, 37, 41, 40, 37, 542, 37, 606, 37,
|
||||
41, 40, 37, 126, 73, 37, 1886, 197, 73, 37,
|
||||
73, 69, 126, 105, 37, 286, 2181, 39, 869, 582,
|
||||
152, 390, 472, 166, 248, 38, 56, 38, 568, 3596,
|
||||
158, 38, 56, 94, 38, 101, 53, 88, 41, 53,
|
||||
105, 41, 73, 37, 553, 297, 1125, 94, 37, 105,
|
||||
101, 798, 133, 94, 57, 126, 94, 37, 1641, 1541,
|
||||
1118, 58, 172, 75, 1790, 478, 37, 2846, 1225, 38,
|
||||
213, 1253, 53, 49, 55, 1452, 49, 44, 53, 76,
|
||||
53, 76, 53, 44, 871, 103, 85, 162, 121, 85,
|
||||
55, 85, 90, 364, 53, 85, 1031, 38, 327, 684,
|
||||
333, 149, 71, 44, 3175, 53, 39, 236, 34, 58,
|
||||
204, 70, 76, 58, 140, 71, 333, 103, 90, 39,
|
||||
469, 34, 39, 44, 967, 876, 2855, 364, 39, 333,
|
||||
1063, 300, 70, 58, 117, 38, 711, 140, 38, 300,
|
||||
38, 108, 38, 172, 501, 807, 108, 53, 39, 359,
|
||||
876, 108, 42, 1735, 44, 42, 44, 39, 106, 268,
|
||||
138, 44, 74, 39, 236, 327, 76, 85, 333, 53,
|
||||
38, 199, 231, 44, 74, 263, 71, 711, 231, 39,
|
||||
135, 44, 39, 106, 140, 74, 74, 44, 39, 42,
|
||||
71, 103, 76, 333, 71, 87, 207, 58, 55, 76,
|
||||
42, 199, 71, 711, 231, 71, 71, 71, 44, 106,
|
||||
76, 76, 108, 44, 135, 39, 333, 76, 103, 44,
|
||||
76, 42, 295, 103, 711, 231, 71, 167, 44, 39,
|
||||
106, 172, 76, 42, 74, 44, 39, 71, 76, 333,
|
||||
53, 55, 44, 74, 263, 71, 711, 231, 71, 167,
|
||||
44, 39, 42, 44, 42, 140, 74, 74, 44, 44,
|
||||
42, 71, 103, 76, 333, 58, 39, 207, 44, 39,
|
||||
199, 103, 135, 71, 39, 71, 71, 103, 391, 74,
|
||||
44, 74, 106, 106, 44, 39, 42, 333, 111, 218,
|
||||
55, 58, 106, 263, 103, 743, 327, 167, 39, 108,
|
||||
138, 108, 140, 76, 71, 71, 76, 333, 239, 58,
|
||||
74, 263, 103, 743, 327, 167, 44, 39, 42, 44,
|
||||
170, 44, 74, 74, 76, 74, 39, 71, 76, 333,
|
||||
71, 74, 263, 103, 1319, 39, 106, 140, 106, 106,
|
||||
44, 39, 42, 71, 76, 333, 207, 58, 199, 74,
|
||||
583, 775, 295, 39, 231, 44, 106, 108, 44, 266,
|
||||
74, 53, 1543, 44, 71, 236, 55, 199, 38, 268,
|
||||
53, 333, 85, 71, 39, 71, 39, 39, 135, 231,
|
||||
103, 39, 39, 71, 135, 44, 71, 204, 76, 39,
|
||||
167, 38, 204, 333, 135, 39, 122, 501, 58, 53,
|
||||
122, 76, 218, 333, 335, 58, 44, 58, 44, 58,
|
||||
44, 54, 50, 54, 50, 74, 263, 1159, 460, 42,
|
||||
172, 53, 76, 167, 364, 1164, 282, 44, 218, 90,
|
||||
181, 154, 85, 1383, 74, 140, 42, 204, 42, 76,
|
||||
74, 76, 39, 333, 213, 199, 74, 76, 135, 108,
|
||||
39, 106, 71, 234, 103, 140, 423, 44, 74, 76,
|
||||
202, 44, 39, 42, 333, 106, 44, 90, 1225, 41,
|
||||
41, 1383, 53, 38, 10631, 135, 231, 39, 135, 1319,
|
||||
135, 1063, 135, 231, 39, 135, 487, 1831, 135, 2151,
|
||||
108, 309, 655, 519, 346, 2727, 49, 19847, 85, 551,
|
||||
61, 839, 54, 50, 2407, 117, 110, 423, 135, 108,
|
||||
583, 108, 85, 583, 76, 423, 103, 76, 1671, 76,
|
||||
42, 236, 266, 44, 74, 364, 117, 38, 117, 55,
|
||||
39, 44, 333, 335, 213, 49, 149, 108, 61, 333,
|
||||
1127, 38, 1671, 1319, 44, 39, 2247, 935, 108, 138,
|
||||
76, 106, 74, 44, 202, 108, 58, 85, 333, 967,
|
||||
167, 1415, 554, 231, 74, 333, 47, 1114, 743, 76,
|
||||
106, 85, 1703, 42, 44, 42, 236, 44, 42, 44,
|
||||
74, 268, 202, 332, 44, 333, 333, 245, 38, 213,
|
||||
140, 42, 1511, 44, 42, 172, 42, 44, 170, 44,
|
||||
74, 231, 333, 245, 346, 300, 314, 76, 42, 967,
|
||||
42, 140, 74, 76, 42, 44, 74, 71, 333, 1415,
|
||||
44, 42, 76, 106, 44, 42, 108, 74, 149, 1159,
|
||||
266, 268, 74, 76, 181, 333, 103, 333, 967, 198,
|
||||
85, 277, 108, 53, 428, 42, 236, 135, 44, 135,
|
||||
74, 44, 71, 1413, 2022, 421, 38, 1093, 1190, 1260,
|
||||
140, 4830, 261, 3166, 261, 265, 197, 201, 261, 265,
|
||||
261, 265, 197, 201, 261, 41, 41, 41, 94, 229,
|
||||
265, 453, 261, 264, 261, 264, 261, 264, 165, 69,
|
||||
137, 40, 56, 37, 120, 101, 69, 137, 40, 120,
|
||||
133, 69, 137, 120, 261, 169, 120, 101, 69, 137,
|
||||
40, 88, 381, 162, 209, 85, 52, 51, 54, 84,
|
||||
51, 54, 52, 277, 59, 60, 162, 61, 309, 52,
|
||||
51, 149, 80, 117, 57, 54, 50, 373, 57, 53,
|
||||
48, 341, 61, 162, 194, 47, 38, 207, 121, 54,
|
||||
50, 38, 335, 121, 54, 50, 422, 855, 428, 139,
|
||||
44, 107, 396, 90, 41, 154, 41, 90, 37, 105,
|
||||
69, 105, 37, 58, 41, 90, 57, 169, 218, 41,
|
||||
58, 41, 58, 41, 58, 137, 58, 37, 137, 37,
|
||||
135, 37, 90, 69, 73, 185, 94, 101, 58, 57,
|
||||
90, 37, 58, 527, 1134, 94, 142, 47, 185, 186,
|
||||
89, 154, 57, 90, 57, 90, 57, 250, 57, 1018,
|
||||
89, 90, 57, 58, 57, 1018, 8601, 282, 153, 666,
|
||||
89, 250, 54, 50, 2618, 57, 986, 825, 1306, 217,
|
||||
602, 1274, 378, 1935, 2522, 719, 5882, 57, 314, 57,
|
||||
1754, 281, 3578, 57, 4634, 3322, 54, 50, 54, 50,
|
||||
54, 50, 54, 50, 54, 50, 54, 50, 54, 50,
|
||||
975, 1434, 185, 54, 50, 1017, 54, 50, 54, 50,
|
||||
54, 50, 54, 50, 54, 50, 537, 8218, 4217, 54,
|
||||
50, 54, 50, 54, 50, 54, 50, 54, 50, 54,
|
||||
50, 54, 50, 54, 50, 54, 50, 54, 50, 54,
|
||||
50, 2041, 54, 50, 54, 50, 1049, 54, 50, 8281,
|
||||
1562, 697, 90, 217, 346, 1513, 1509, 126, 73, 69,
|
||||
254, 105, 37, 94, 37, 94, 165, 70, 105, 37,
|
||||
3166, 37, 218, 158, 108, 94, 149, 47, 85, 1221,
|
||||
37, 37, 1799, 38, 53, 44, 743, 231, 231, 231,
|
||||
231, 231, 231, 231, 231, 1036, 85, 52, 51, 52,
|
||||
51, 117, 52, 51, 53, 52, 51, 309, 49, 85,
|
||||
49, 53, 52, 51, 85, 52, 51, 54, 50, 54,
|
||||
50, 54, 50, 54, 50, 181, 38, 341, 81, 858,
|
||||
2874, 6874, 410, 61, 117, 58, 38, 39, 46, 54,
|
||||
50, 54, 50, 54, 50, 54, 50, 54, 50, 90,
|
||||
54, 50, 54, 50, 54, 50, 54, 50, 49, 54,
|
||||
82, 58, 302, 140, 74, 49, 166, 90, 110, 38,
|
||||
39, 53, 90, 2759, 76, 88, 70, 39, 49, 2887,
|
||||
53, 102, 39, 1319, 3015, 90, 143, 346, 871, 1178,
|
||||
519, 1018, 335, 986, 271, 58, 495, 1050, 335, 1274,
|
||||
495, 2042, 8218, 39, 39, 2074, 39, 39, 679, 38,
|
||||
36583, 1786, 1287, 198, 85, 8583, 38, 117, 519, 333,
|
||||
71, 1502, 39, 44, 107, 53, 332, 53, 38, 798,
|
||||
44, 2247, 334, 76, 213, 760, 294, 88, 478, 69,
|
||||
2014, 38, 261, 190, 350, 38, 88, 158, 158, 382,
|
||||
70, 37, 231, 44, 103, 44, 135, 44, 743, 74,
|
||||
76, 42, 154, 207, 90, 55, 58, 1671, 149, 74,
|
||||
1607, 522, 44, 85, 333, 588, 199, 117, 39, 333,
|
||||
903, 268, 85, 743, 364, 74, 53, 935, 108, 42,
|
||||
1511, 44, 74, 140, 74, 44, 138, 437, 38, 333,
|
||||
85, 1319, 204, 74, 76, 74, 76, 103, 44, 263,
|
||||
44, 42, 333, 149, 519, 38, 199, 122, 39, 42,
|
||||
1543, 44, 39, 108, 71, 76, 167, 76, 39, 44,
|
||||
39, 71, 38, 85, 359, 42, 76, 74, 85, 39,
|
||||
70, 42, 44, 199, 199, 199, 231, 231, 1127, 74,
|
||||
44, 74, 44, 74, 53, 42, 44, 333, 39, 39,
|
||||
743, 1575, 36, 68, 68, 36, 63, 63, 11719, 3399,
|
||||
229, 165, 39, 44, 327, 57, 423, 167, 39, 71,
|
||||
71, 3463, 536, 11623, 54, 50, 2055, 1735, 391, 55,
|
||||
58, 524, 245, 54, 50, 53, 236, 53, 81, 80,
|
||||
54, 50, 54, 50, 54, 50, 54, 50, 54, 50,
|
||||
54, 50, 54, 50, 54, 50, 85, 54, 50, 149,
|
||||
112, 117, 149, 49, 54, 50, 54, 50, 54, 50,
|
||||
117, 57, 49, 121, 53, 55, 85, 167, 4327, 34,
|
||||
117, 55, 117, 54, 50, 53, 57, 53, 49, 85,
|
||||
333, 85, 121, 85, 841, 54, 53, 50, 56, 48,
|
||||
56, 837, 54, 57, 50, 57, 54, 50, 53, 54,
|
||||
50, 85, 327, 38, 1447, 70, 999, 199, 199, 199,
|
||||
103, 87, 57, 56, 58, 87, 58, 153, 90, 98,
|
||||
90, 391, 839, 615, 71, 487, 455, 3943, 117, 1455,
|
||||
314, 1710, 143, 570, 47, 410, 1466, 44, 935, 1575,
|
||||
999, 143, 551, 46, 263, 46, 967, 53, 1159, 263,
|
||||
53, 174, 1289, 1285, 2503, 333, 199, 39, 1415, 71,
|
||||
39, 743, 53, 271, 711, 207, 53, 839, 53, 1799,
|
||||
71, 39, 108, 76, 140, 135, 103, 871, 108, 44,
|
||||
271, 309, 935, 79, 53, 1735, 245, 711, 271, 615,
|
||||
271, 2343, 1007, 42, 44, 42, 1703, 492, 245, 655,
|
||||
333, 76, 42, 1447, 106, 140, 74, 76, 85, 34,
|
||||
149, 807, 333, 108, 1159, 172, 42, 268, 333, 149,
|
||||
76, 42, 1543, 106, 300, 74, 135, 149, 333, 1383,
|
||||
44, 42, 44, 74, 204, 42, 44, 333, 28135, 3182,
|
||||
149, 34279, 18215, 2215, 39, 1482, 140, 422, 71, 7898,
|
||||
1274, 1946, 74, 108, 122, 202, 258, 268, 90, 236,
|
||||
986, 140, 1562, 2138, 108, 58, 2810, 591, 841, 837,
|
||||
841, 229, 581, 841, 837, 41, 73, 41, 73, 137,
|
||||
265, 133, 37, 229, 357, 841, 837, 73, 137, 265,
|
||||
233, 837, 73, 137, 169, 41, 233, 837, 841, 837,
|
||||
841, 837, 841, 837, 841, 837, 841, 837, 841, 901,
|
||||
809, 57, 805, 57, 197, 809, 57, 805, 57, 197,
|
||||
809, 57, 805, 57, 197, 809, 57, 805, 57, 197,
|
||||
809, 57, 805, 57, 197, 94, 1613, 135, 871, 71,
|
||||
39, 39, 327, 135, 39, 39, 39, 39, 39, 39,
|
||||
103, 71, 39, 39, 39, 39, 39, 39, 71, 39,
|
||||
135, 231, 135, 135, 39, 327, 551, 103, 167, 551,
|
||||
89, 1434, 3226, 506, 474, 506, 506, 367, 1018, 1946,
|
||||
1402, 954, 1402, 314, 90, 1082, 218, 2266, 666, 1210,
|
||||
186, 570, 2042, 58, 5850, 154, 2010, 154, 794, 2266,
|
||||
378, 2266, 3738, 39, 39, 39, 39, 39, 39, 17351,
|
||||
34, 3074, 7692, 63, 63,
|
||||
};
|
||||
|
||||
int sqlite3Fts5UnicodeCategory(u32 iCode) {
|
||||
int iRes = -1;
|
||||
int iHi;
|
||||
int iLo;
|
||||
int ret;
|
||||
u16 iKey;
|
||||
|
||||
if( iCode>=(1<<20) ){
|
||||
return 0;
|
||||
}
|
||||
iLo = aFts5UnicodeBlock[(iCode>>16)];
|
||||
iHi = aFts5UnicodeBlock[1+(iCode>>16)];
|
||||
iKey = (iCode & 0xFFFF);
|
||||
while( iHi>iLo ){
|
||||
int iTest = (iHi + iLo) / 2;
|
||||
assert( iTest>=iLo && iTest<iHi );
|
||||
if( iKey>=aFts5UnicodeMap[iTest] ){
|
||||
iRes = iTest;
|
||||
iLo = iTest+1;
|
||||
}else{
|
||||
iHi = iTest;
|
||||
}
|
||||
}
|
||||
|
||||
if( iRes<0 ) return 0;
|
||||
if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
|
||||
ret = aFts5UnicodeData[iRes] & 0x1F;
|
||||
if( ret!=30 ) return ret;
|
||||
return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9;
|
||||
}
|
||||
|
||||
void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
|
||||
int i = 0;
|
||||
int iTbl = 0;
|
||||
while( i<128 ){
|
||||
int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
|
||||
int n = (aFts5UnicodeData[iTbl] >> 5) + i;
|
||||
for(; i<128 && i<n; i++){
|
||||
aAscii[i] = (u8)bToken;
|
||||
}
|
||||
iTbl++;
|
||||
}
|
||||
aAscii[0] = 0; /* 0x00 is never a token character */
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
|
||||
u8 n;
|
||||
p -= 2;
|
||||
n = sqlite3Fts5GetVarint(p, &v64);
|
||||
*v = ((u32)v64) & 0x7FFFFFFF;
|
||||
*v = (u32)v64;
|
||||
assert( n>3 && n<=9 );
|
||||
return n;
|
||||
}
|
||||
@@ -342,3 +342,4 @@ int sqlite3Fts5GetVarintLen(u32 iVal){
|
||||
if( iVal<(1 << 28) ) return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
+36
-63
@@ -50,22 +50,21 @@ struct Fts5VocabTable {
|
||||
sqlite3 *db; /* Database handle */
|
||||
Fts5Global *pGlobal; /* FTS5 global object for this database */
|
||||
int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */
|
||||
unsigned bBusy; /* True if busy */
|
||||
};
|
||||
|
||||
struct Fts5VocabCursor {
|
||||
sqlite3_vtab_cursor base;
|
||||
sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
|
||||
Fts5Table *pFts5; /* Associated FTS5 table */
|
||||
Fts5Index *pIndex; /* Associated FTS5 index */
|
||||
|
||||
int bEof; /* True if this cursor is at EOF */
|
||||
Fts5IndexIter *pIter; /* Term/rowid iterator object */
|
||||
void *pStruct; /* From sqlite3Fts5StructureRef() */
|
||||
|
||||
int nLeTerm; /* Size of zLeTerm in bytes */
|
||||
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
|
||||
|
||||
/* These are used by 'col' tables only */
|
||||
Fts5Config *pConfig; /* Fts5 table configuration */
|
||||
int iCol;
|
||||
i64 *aCnt;
|
||||
i64 *aDoc;
|
||||
@@ -328,18 +327,13 @@ static int fts5VocabOpenMethod(
|
||||
sqlite3_vtab_cursor **ppCsr
|
||||
){
|
||||
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
|
||||
Fts5Table *pFts5 = 0;
|
||||
Fts5Index *pIndex = 0;
|
||||
Fts5Config *pConfig = 0;
|
||||
Fts5VocabCursor *pCsr = 0;
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char *zSql = 0;
|
||||
|
||||
if( pTab->bBusy ){
|
||||
pVTab->zErrMsg = sqlite3_mprintf(
|
||||
"recursive definition for %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
zSql = sqlite3Fts5Mprintf(&rc,
|
||||
"SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
|
||||
pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
|
||||
@@ -351,38 +345,33 @@ static int fts5VocabOpenMethod(
|
||||
assert( rc==SQLITE_OK || pStmt==0 );
|
||||
if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
|
||||
|
||||
pTab->bBusy = 1;
|
||||
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
i64 iId = sqlite3_column_int64(pStmt, 0);
|
||||
pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
|
||||
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
|
||||
}
|
||||
pTab->bBusy = 0;
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pFts5==0 ){
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
pVTab->zErrMsg = sqlite3_mprintf(
|
||||
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}else{
|
||||
rc = sqlite3Fts5FlushToDisk(pFts5);
|
||||
if( rc==SQLITE_OK && pIndex==0 ){
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
pVTab->zErrMsg = sqlite3_mprintf(
|
||||
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
|
||||
int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
|
||||
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
|
||||
}
|
||||
|
||||
if( pCsr ){
|
||||
pCsr->pFts5 = pFts5;
|
||||
pCsr->pIndex = pIndex;
|
||||
pCsr->pStmt = pStmt;
|
||||
pCsr->pConfig = pConfig;
|
||||
pCsr->aCnt = (i64*)&pCsr[1];
|
||||
pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol];
|
||||
pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
|
||||
}else{
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
@@ -394,13 +383,10 @@ static int fts5VocabOpenMethod(
|
||||
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
|
||||
pCsr->rowid = 0;
|
||||
sqlite3Fts5IterClose(pCsr->pIter);
|
||||
sqlite3Fts5StructureRelease(pCsr->pStruct);
|
||||
pCsr->pStruct = 0;
|
||||
pCsr->pIter = 0;
|
||||
sqlite3_free(pCsr->zLeTerm);
|
||||
pCsr->nLeTerm = -1;
|
||||
pCsr->zLeTerm = 0;
|
||||
pCsr->bEof = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -439,14 +425,12 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
|
||||
}
|
||||
|
||||
static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
|
||||
int eDetail = pCsr->pFts5->pConfig->eDetail;
|
||||
int eDetail = pCsr->pConfig->eDetail;
|
||||
int rc = SQLITE_OK;
|
||||
Fts5IndexIter *pIter = pCsr->pIter;
|
||||
i64 *pp = &pCsr->iInstPos;
|
||||
int *po = &pCsr->iInstOff;
|
||||
|
||||
assert( sqlite3Fts5IterEof(pIter)==0 );
|
||||
assert( pCsr->bEof==0 );
|
||||
while( eDetail==FTS5_DETAIL_NONE
|
||||
|| sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
|
||||
){
|
||||
@@ -456,7 +440,7 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
|
||||
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5VocabInstanceNewTerm(pCsr);
|
||||
if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
|
||||
if( eDetail==FTS5_DETAIL_NONE ) break;
|
||||
}
|
||||
if( rc ){
|
||||
pCsr->bEof = 1;
|
||||
@@ -473,11 +457,9 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
|
||||
static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
|
||||
int nCol = pCsr->pFts5->pConfig->nCol;
|
||||
int rc;
|
||||
int rc = SQLITE_OK;
|
||||
int nCol = pCsr->pConfig->nCol;
|
||||
|
||||
rc = sqlite3Fts5StructureTest(pCsr->pFts5->pIndex, pCsr->pStruct);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
pCsr->rowid++;
|
||||
|
||||
if( pTab->eType==FTS5_VOCAB_INSTANCE ){
|
||||
@@ -498,7 +480,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
int nTerm;
|
||||
|
||||
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
|
||||
assert( nTerm>=0 );
|
||||
if( pCsr->nLeTerm>=0 ){
|
||||
int nCmp = MIN(nTerm, pCsr->nLeTerm);
|
||||
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
|
||||
@@ -515,7 +496,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
|
||||
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
|
||||
while( rc==SQLITE_OK ){
|
||||
int eDetail = pCsr->pFts5->pConfig->eDetail;
|
||||
int eDetail = pCsr->pConfig->eDetail;
|
||||
const u8 *pPos; int nPos; /* Position list */
|
||||
i64 iPos = 0; /* 64-bit position read from poslist */
|
||||
int iOff = 0; /* Current offset within position list */
|
||||
@@ -538,6 +519,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
int iCol = -1;
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
|
||||
int ii = FTS5_POS2COLUMN(iPos);
|
||||
pCsr->aCnt[ii]++;
|
||||
if( iCol!=ii ){
|
||||
if( ii>=nCol ){
|
||||
rc = FTS5_CORRUPT;
|
||||
@@ -546,7 +528,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
pCsr->aDoc[ii]++;
|
||||
iCol = ii;
|
||||
}
|
||||
pCsr->aCnt[ii]++;
|
||||
}
|
||||
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
|
||||
@@ -575,9 +556,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
|
||||
if( nTerm!=pCsr->term.n
|
||||
|| (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm))
|
||||
){
|
||||
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
|
||||
break;
|
||||
}
|
||||
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
|
||||
@@ -587,10 +566,8 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
|
||||
for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
|
||||
if( pCsr->iCol==nCol ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
|
||||
assert( pCsr->iCol<pCsr->pConfig->nCol );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -637,7 +614,6 @@ static int fts5VocabFilterMethod(
|
||||
}
|
||||
if( pLe ){
|
||||
const char *zCopy = (const char *)sqlite3_value_text(pLe);
|
||||
if( zCopy==0 ) zCopy = "";
|
||||
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
|
||||
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
|
||||
if( pCsr->zLeTerm==0 ){
|
||||
@@ -649,18 +625,14 @@ static int fts5VocabFilterMethod(
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
Fts5Index *pIndex = pCsr->pFts5->pIndex;
|
||||
rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
|
||||
if( rc==SQLITE_OK ){
|
||||
pCsr->pStruct = sqlite3Fts5StructureRef(pIndex);
|
||||
}
|
||||
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
|
||||
}
|
||||
if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
|
||||
rc = fts5VocabInstanceNewTerm(pCsr);
|
||||
}
|
||||
if( rc==SQLITE_OK && !pCsr->bEof
|
||||
&& (eType!=FTS5_VOCAB_INSTANCE
|
||||
|| pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE)
|
||||
if( rc==SQLITE_OK
|
||||
&& !pCsr->bEof
|
||||
&& (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
|
||||
){
|
||||
rc = fts5VocabNextMethod(pCursor);
|
||||
}
|
||||
@@ -683,7 +655,7 @@ static int fts5VocabColumnMethod(
|
||||
int iCol /* Index of column to read value from */
|
||||
){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
int eDetail = pCsr->pFts5->pConfig->eDetail;
|
||||
int eDetail = pCsr->pConfig->eDetail;
|
||||
int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
|
||||
i64 iVal = 0;
|
||||
|
||||
@@ -695,7 +667,7 @@ static int fts5VocabColumnMethod(
|
||||
assert( iCol==1 || iCol==2 || iCol==3 );
|
||||
if( iCol==1 ){
|
||||
if( eDetail!=FTS5_DETAIL_NONE ){
|
||||
const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol];
|
||||
const char *z = pCsr->pConfig->azCol[pCsr->iCol];
|
||||
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
|
||||
}
|
||||
}else if( iCol==2 ){
|
||||
@@ -723,8 +695,8 @@ static int fts5VocabColumnMethod(
|
||||
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
ii = (int)pCsr->iInstPos;
|
||||
}
|
||||
if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){
|
||||
const char *z = pCsr->pFts5->pConfig->azCol[ii];
|
||||
if( ii>=0 && ii<pCsr->pConfig->nCol ){
|
||||
const char *z = pCsr->pConfig->azCol[ii];
|
||||
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
|
||||
}
|
||||
break;
|
||||
@@ -783,9 +755,10 @@ int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
|
||||
/* xSavepoint */ 0,
|
||||
/* xRelease */ 0,
|
||||
/* xRollbackTo */ 0,
|
||||
/* xShadowName */ 0
|
||||
};
|
||||
void *p = (void*)pGlobal;
|
||||
|
||||
return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ do_execsql_test 1.0 {
|
||||
do_execsql_test 1.1 {
|
||||
DROP TABLE t1;
|
||||
SELECT name, sql FROM sqlite_master;
|
||||
} {}
|
||||
} {
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -408,7 +409,6 @@ do_test 14.3 {
|
||||
do_execsql_test 15.0 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_execsql_test 15.1 {
|
||||
UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
|
||||
}
|
||||
@@ -427,7 +427,7 @@ proc funk {} {
|
||||
db eval { UPDATE n1_config SET v=50 WHERE k='version' }
|
||||
set fd [db incrblob main n1_data block 10]
|
||||
fconfigure $fd -encoding binary -translation binary
|
||||
# puts -nonewline $fd "\x44\x45"
|
||||
puts -nonewline $fd "\x44\x45"
|
||||
close $fd
|
||||
}
|
||||
db func funk funk
|
||||
@@ -591,50 +591,6 @@ do_execsql_test 22.1 {
|
||||
SELECT rowid FROM t9('a*')
|
||||
} {1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 23.0 {
|
||||
CREATE VIRTUAL TABLE t10 USING fts5(x, detail=%DETAIL%);
|
||||
CREATE TABLE t11(x);
|
||||
}
|
||||
do_execsql_test 23.1 {
|
||||
SELECT * FROM t11, t10 WHERE t11.x = t10.x AND t10.rowid IS NULL;
|
||||
}
|
||||
do_execsql_test 23.2 {
|
||||
SELECT * FROM t11, t10 WHERE t10.rowid IS NULL;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 24.0 {
|
||||
CREATE VIRTUAL TABLE t12 USING fts5(x, detail=%DETAIL%);
|
||||
INSERT INTO t12 VALUES('aaaa');
|
||||
}
|
||||
do_execsql_test 24.1 {
|
||||
BEGIN;
|
||||
DELETE FROM t12 WHERE rowid=1;
|
||||
SELECT * FROM t12('aaaa');
|
||||
INSERT INTO t12 VALUES('aaaa');
|
||||
END;
|
||||
}
|
||||
do_execsql_test 24.2 {
|
||||
INSERT INTO t12(t12) VALUES('integrity-check');
|
||||
}
|
||||
do_execsql_test 24.3 {
|
||||
SELECT * FROM t12('aaaa');
|
||||
} {aaaa}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 25.0 {
|
||||
CREATE VIRTUAL TABLE t13 USING fts5(x, detail=%DETAIL%);
|
||||
}
|
||||
do_execsql_test 25.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t13 VALUES('AAAA');
|
||||
SELECT * FROM t13('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*');
|
||||
|
||||
END;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
expand_all_sql db
|
||||
|
||||
@@ -165,7 +165,7 @@ do_execsql_test 4.0 {
|
||||
}
|
||||
|
||||
do_execsql_test 5.0 {
|
||||
CREATE VIRTUAL TABLE p1 USING fts5(a, b, detail=%DETAIL%);
|
||||
CREATE VIRTUAL TABLE p1 USING fts5(a, b);
|
||||
INSERT INTO p1 VALUES(
|
||||
'x a a a a a a a a a a',
|
||||
'a a a a a a a a a a a a a a a a a a a x'
|
||||
@@ -184,12 +184,6 @@ do_execsql_test 5.3 {
|
||||
do_execsql_test 5.4 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x');
|
||||
} {{[x a a a a a...}}
|
||||
do_execsql_test 5.5 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x OR ""');
|
||||
} {{[x a a a a a...}}
|
||||
do_execsql_test 5.6 {
|
||||
SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x OR ' || x'DB');
|
||||
} {{[x a a a a a...}}
|
||||
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
# TESTRUNNER: slow
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5ah
|
||||
|
||||
@@ -51,12 +51,6 @@ do_execsql_test 1.1 {
|
||||
do_execsql_test 1.2 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
SAVEPOINT one;
|
||||
INSERT INTO t1 VALUES('v w x');
|
||||
ROLLBACK TO one;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -144,14 +144,6 @@ do_execsql_test 3.1 {
|
||||
{[a b c d e]}
|
||||
}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
SELECT highlight(ft, 0, NULL, NULL) FROM ft WHERE ft MATCH 'a+b+c AND c+d+e';
|
||||
} {
|
||||
{a b c x c d e}
|
||||
{a b c c d e}
|
||||
{a b c d e}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -275,37 +275,6 @@ do_execsql_test 9.3 {
|
||||
9 10
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that aux. functions may not be used in aggregate queries.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 10.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y, z);
|
||||
INSERT INTO t1 VALUES('a', 'one two', 1);
|
||||
INSERT INTO t1 VALUES('b', 'two three', 2);
|
||||
INSERT INTO t1 VALUES('c', 'three four', 1);
|
||||
INSERT INTO t1 VALUES('d', 'four five', 2);
|
||||
INSERT INTO t1 VALUES('e', 'five six', 1);
|
||||
INSERT INTO t1 VALUES('f', 'six seven', 2);
|
||||
}
|
||||
|
||||
proc firstcol {cmd} { $cmd xColumnText 0 }
|
||||
sqlite3_fts5_create_function db firstcol firstcol
|
||||
|
||||
do_execsql_test 10.1.1 {
|
||||
SELECT firstcol(t1) FROM t1
|
||||
} {a b c d e f}
|
||||
do_execsql_test 10.1.2 {
|
||||
SELECT group_concat(x, '.') FROM t1
|
||||
} {a.b.c.d.e.f}
|
||||
|
||||
do_catchsql_test 10.1.3 {
|
||||
SELECT group_concat(firstcol(t1), '.') FROM t1
|
||||
} {1 {unable to use function firstcol in the requested context}}
|
||||
|
||||
do_catchsql_test 10.1.4 {
|
||||
SELECT group_concat(firstcol(t1), '.') FROM t1 GROUP BY rowid
|
||||
} {1 {unable to use function firstcol in the requested context}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# 2016 Jan 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
ifcapable !fts5 { finish_test ; return }
|
||||
set ::testprefix fts5cat
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize="unicode61 categories 'L*'");
|
||||
INSERT INTO t1 VALUES ('Unlike1option2values3and4column5names');
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT rowid FROM t1('option');
|
||||
} {1}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(x);
|
||||
CREATE VIRTUAL TABLE t2t USING fts5vocab(t2, row);
|
||||
|
||||
CREATE VIRTUAL TABLE t3 USING fts5(
|
||||
x, tokenize="unicode61 categories 'L* N* Co Mn'"
|
||||
);
|
||||
CREATE VIRTUAL TABLE t3t USING fts5vocab(t3, row);
|
||||
|
||||
CREATE VIRTUAL TABLE t4 USING fts5(
|
||||
x, tokenize="unicode61 categories 'L* N* Co M*'"
|
||||
);
|
||||
CREATE VIRTUAL TABLE t4t USING fts5vocab(t4, row);
|
||||
|
||||
INSERT INTO t2 VALUES ('สนามกีฬา');
|
||||
INSERT INTO t3 VALUES ('สนามกีฬา');
|
||||
INSERT INTO t4 VALUES ('สนามกีฬา');
|
||||
}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
SELECT * FROM t2t
|
||||
} {สนามก 1 1 ฬา 1 1}
|
||||
|
||||
do_execsql_test 1.4 {
|
||||
SELECT * FROM t3t
|
||||
} {สนามกีฬา 1 1}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
SELECT * FROM t4t
|
||||
} {สนามกีฬา 1 1}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -1,80 +0,0 @@
|
||||
# 2018 Dec 22
|
||||
#
|
||||
# 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 fts5circref
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE tt USING fts5(a);
|
||||
SELECT name FROM sqlite_master ORDER BY 1;
|
||||
} {
|
||||
tt tt_config tt_content tt_data tt_docsize tt_idx
|
||||
}
|
||||
db_save_and_close
|
||||
|
||||
foreach {tn schema sql} {
|
||||
1 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON tt_config BEGIN
|
||||
SELECT * FROM tt;
|
||||
END;
|
||||
} {
|
||||
INSERT INTO tt(tt, rank) VALUES('usermerge', 4);
|
||||
}
|
||||
|
||||
2 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON tt_docsize BEGIN
|
||||
SELECT * FROM tt;
|
||||
END;
|
||||
} {
|
||||
INSERT INTO tt(a) VALUES('one two three');
|
||||
}
|
||||
|
||||
3 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON tt_content BEGIN
|
||||
SELECT * FROM tt;
|
||||
END;
|
||||
} {
|
||||
INSERT INTO tt(a) VALUES('one two three');
|
||||
}
|
||||
|
||||
4 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON tt_data BEGIN
|
||||
SELECT * FROM tt;
|
||||
END;
|
||||
} {
|
||||
INSERT INTO tt(a) VALUES('one two three');
|
||||
}
|
||||
|
||||
5 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON tt_idx BEGIN
|
||||
SELECT * FROM tt;
|
||||
END;
|
||||
} {
|
||||
INSERT INTO tt(a) VALUES('one two three');
|
||||
}
|
||||
} {
|
||||
db_restore_and_reopen
|
||||
do_execsql_test 1.1.$tn.1 $schema
|
||||
do_catchsql_test 1.1.$tn.2 $sql {1 {SQL logic error}}
|
||||
db close
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -82,24 +82,5 @@ foreach_detail_mode $::testprefix {
|
||||
} {1 {unable to use function MATCH in the requested context}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Confirm that the expression parser creates the same expression tree
|
||||
# for:
|
||||
#
|
||||
# {a b} : (abc AND def)
|
||||
# -{c d} : (abc AND def)
|
||||
#
|
||||
# Assuming that the table columns are (a, b, c, d).
|
||||
#
|
||||
do_execsql_test 5.1 {
|
||||
SELECT fts5_expr('abcd AND cdef');
|
||||
} {{"abcd" AND "cdef"}}
|
||||
do_execsql_test 5.2 {
|
||||
SELECT fts5_expr('{a b} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
|
||||
} {{{a b} : "abcd" AND {a b} : "cdef"}}
|
||||
do_execsql_test 5.3 {
|
||||
SELECT fts5_expr('-{c d} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
|
||||
} {{{a b} : "abcd" AND {a b} : "cdef"}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -244,3 +244,4 @@ foreach {tn sql res} {
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -253,45 +253,5 @@ do_execsql_test 6.2 {
|
||||
SELECT name FROM sqlite_master;
|
||||
} {}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Check that an fts5 table cannot be its own content table.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 7.1.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, c=t1 );
|
||||
INSERT INTO t1( a ) VALUES('abc');
|
||||
}
|
||||
do_catchsql_test 7.1.2 {
|
||||
SELECT * FROM t1;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.1.3 {
|
||||
SELECT * FROM t1('abc');
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.1.4 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.1.5 {
|
||||
SELECT * FROM t1('abc') ORDER BY rank;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 7.2.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, c=t2 );
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(a, c=t1 );
|
||||
INSERT INTO t1( a ) VALUES('abc');
|
||||
}
|
||||
do_catchsql_test 7.2.2 {
|
||||
SELECT * FROM t1;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.2.3 {
|
||||
SELECT * FROM t1('abc');
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.2.4 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
do_catchsql_test 7.2.5 {
|
||||
SELECT * FROM t1('abc') ORDER BY rank;
|
||||
} {1 {recursively defined fts5 content table}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ db_save
|
||||
do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
set segid [lindex [fts5_level_segids t1] 0]
|
||||
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_test 1.3 {
|
||||
execsql {
|
||||
DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
|
||||
@@ -51,7 +50,6 @@ do_test 1.3 {
|
||||
|
||||
do_test 1.4 {
|
||||
db_restore_and_reopen
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
execsql {
|
||||
UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
|
||||
rowid = fts5_rowid('segment', $segid, 4);
|
||||
@@ -91,7 +89,7 @@ do_execsql_test 3.0 {
|
||||
do_execsql_test 3.1 {
|
||||
SELECT * FROM t3 WHERE t3 MATCH 'o'
|
||||
} {{one o} {three o} {five o}}
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
|
||||
do_catchsql_test 3.1 {
|
||||
DELETE FROM t3_content WHERE rowid = 3;
|
||||
SELECT * FROM t3 WHERE t3 MATCH 'o';
|
||||
|
||||
@@ -99,7 +99,6 @@ foreach {tno stmt} {
|
||||
set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}]
|
||||
set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}]
|
||||
set all [db eval {SELECT rowid FROM t1}]
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
|
||||
do_execsql_test 2.$i.1 {
|
||||
BEGIN;
|
||||
@@ -249,7 +248,6 @@ foreach {tn hdr} {
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
reset_db
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_execsql_test 6.1 {
|
||||
CREATE VIRTUAL TABLE x5 USING fts5(tt);
|
||||
INSERT INTO x5 VALUES('a');
|
||||
|
||||
+4
-15118
File diff suppressed because one or more lines are too long
@@ -1,63 +0,0 @@
|
||||
# 2019 May 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5corrupt4
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
sqlite3_fts5_may_be_corrupt 1
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE ttt USING fts5(a, b);
|
||||
INSERT INTO ttt
|
||||
VALUES('e ee eee e ee eee e ee eee', 'eee ee e e e ee eee ee ee');
|
||||
INSERT INTO ttt SELECT a||a, b||b FROM ttt;
|
||||
INSERT INTO ttt SELECT a||a, b||b FROM ttt;
|
||||
}
|
||||
|
||||
expr srand(1)
|
||||
|
||||
proc mutate {blob i} {
|
||||
set o [expr {$i % [string length $blob]}]
|
||||
set a [string range $blob 0 $o-1]
|
||||
set b [string range $blob $o+1 end]
|
||||
set v [expr int(rand()*255) - 127]
|
||||
return "$a[binary format c $v]$b"
|
||||
}
|
||||
db func mutate mutate
|
||||
|
||||
for {set j 1000} {$j <= 5000} {incr j 1000} {
|
||||
do_test 1.$j {
|
||||
for {set i 0} {$i < 1000} {incr i} {
|
||||
execsql {
|
||||
BEGIN;
|
||||
UPDATE ttt_data SET block = mutate(block, $i) WHERE id>10;
|
||||
}
|
||||
foreach sql {
|
||||
{SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e*')}
|
||||
{SELECT snippet(ttt, -1, '.', '..', '[', ']'), * FROM ttt('e* NOT ee*')}
|
||||
} {
|
||||
catch { execsql $sql }
|
||||
}
|
||||
execsql ROLLBACK
|
||||
}
|
||||
} {}
|
||||
}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -1,798 +0,0 @@
|
||||
# 2015 Apr 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file tests that FTS5 handles corrupt databases (i.e. internal
|
||||
# inconsistencies in the backing tables) correctly. In this case
|
||||
# "correctly" means without crashing.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5corrupt3
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
sqlite3_fts5_may_be_corrupt 1
|
||||
database_may_be_corrupt
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# dbsqlfuzz crash-0f47112aa7520cf08c6a835a88fdff8c2a32a188
|
||||
#
|
||||
reset_db
|
||||
do_test 1.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 24576 pagesize 4096 filename crash-0f47112aa7520c.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
|
||||
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
|
||||
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
|
||||
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
|
||||
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
|
||||
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
|
||||
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
|
||||
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
|
||||
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
|
||||
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
|
||||
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
|
||||
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
|
||||
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
|
||||
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
|
||||
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
|
||||
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
|
||||
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
|
||||
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
|
||||
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
|
||||
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
|
||||
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
|
||||
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
|
||||
| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
|
||||
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
|
||||
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
|
||||
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
|
||||
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
|
||||
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
|
||||
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
|
||||
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
|
||||
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
|
||||
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
|
||||
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
|
||||
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
|
||||
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
|
||||
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
|
||||
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
|
||||
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00 ...~.H..........
|
||||
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
|
||||
| 2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12 0......5........
|
||||
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
|
||||
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
|
||||
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
|
||||
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
|
||||
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
|
||||
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
|
||||
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
|
||||
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
|
||||
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
|
||||
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
|
||||
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
|
||||
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
|
||||
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
|
||||
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
|
||||
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
|
||||
| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
|
||||
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
|
||||
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
|
||||
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
|
||||
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
|
||||
| 2720: 01 02 05 01 00 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
|
||||
| 2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03 ......6......1f.
|
||||
| 2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80 ....i...........
|
||||
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
|
||||
| 2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
|
||||
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
|
||||
| 2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80 .0table.B.......
|
||||
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
|
||||
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
|
||||
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
|
||||
| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
|
||||
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
|
||||
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
|
||||
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
|
||||
| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
|
||||
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
|
||||
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
|
||||
| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
|
||||
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
|
||||
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
|
||||
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
|
||||
| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
|
||||
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
|
||||
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32 .........<.....2
|
||||
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
|
||||
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
|
||||
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
|
||||
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
|
||||
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
|
||||
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 9e 00 ............<...
|
||||
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
|
||||
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
|
||||
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
|
||||
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
|
||||
| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
|
||||
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
|
||||
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
|
||||
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
|
||||
| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11.
|
||||
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
|
||||
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
|
||||
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
|
||||
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
|
||||
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
|
||||
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
|
||||
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
|
||||
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
|
||||
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
|
||||
| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
|
||||
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
|
||||
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
|
||||
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
|
||||
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
|
||||
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
|
||||
| 3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03 res.............
|
||||
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
|
||||
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
|
||||
| 3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01 ..<.....3.re....
|
||||
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
|
||||
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
|
||||
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
|
||||
| 3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06 .....<.....2th..
|
||||
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
|
||||
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
|
||||
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
|
||||
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
|
||||
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
|
||||
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
|
||||
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
|
||||
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
|
||||
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
|
||||
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
|
||||
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
|
||||
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
|
||||
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
|
||||
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
|
||||
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
|
||||
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62 ............0dab
|
||||
| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
|
||||
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
|
||||
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
|
||||
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
|
||||
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
|
||||
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66 .....0each.....f
|
||||
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
|
||||
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
|
||||
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
|
||||
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
|
||||
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
|
||||
| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
|
||||
| 80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
|
||||
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
|
||||
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
|
||||
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
|
||||
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
|
||||
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
|
||||
| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
|
||||
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
|
||||
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
|
||||
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
|
||||
| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
|
||||
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
|
||||
| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
|
||||
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
|
||||
| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
|
||||
| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
|
||||
| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
|
||||
| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
|
||||
| 3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
|
||||
| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
|
||||
| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
|
||||
| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
|
||||
| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
|
||||
| 4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66 ..d...2i......2f
|
||||
| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
|
||||
| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
|
||||
| 4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
|
||||
| 4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| page 4 offset 12288
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
|
||||
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
|
||||
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
|
||||
| page 6 offset 20480
|
||||
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00 ................
|
||||
| end crash-0f47112aa7520c.db
|
||||
}]
|
||||
} {}
|
||||
|
||||
do_catchsql_test 1.1 {
|
||||
SELECT * FROM t1('R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_test 2.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
|
||||
.open --hexdb
|
||||
| size 24576 pagesize 4096 filename sql047467.txt.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
|
||||
| 112: 0e e8 0e 8b 0e 33 0e 0f 01 00 00 00 00 00 00 00 .....3..........
|
||||
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
|
||||
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
|
||||
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
|
||||
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
|
||||
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
|
||||
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
|
||||
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
|
||||
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
|
||||
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
|
||||
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
|
||||
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
|
||||
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
|
||||
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
|
||||
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
|
||||
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
|
||||
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
|
||||
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
|
||||
| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM
|
||||
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
|
||||
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
|
||||
| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl
|
||||
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
|
||||
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
|
||||
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
|
||||
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
|
||||
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
|
||||
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
|
||||
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
|
||||
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
|
||||
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
|
||||
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
|
||||
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
|
||||
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
|
||||
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
|
||||
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
|
||||
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00 ...~.H..........
|
||||
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
|
||||
| 2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12 0......5........
|
||||
| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>...
|
||||
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
|
||||
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
|
||||
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
|
||||
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
|
||||
| 2480: 00 3b ff f0 00 16 04 33 74 68 65 03 06 01 01 04 .;.....3the.....
|
||||
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
|
||||
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
|
||||
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
|
||||
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
|
||||
| 2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts.........
|
||||
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
|
||||
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
|
||||
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
|
||||
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
|
||||
| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
|
||||
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
|
||||
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
|
||||
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
|
||||
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
|
||||
| 2720: 01 02 05 01 00 6f 03 06 01 01 06 14 09 18 8c 80 .....o..........
|
||||
| 2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03 ......6......1f.
|
||||
| 2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80 ....i...........
|
||||
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
|
||||
| 2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
|
||||
| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0.......
|
||||
| 2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80 .0table.B.......
|
||||
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
|
||||
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
|
||||
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........
|
||||
| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n..............
|
||||
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
|
||||
| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*.
|
||||
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
|
||||
| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................
|
||||
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
|
||||
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
|
||||
| 2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01 .........0......
|
||||
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
|
||||
| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
|
||||
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
|
||||
| 3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04 .......<........
|
||||
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
|
||||
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32 .........<.....2
|
||||
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
|
||||
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
|
||||
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
|
||||
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
|
||||
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
|
||||
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 94 50 ............<..P
|
||||
| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
|
||||
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
|
||||
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
|
||||
| 3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00 ..............4.
|
||||
| 3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
|
||||
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
|
||||
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
|
||||
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
|
||||
| 3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02 ..0there.....11.
|
||||
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
|
||||
| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07 .......0the.....
|
||||
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
|
||||
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
|
||||
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
|
||||
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
|
||||
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
|
||||
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
|
||||
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
|
||||
| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
|
||||
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
|
||||
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
|
||||
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
|
||||
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
|
||||
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p
|
||||
| 3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03 res.............
|
||||
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
|
||||
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
|
||||
| 3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01 ..<.....3.re....
|
||||
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
|
||||
| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for..
|
||||
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
|
||||
| 3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06 .....<.....2th..
|
||||
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
|
||||
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
|
||||
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
|
||||
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01 ......8.....2in.
|
||||
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
|
||||
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
|
||||
| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
|
||||
| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
|
||||
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
|
||||
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
|
||||
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
|
||||
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
|
||||
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
|
||||
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
|
||||
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
|
||||
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62 ............0dab
|
||||
| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le..............
|
||||
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
|
||||
| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<..
|
||||
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
|
||||
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
|
||||
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66 .....0each.....f
|
||||
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
|
||||
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
|
||||
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
|
||||
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
|
||||
| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&....
|
||||
| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd ................
|
||||
| 80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
|
||||
| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
|
||||
| 3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
|
||||
| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w.....
|
||||
| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
|
||||
| 3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
|
||||
| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
|
||||
| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
|
||||
| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
|
||||
| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
|
||||
| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
|
||||
| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
|
||||
| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
|
||||
| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
|
||||
| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n..
|
||||
| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
|
||||
| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
|
||||
| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
|
||||
| 3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
|
||||
| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
|
||||
| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
|
||||
| 3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
|
||||
| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
|
||||
| 4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66 ..d...2i......2f
|
||||
| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
|
||||
| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
|
||||
| 4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
|
||||
| 4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| page 4 offset 12288
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
|
||||
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
|
||||
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
|
||||
| page 6 offset 20480
|
||||
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00 ................
|
||||
| end sql047467.txt.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 2.1 {
|
||||
SELECT * FROM t1('R*R*R*R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 3.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 32768 pagesize 4096 filename crash-c69fcaceff1e50.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
|
||||
| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................
|
||||
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
|
||||
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............
|
||||
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
|
||||
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
|
||||
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
|
||||
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
|
||||
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
|
||||
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
|
||||
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
|
||||
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
|
||||
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
|
||||
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
|
||||
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
|
||||
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
|
||||
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
|
||||
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
|
||||
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
|
||||
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
|
||||
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
|
||||
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
|
||||
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i....
|
||||
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
|
||||
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
|
||||
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
|
||||
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
|
||||
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
|
||||
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
|
||||
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
|
||||
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
|
||||
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
|
||||
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
|
||||
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
|
||||
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
|
||||
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
|
||||
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
|
||||
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
|
||||
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
|
||||
| page 3 offset 8192
|
||||
| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................
|
||||
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
|
||||
| 3232: 00 00 01 bb 02 30 30 01 02 06 01 02 06 01 02 06 .....00.........
|
||||
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160
|
||||
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4.
|
||||
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5.....
|
||||
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000...
|
||||
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
|
||||
| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
|
||||
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
|
||||
| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat...........
|
||||
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e
|
||||
| 3440: 6b b1 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 k.ble...........
|
||||
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 3472: 01 02 02 01 02 02 05 02 02 01 02 02 01 02 02 01 ................
|
||||
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
|
||||
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 1a 02 03 .........fts4...
|
||||
| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5.......
|
||||
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
|
||||
| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........
|
||||
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
|
||||
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
|
||||
| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
|
||||
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
|
||||
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
|
||||
| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase...........
|
||||
| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 01 ...omit.........
|
||||
| 3744: ff ff ff ff ff ff ff ff ff ff ff ff ff ff f1 02 ................
|
||||
| 3760: 58 81 96 4d 01 06 01 02 02 03 06 01 02 02 03 06 X..M............
|
||||
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
|
||||
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
|
||||
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
|
||||
| 3872: 02 01 06 01 c6 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3904: 06 01 01 02 00 f6 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
|
||||
| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G..........
|
||||
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 4 offset 12288
|
||||
| 0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
|
||||
| page 7 offset 24576
|
||||
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
|
||||
| end crash-c69fcaceff1e50.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 3.1 {
|
||||
UPDATE t1 SET b=quote(zeroblob(200)) WHERE a MATCH 'thra*T';
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 4.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 24576 pagesize 4096 filename crash-ef6738247b1344.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 10 00 06 40 00 00 06 .....@ ....@...
|
||||
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 ................
|
||||
| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S
|
||||
| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3..........
|
||||
| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................
|
||||
| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb
|
||||
| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb
|
||||
| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table
|
||||
| 3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66 t1_configt1_conf
|
||||
| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE
|
||||
| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR
|
||||
| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI
|
||||
| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...!
|
||||
| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73 !...tablet1_docs
|
||||
| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR
|
||||
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d
|
||||
| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG
|
||||
| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i.......
|
||||
| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i
|
||||
| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE
|
||||
| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid,
|
||||
| 3872: 74 65 72 6d 2c 20 6f 67 6e 6f 2c 20 50 52 49 4d term, ogno, PRIM
|
||||
| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t
|
||||
| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO
|
||||
| 3920: 57 49 44 55 35 07 17 1b 1b 01 81 01 74 61 62 6c WIDU5.......tabl
|
||||
| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data.
|
||||
| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
|
||||
| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE
|
||||
| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b
|
||||
| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T.....
|
||||
| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA
|
||||
| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE
|
||||
| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a
|
||||
| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33 ,b,prefix=.1,2,3
|
||||
| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L....
|
||||
| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad ...m.K.,........
|
||||
| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........
|
||||
| 48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5 ...v.T.1........
|
||||
| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........
|
||||
| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a 00 ...~.H..........
|
||||
| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................
|
||||
| 2384: 30 00 00 00 01 01 03 35 00 03 01 01 12 02 01 12 0......5........
|
||||
| 2400: 03 01 11 1c 8c 80 80 80 80 10 02 9c 3e 00 00 00 ............>...
|
||||
| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh
|
||||
| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............<
|
||||
| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n
|
||||
| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb.............
|
||||
| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the.....
|
||||
| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe...........
|
||||
| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num...
|
||||
| 2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80 ....tab.........
|
||||
| 2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02 .....8.....2wh..
|
||||
| 2560: 04 00 04 33 66 74 73 03 12 02 04 07 18 8c 80 80 ...3fts.........
|
||||
| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta..
|
||||
| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............
|
||||
| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu...
|
||||
| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of..........
|
||||
| 2640: 82 d0 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft.
|
||||
| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is..........
|
||||
| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t..
|
||||
| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w.........
|
||||
| 2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01 .....:.....1n...
|
||||
| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o..........
|
||||
| 2736: 81 80 80 06 03 00 36 00 00 00 13 04 12 31 66 03 ......6......1f.
|
||||
| 2752: 02 02 01 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i...........
|
||||
| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the.
|
||||
| 2784: 06 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15 ......where.....
|
||||
| 2800: 8c 80 65 80 80 04 03 00 30 00 00 00 11 01 01 06 ..e.....0.......
|
||||
| 2816: 06 30 74 61 62 6c 65 03 02 03 07 1c 8c 80 80 80 .0table.........
|
||||
| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe
|
||||
| 2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c r.......of......
|
||||
| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f fc 01 03 02 .......,........
|
||||
| 2880: 30 6e 03 06 01 00 f2 07 1b 8c 80 80 80 80 01 03 0n..............
|
||||
| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux.
|
||||
| 2912: 03 02 01 02 69 73 03 06 04 0c 00 00 00 18 ea 00 ....is..........
|
||||
| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$..........
|
||||
| 2944: 80 80 80 80 12 03 00 12 10 00 00 05 02 1c 88 80 ................
|
||||
| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row
|
||||
| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther....
|
||||
| 2992: 15 88 80 80 80 80 10 03 00 2f ff ff f0 11 02 01 ........./......
|
||||
| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........
|
||||
| 3024: 80 80 0f cf 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row
|
||||
| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the......
|
||||
| 3056: 80 80 80 80 0d 03 00 3c 00 00 00 16 00 01 02 04 .......<........
|
||||
| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet....
|
||||
| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2
|
||||
| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and..
|
||||
| 3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<....
|
||||
| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro...
|
||||
| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6..
|
||||
| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be..
|
||||
| 3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 00 00 ............<...
|
||||
| 3200: 16 12 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an.
|
||||
| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8.
|
||||
| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r..
|
||||
| 3248: 01 01 05 04 08 17 78 80 80 80 80 08 03 00 34 10 ......x.......4.
|
||||
| 3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i....
|
||||
| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8...
|
||||
| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a.....
|
||||
| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<...
|
||||
| 3328: 16 06 30 74 68 65 72 65 e7 02 02 00 02 31 31 02 ..0there.....11.
|
||||
| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0.
|
||||
| 3360: 00 00 11 01 01 05 e5 30 74 68 65 02 06 01 01 07 .......0the.....
|
||||
| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>.....
|
||||
| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows
|
||||
| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<..
|
||||
| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between.....
|
||||
| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............:
|
||||
| 3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and.......
|
||||
| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re..............
|
||||
| 3488: 34 01 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2
|
||||
| 3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00 ................
|
||||
| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<..
|
||||
| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e
|
||||
| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............<
|
||||
| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 02 01 04 70 .....4each.....p
|
||||
| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res.............
|
||||
| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter.....
|
||||
| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he..............
|
||||
| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre....
|
||||
| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............
|
||||
| 3664: 80 0d 03 0d 1a 00 00 00 15 04 33 66 6e 72 01 02 ..........3fnr..
|
||||
| 3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80 ...ts...........
|
||||
| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th..
|
||||
| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac.......
|
||||
| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta
|
||||
| 3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80 .......e........
|
||||
| 3760: 80 80 80 0a 03 00 38 00 00 00 14 03 30 c9 6e 01 ......8.....0.n.
|
||||
| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........
|
||||
| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo.
|
||||
| 3808: 02 0b e2 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t...........
|
||||
| 3824: 86 f0 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t...
|
||||
| 3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea.......
|
||||
| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i.
|
||||
| 3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80 ......p.........
|
||||
| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e...
|
||||
| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f.............
|
||||
| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term.
|
||||
| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he..........
|
||||
| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab
|
||||
| 3968: 6c 65 01 06 01 01 05 04 15 84 7f 80 80 80 03 03 le..............
|
||||
| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present
|
||||
| 4000: 01 02 05 05 1b 84 80 22 80 80 02 03 00 3c 00 00 .............<..
|
||||
| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in
|
||||
| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............:
|
||||
| 4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 03 66 .....0each.....f
|
||||
| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or..............
|
||||
| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O.........
|
||||
| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0 ................
|
||||
| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._
|
||||
| 48: 0f 56 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 .V..............
|
||||
| 3392: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................
|
||||
| 3408: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4.
|
||||
| 3424: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03 ......3th.......
|
||||
| 3440: 34 6e 1a 08 04 01 10 01 03 32 67 18 08 04 01 10 4n.......2g.....
|
||||
| 3456: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n...
|
||||
| 3472: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08 ....2.......1t..
|
||||
| 3488: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c .....1n.......1.
|
||||
| 3504: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th.......
|
||||
| 3520: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu....
|
||||
| 3536: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01 ...0n...........
|
||||
| 3552: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 ..
|
||||
| 3568: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar
|
||||
| 3584: 1c 18 04 01 10 01 02 32 74 1a 08 04 01 10 01 02 .......2t.......
|
||||
| 3600: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar....
|
||||
| 3616: 10 01 02 31 74 2a 08 04 01 0f 01 02 31 6e 12 0a ...1t*......1n..
|
||||
| 3632: d4 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12
|
||||
| 3648: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther....
|
||||
| 3664: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n..
|
||||
| 3680: 04 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61 .....0b.......0a
|
||||
| 3696: 04 06 03 f1 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t.
|
||||
| 3712: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te.
|
||||
| 3728: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a .....3p......3f.
|
||||
| 3744: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74 .....2th......2t
|
||||
| 3760: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f
|
||||
| 3776: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i
|
||||
| 3792: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te
|
||||
| 3808: 0a 07 04 09 10 01 30 74 08 07 04 09 10 01 30 70 ......0t......0p
|
||||
| 3824: 06 08 04 09 1e 61 30 66 74 04 05 00 00 00 00 00 .....a0ft.......
|
||||
| page 4 offset 12288
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
|
||||
| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p
|
||||
| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version.
|
||||
| end crash-ef6738247b1344.db
|
||||
}]} {}
|
||||
|
||||
|
||||
do_catchsql_test 4.1 {
|
||||
BEGIN;
|
||||
REPLACE INTO t1(rowid,b,a,rowid) VALUES(200,1,2,3);
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 4.2 {
|
||||
INSERT INTO t1(t1) VALUES('delete-all');
|
||||
} {1 {database disk image is malformed}}
|
||||
do_catchsql_test 4.3 {
|
||||
REPLACE INTO t1(rowid,b,rowid,a) VALUES(200,1,2,3);
|
||||
} {1 {database disk image is malformed}}
|
||||
do_catchsql_test 4.4 {
|
||||
REPLACE INTO t1(rowid,b,a,rowid) VALUES(0,1,2,3);
|
||||
} {1 {database disk image is malformed}}
|
||||
do_catchsql_test 4.5 {
|
||||
REPLACE INTO t1(rowid,a,b,rowid) VALUES(200,1,2,3);
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# 2015 Apr 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file tests that FTS5 handles corrupt databases (i.e. internal
|
||||
# inconsistencies in the backing tables) correctly. In this case
|
||||
# "correctly" means without crashing.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5corrupt6
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
sqlite3_fts5_may_be_corrupt 1
|
||||
database_may_be_corrupt
|
||||
|
||||
proc editblock {block} {
|
||||
binary format Sa* 20000 [string range $block 2 end]
|
||||
}
|
||||
db func editblock editblock
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(abc, def);
|
||||
WITH a(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM a WHERE i<1000
|
||||
)
|
||||
INSERT INTO ft SELECT
|
||||
'abc abc abc abc abc abc abc abc abc abc',
|
||||
'def def def def def def def def def def'
|
||||
FROM a;
|
||||
UPDATE ft_data SET block = editblock(block) WHERE id=(
|
||||
SELECT id FROM ft_data ORDER BY id LIMIT 1 OFFSET 5
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.1 {
|
||||
SELECT rowid FROM ft('def') ORDER BY rowid DESC LIMIT 1 OFFSET 9999;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -50,68 +50,4 @@ do_test 1.2 {
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE test (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT,
|
||||
value TEXT
|
||||
);
|
||||
CREATE VIRTUAL TABLE test_idx USING fts5(
|
||||
name, content=test, content_rowid=id
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 2.1 {
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 1, 'quick');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 2.2 {
|
||||
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 2.3 {
|
||||
DROP TABLE test_idx;
|
||||
CREATE VIRTUAL TABLE test_idx USING fts5(
|
||||
name, content=test, content_rowid=id
|
||||
);
|
||||
|
||||
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
|
||||
INSERT INTO test_idx(rowid, name) VALUES(124, 'two two two');
|
||||
INSERT INTO test_idx(rowid, name) VALUES(125, 'two two two');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
}
|
||||
|
||||
do_catchsql_test 2.4 {
|
||||
SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE tx USING fts5(a, b, c, d, content=);
|
||||
INSERT INTO tx(rowid, a, c) VALUES(1, 'abc def', 'a b c');
|
||||
INSERT INTO tx(rowid, a, c) VALUES(5, 'a b c', 'a b d def');
|
||||
}
|
||||
do_execsql_test 3.1 {
|
||||
INSERT INTO tx(tx, rowid, a, b, c, d)
|
||||
VALUES('delete', 5, 'a b c', NULL, 'a b d def', NULL);
|
||||
}
|
||||
do_execsql_test 3.2 {
|
||||
INSERT INTO tx(tx) VALUES('integrity-check');
|
||||
}
|
||||
do_execsql_test 3.3 {
|
||||
INSERT INTO tx(tx, rowid, a, b, c, d)
|
||||
VALUES('delete', 1, 'abc def', NULL, 'a b c', NULL);
|
||||
}
|
||||
do_execsql_test 3.4 {
|
||||
INSERT INTO tx(tx) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -212,10 +212,6 @@ do_catchsql_test 4.1 {
|
||||
SELECT * FROM t4('a:a')
|
||||
} {1 {fts5: column queries are not supported (detail=none)}}
|
||||
|
||||
do_catchsql_test 4.2 {
|
||||
SELECT * FROM t4('a:a &')
|
||||
} {1 {fts5: syntax error near "&"}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that for the same content detail=none uses less space than
|
||||
# detail=col, and that detail=col uses less space than detail=full
|
||||
|
||||
@@ -42,26 +42,5 @@ do_execsql_test 1.2 {
|
||||
INSERT INTO ccc(ccc) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.1 {
|
||||
CREATE VIRTUAL TABLE tx USING fts5(x);
|
||||
}
|
||||
|
||||
set doc [string repeat "abc " 5000]
|
||||
do_execsql_test 2.2 {
|
||||
BEGIN;
|
||||
INSERT INTO tx(rowid, x) VALUES(-9000000000000000000, $doc);
|
||||
INSERT INTO tx(rowid, x) VALUES(9000000000000000000, $doc);
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 2.3 {
|
||||
SELECT rowid FROM tx('abc');
|
||||
} {
|
||||
-9000000000000000000
|
||||
9000000000000000000
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -59,31 +59,14 @@ do_catchsql_test 2.1 {
|
||||
SELECT fts5_expr()
|
||||
} {1 {wrong number of arguments to function fts5_expr}}
|
||||
|
||||
do_catchsql_test 2.2 {
|
||||
do_catchsql_test 2.1 {
|
||||
SELECT fts5_expr_tcl()
|
||||
} {1 {wrong number of arguments to function fts5_expr_tcl}}
|
||||
|
||||
do_catchsql_test 2.3 {
|
||||
SELECT fts5_expr('')
|
||||
} {1 {fts5: syntax error near ""}}
|
||||
|
||||
do_catchsql_test 2.4 {
|
||||
SELECT fts5_expr(NULL)
|
||||
} {1 {fts5: syntax error near ""}}
|
||||
|
||||
do_catchsql_test 2.5 {
|
||||
SELECT fts5_expr(NULL, NULL)
|
||||
} {1 {parse error in ""}}
|
||||
|
||||
for {set i 0} {$i < 255} {incr i} {
|
||||
do_test 2.6.$i {
|
||||
lindex [catchsql {sELECT fts5_expr(NULL, char($i));}] 0
|
||||
} 1
|
||||
}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61');
|
||||
INSERT INTO e1 VALUES ('just a few words with a / inside');
|
||||
INSERT INTO e1 VALUES ("just a few words with a / inside");
|
||||
}
|
||||
do_execsql_test 3.1 {
|
||||
SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank;
|
||||
|
||||
@@ -16,16 +16,12 @@ source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5fault4
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
set ::TMPDBERROR [list 1 \
|
||||
{unable to open a temporary database file for storing temporary tables}
|
||||
]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# An OOM while dropping an fts5 table.
|
||||
#
|
||||
@@ -395,7 +391,7 @@ do_faultsim_test 14.1 -faults oom-t* -prep {
|
||||
} -body {
|
||||
db eval { ALTER TABLE "tbl one" RENAME TO "tbl two" }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} $::TMPDBERROR
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -147,27 +147,5 @@ do_faultsim_test 5.1 -faults oom* -body {
|
||||
faultsim_test_result {0 {1 4}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test OOM injection in a query with two MATCH expressions
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a);
|
||||
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 6.1 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 2 3 4}}
|
||||
}
|
||||
do_faultsim_test 6.2 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 2 3 4}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultD
|
||||
set testprefix fts5faultA
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# 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 fts5faultE
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql { CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram) }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram);
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 2 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
|
||||
SELECT count(*) FROM t1 WHERE x LIKE '%mnop%' AND t1 MATCH 'jkl';
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram, detail=none);
|
||||
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 3 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
SELECT count(*) FROM t1 WHERE x LIKE '%mnopqrs%' AND t1 MATCH 'abc'
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -93,3 +93,4 @@ do_catchsql_test 3.3 {
|
||||
SELECT * FROM x2('^a');
|
||||
} {1 {fts5: phrase queries are not supported (detail!=full)}}
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ do_test 1.1 {
|
||||
execsql { INSERT INTO x8 VALUES( rnddoc(5) ); }
|
||||
}
|
||||
} msg] $msg
|
||||
} {0 {}}
|
||||
} {1 {database or disk is full}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user