Compare commits

..

13 Commits

Author SHA1 Message Date
dan e2a3c7232b Update documentation in fts5.h.
FossilOrigin-Name: f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9
2024-11-26 20:16:34 +00:00
dan 032bcf72fb Fix compiler warnings caused by variable shadowing.
FossilOrigin-Name: 211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa
2024-11-20 20:39:18 +00:00
dan 67a3914e65 Merge latest trunk changes into this branch.
FossilOrigin-Name: edb842349320eda9550bdfcd5a327949c5512e02f4b993782587b2131a425746
2024-11-06 17:31:48 +00:00
dan 8acaa6d039 Add tests for xInstToken() and prefix queries with various fts5 configurations.
FossilOrigin-Name: 9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d
2024-11-06 16:20:16 +00:00
dan 090b8649be Allow an fts5 table or query to be configured to collect xInstToken data for any prefix terms as part of the first parse of the main index, if any.
FossilOrigin-Name: 46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152
2024-11-02 19:10:50 +00:00
dan 32b4979559 Merge latest trunk changes into this branch.
FossilOrigin-Name: 790c56d493c66a2136e24d349d169639809d70bfab6996975a403be568a267a5
2024-11-01 19:41:22 +00:00
dan cd9b951e6b Merge latest trunk changes into this branch.
FossilOrigin-Name: bce9a524de6dda87daa90395cd55713d2d3ccfc090e53a947548e434db5eef5e
2024-10-28 10:39:14 +00:00
dan b27a30c620 Merge latest trunk into this branch.
FossilOrigin-Name: 740a37c5d54b57befa86a6bb299ffa89ed4243d10db885a08ab5c63238460dad
2024-10-27 14:41:58 +00:00
dan d2a88e961a Rationalize code further. And add tests.
FossilOrigin-Name: 0ca002a4ab88f3e7ae1e6e518038157eaa20759f57888c2ed7e50cb92bd96348
2024-10-01 20:38:08 +00:00
dan 7d56669bc4 Rationalize some of the new code on this branch.
FossilOrigin-Name: 66f209ba40e7de49b304d7931ff38a4994038452aab08e9347286a234c6f7075
2024-09-28 20:45:11 +00:00
dan 2eff8f2252 Change the way tokendata indexes are collected for prefix queries.
FossilOrigin-Name: 204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff
2024-09-25 18:55:11 +00:00
dan acfd1e2ba8 Merge trunk changes into this branch.
FossilOrigin-Name: 9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7
2024-09-24 15:43:52 +00:00
dan e25a267e81 Fix the fts5 xInstToken() API for prefix queries that do not use prefix-indexes. This is experimental.
FossilOrigin-Name: 97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe
2024-09-14 20:30:14 +00:00
43 changed files with 1752 additions and 1853 deletions
+15 -25
View File
@@ -117,29 +117,13 @@ CC = @CC@
B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@
T.cc = $(CC)
#
# $(CFLAGS) is problematic because it is frequently overridden when
# invoking make, which loses things like -fPIC. So... we avoid using
# it directly and instead add a level of indirection. We combine
# $(CFLAGS) and $(CPPFLAGS) here because that's the way the legacy
# build did it and many builds rely on that. See main.mk for more
# details.
#
# Historical note: the pre-3.48 build only honored CPPFLAGS at
# configure-time, and expanded them into the generated Makefile. There
# are, in that build, no uses of CPPFLAGS in the configure-expanded
# Makefile. Ergo: if a client configures with CPPFLAGS=... and then
# explicitly passes CFLAGS=... to make, the CPPFLAGS will be
# lost. That behavior is retained in 3.48+ because also honoring
# CPPFLAGS at make-time may have undesired side effects on any number
# of builds.
# CFLAGS is problematic because it is frequently overridden when
# invoking make, which loses things like -fPIC. So... let's avoid
# using it directly and instead add a level of indirection. We
# combine CFLAGS and CPPFLAGS here because that's the way the legacy
# build did it.
#
CFLAGS = @CFLAGS@ @CPPFLAGS@
#
# $(LDFLAGS.configure) represents any LDFLAGS=... the client passes to
# configure. See main.mk.
#
LDFLAGS.configure = @LDFLAGS@
#
# CFLAGS.core is documented in main.mk.
#
@@ -164,9 +148,6 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@
# Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it
# can include the generated sqlite_cfg.h.
#
# main.mk will fill out T.cc.sqlite with additional flags common to
# all builds.
#
T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
#
# -I$(prefix)/include is primarily so that the ICU
@@ -174,6 +155,9 @@ T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
#
T.cc.sqlite += -I$(prefix)/include
#
# main.mk will fill out T.cc.sqlite with some flags common to all builds.
#
# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH)
# must start with a path component so that it can be invoked as a
@@ -247,6 +231,12 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@
#TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@
#TCL_VERSION = @TCL_VERSION@
#
# $(TCLLIB_RPATH) is calculated by the configure script. Its counterpart
# in tclConfig.sh (TCL_LD_SEARCH_FLAGS) is defined in such a way as to
# make it incompatible with static makefiles.
#
#TCLLIB_RPATH = @TCLLIB_RPATH@
#
# $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it
# is calculated at make-time by the targets which need it but we
# export it here so that it can be set at configure-time, so that
@@ -308,7 +298,7 @@ sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF)
@touch $@
install: install-pc # defined in main.mk
sqlite_cfg.h: $(AS_AUTO_DEF)
sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF)
$(AS_AUTORECONFIG)
@touch $@
+164 -228
View File
@@ -12,7 +12,7 @@
#
# JimTCL: https://jim.tcl.tk
#
use cc cc-db cc-shared cc-lib proj
use cc cc-db cc-shared cc-lib proj pkg-config
# $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended
# only for build debugging and not part of the public build interface.
@@ -73,7 +73,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json
# --disable-readline ==> boolean false
#
# Trying to pass --readline or --readline=1 or --readline=0 will
# result in an "unrecognized option" error, despite the the [options]
# result in an "unrecognized option" error, despite the the options
# call listing the flag as "readline".
#
# The behavior described above can lead lead to some confusion when
@@ -91,7 +91,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json
# --enable-FLAG
#
# Non-boolean flags, in contrast, use the names specifically given to
# them in the [options] invocation. e.g. "with-tcl" is the --with-tcl
# them in the 'options' invocation. e.g. "with-tcl" is the --with-tcl
# flag. Autosetup may, however, choose to automatically alter the help
# text, as demonstrated here:
#
@@ -130,7 +130,7 @@ set flags {
# </build-modes>
# <lib-feature>
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always}
largefile=1 => {Disable large file support}
load-extension=1 => {Disable loading of external extensions}
math=1 => {Disable math functions}
@@ -150,17 +150,18 @@ set flags {
# --with-tcl=DIR may be either a dir containing tclConfig.sh or a
# dir one level up from that from which we can derive a dir
# containing tclConfig.sh.
with-tcl: => {Root of path containing tclConfig.sh}
with-tcl:DIR => {Root of path containing tclConfig.sh}
# If --with-tclsh=X given, it is used for (A) trying to find
# tclConfig.sh and (B) all TCL-based code generation. Warning: if
# its containing dir has multiple tclsh versions, it may select the
# wrong tclConfig.sh!
with-tclsh:PATH => {Full pathname of tclsh to use}
# --disable-tcl disables building of components which require TCL,
# including tests. This tree requires TCL for code generation but
# can use the in-tree copy of autosetup/jimsh0.c for that. The
# SQLite TCL extension and the test code require a canonical tclsh.
tcl=1 => {Disable components which require TCL}
# --disable-tcl only disables building of the SQLite TCL extension,
# not the requirement for TCL. This tree requires TCL for code
# generation but can use the in-tree copy of autosetup/jimsh0.c for
# that. The SQLite TCL extension and, by extension, the test code
# require a canonical tclsh.
tcl=1 => {Disable components which require TCL-dev}
# <tcl>
# <line-editing>
readline=1 => {Disable readline support}
@@ -195,12 +196,6 @@ set flags {
gcov=0 => {Enable coverage testing using gcov}
linemacros => {Enable #line macros in the amalgamation}
dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)}
#soname:=none => {SONAME for libsqlite3.so}
#^^^ we "could", but arguably shouldn't, support clients passing a
# value of libsqlite3.so.0 for compatibility with clients which
# linked against a pre-3.48 build.
# Maybe we should support values of --soname=(none,auto,legacy), where auto means
# to use the 3.48+ value of libsqlite3.so.3..
# </developer>
}
if {"" ne $DUMP_DEFINES_JSON} {
@@ -257,12 +252,12 @@ if {1} {
set isCrossCompiling [proj-is-cross-compiling]
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app
define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app
########################################################################
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is
# -shell then it strips that arg and passes the remaining args the
# sqlite-add-shell-opt in addition to adding them to
# OPT_FEATURE_FLAGS.
# Adds $args, if not empty, to OPT_FEATURE_FLAGS.
# If the first arg is -shell then it strips that arg
# and passes the remaining args th sqlite-add-shell-opt
# in addition to adding them to OPT_FEATURE_FLAGS.
proc sqlite-add-feature-flag {args} {
set shell ""
if {"-shell" eq [lindex $args 0]} {
@@ -334,40 +329,23 @@ proc sqlite-check-wasi-sdk {} {
}
msg-result "Checking WASI SDK directory \[$wasiSdkDir]... "
#puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]"
proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld ar}]
proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}]
define HAVE_WASI_SDK 1
define WASI_SDK_DIR $wasiSdkDir
# Disable numerous options which we know either can't work or are
# not useful in this build...
msg-result "Using wasi-sdk clang. Disabling CLI shell modifying config flags:"
# Boolean flags which must be switched off:
msg-result "Using wasi-sdk clang. Disabling CLI shell and forcing:"
foreach opt {
editline
gcov
icu-collations
load-extension
readline
shared
tcl
threadsafe
} {
if {[opt-bool $opt]} {
msg-result " --disable-$opt"
proj-opt-set $opt 0
}
}
# Non-boolean flags which need to be cleared:
foreach opt {
with-emsdk
with-icu-config
with-icu-ldflags
with-linenoise
with-tcl
} {
if {[proj-opt-was-provided $opt]} {
msg-result " removing --$opt"
proj-opt-set $opt ""
}
msg-result " --disable-$opt"
proj-opt-set $opt 0
}
# Remember that we now have a discrepancy beteween
# $::isCrossCompiling and [proj-is-cross-compiling].
@@ -433,57 +411,28 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} {
}
proj-check-rpath ; # Determine proper rpath-handling flag
########################################################################
# It's not yet clear whether we gain anything from setting -soname,
# but not having it has been a source of anxiety for some users.
# Setting it to any value other than its historical value of
# libsqlite3.so.0 may (this is not certain) break dynamic linking of
# clients which initially linked against a legacy build.
#
# See discussion in/around:
# https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3
proc sqlite-check-soname {} {
if {0 && [proj-check-soname libsqlite3.so.3]} {
# It's not yet clear whether we gain anything from setting -soname
define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3
} else {
define LDFLAGS_SONAME_LIBSQLITE3 ""
if {[proj-opt-was-provided soname]} {
set soname [opt-val soname]
} else {
return 0
}
switch -exact -- $soname {
none { return 0 }
auto - 3 { set soname libsqlite3.so.3 }
legacy - 0 { set soname libsqlite3.so.0 }
default {
proj-fatal "Invalid value for --soname. Use one of (none, auto, legacy)."
}
}
msg-debug "soname=$soname"
if {[proj-check-soname $soname]} {
define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]$soname
msg-result "Setting SONAME: [get-define LDFLAGS_SONAME_LIBSQLITE3]"
} else {
proj-fatal "This environment does not support SONAME."
}
return sqlite-check-soname ""
}
sqlite-check-soname
proj-define-for-opt shared ENABLE_SHARED "Build shared library?"
proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?"
if {![proj-define-for-opt static ENABLE_STATIC \
if {![proj-define-if-opt-truthy static ENABLE_STATIC \
"Build static library?"]} {
proj-warn "Static lib build may be implicitly re-activated by other components, e.g. some test apps."
}
proj-define-for-opt amalgamation USE_AMALGAMATION "Use amalgamation for builds?"
proj-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?"
proj-define-for-opt gcov USE_GCOV "Use gcov?"
proj-define-if-opt-truthy gcov USE_GCOV "Use gcov?"
proj-define-for-opt test-status TSTRNNR_OPTS \
proj-define-if-opt-truthy test-status TSTRNNR_OPTS \
"test-runner flags:" {--status} {}
proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \
proj-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \
"Use #line macros in the amalgamation:"
msg-checking "SQLITE_DEBUG build? "
@@ -517,39 +466,31 @@ proj-if-opt-truthy with-debug {
#
# - TCLLIBDIR is the dir to which libtclsqlite3 gets installed.
#
# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3, which
# will usually differ from the rpath used by the rest of the lib.
#
# - BTCLSH = the path to the tcl interpreter used for in-tree code
# generation. It may be jimtcl or the canonical tclsh but may not
# be empty - this tree requires TCL to generated numerous
# components.
#
# If --tcl or --with-tcl are provided but no TCL is found, this
# function fails fatally. If they are not explicitly provided then
# failure to find TCL is not fatal but a loud warning will be emitted.
#
proc sqlite-check-tcl {} {
define TCLSH_CMD false ; # Significant is that it exits with non-0
define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search
define TCLLIBDIR "" ; # Installation dir for TCL extension lib
define TCLLIB_RPATH "" ; # rpath for TCL extension lib
define TCL_CONFIG_SH ""; # full path to tclConfig.sh
file delete -force ".tclenv.sh"; # ensure no stale state from previous configures.
if {![opt-bool tcl]} {
proj-indented-notice {
NOTE: TCL is disabled via --disable-tcl. This means that none
of the TCL-based components, including tests and sqlite3_analyzer,
will be built.
}
msg-result "TCL disabled via --disable-tcl. Will not be able to run tests."
return
}
# TODO: document the steps this is taking.
global srcdir
msg-result "Checking for a suitable tcl... "
proj-assert [proj-opt-truthy tcl]
proj-assert {proj-opt-truthy tcl}
set use_tcl 1
set with_tclsh [opt-val with-tclsh]
set with_tcl [opt-val with-tcl]
if {"prefix" eq $with_tcl} {
set with_tcl [get-define prefix]
}
msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}"
msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}"
msg-debug "sqlite-check-tcl: with_tcl=$with_tcl"
@@ -560,10 +501,9 @@ proc sqlite-check-tcl {} {
msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}"
}
set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases
if {"" ne $with_tclsh} {
# --with-tclsh was provided or found above. Validate it and use it
# to trump any value passed via --with-tcl=DIR.
# --with-tclsh was provided. Validate it and use it to trump any
# value passed via --with-tcl=DIR.
if {![file isfile $with_tclsh]} {
proj-fatal "TCL shell $with_tclsh is not a file"
} elseif {![file-isexec $with_tclsh]} {
@@ -572,23 +512,23 @@ proc sqlite-check-tcl {} {
define TCLSH_CMD $with_tclsh
#msg-result "Using tclsh: $with_tclsh"
}
if {$doConfigLookup &&
[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} {
if {[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} {
set with_tcl $result
}
if {"" ne $with_tcl && [file isdir $with_tcl]} {
msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl"
} else {
proj-warn "$with_tclsh is unable to recommend a tclConfig.sh"
proj-warn "$with_tclsh is unable to recommand a tclConfig.sh"
set use_tcl 0
}
}
set cfg ""
set tclSubdirs {tcl9.0 tcl8.6 lib}
while {$use_tcl} {
if {"" ne $with_tcl} {
# Ensure that we can find tclConfig.sh under ${with_tcl}/...
if {$doConfigLookup} {
while {1} {
if {$use_tcl} {
if {"" ne $with_tcl} {
# Ensure that we can find tclConfig.sh under ${with_tcl}/...
if {[file readable "${with_tcl}/tclConfig.sh"]} {
set cfg "${with_tcl}/tclConfig.sh"
} else {
@@ -599,43 +539,49 @@ proc sqlite-check-tcl {} {
}
}
}
}
if {"" eq $cfg} {
proj-fatal "No tclConfig.sh found under ${with_tcl}"
}
} else {
# If we have not yet found a tclConfig.sh file, look in
# $libdir which is set automatically by autosetup or by the
# --prefix command-line option. See
# https://sqlite.org/forum/forumpost/e04e693439a22457
set libdir [get-define libdir]
if {[file readable "${libdir}/tclConfig.sh"]} {
set cfg "${libdir}/tclConfig.sh"
if {"" eq $cfg} {
proj-fatal "No tclConfig.sh found under ${with_tcl}"
}
} else {
foreach i $tclSubdirs {
if {[file readable "${libdir}/$i/tclConfig.sh"]} {
set cfg "${libdir}/$i/tclConfig.sh"
break
# If we have not yet found a tclConfig.sh file, look in
# $libdir which is set automatically by autosetup or by the
# --prefix command-line option. See
# https://sqlite.org/forum/forumpost/e04e693439a22457
set libdir [get-define libdir]
if {[file readable "${libdir}/tclConfig.sh"]} {
set cfg "${libdir}/tclConfig.sh"
} else {
foreach i $tclSubdirs {
if {[file readable "${libdir}/$i/tclConfig.sh"]} {
set cfg "${libdir}/$i/tclConfig.sh"
break
}
}
}
if {![file readable $cfg]} {
proj-indented-notice {
WARNING: Cannot find a usable tclConfig.sh file. Use
--with-tcl=DIR to specify a directory where tclConfig.sh
can be found. SQLite does not use TCL internally, but TCL
is required for testing.
}
break
}
}
if {![file readable $cfg]} {
break
}
msg-result "Using tclConfig.sh: $cfg"
} else {
proj-warn "Unable to run tests because no tclConfig.sh file could be located"
}
msg-result "Using tclConfig.sh: $cfg"
break
}
define TCL_CONFIG_SH $cfg
# Export a subset of tclConfig.sh to the current TCL-space. If $cfg
# is an empty string, this emits empty-string entries for the
# Export a subset of tclConfig.sh to the current TCL-space. If the
# config is not available, this emits empty-string entries for the
# various options we're interested in.
eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"]
if {"" eq $with_tclsh && $cfg ne ""} {
# We have tclConfig.sh but no tclsh. Attempt to locate a tclsh
# based on info from tclConfig.sh.
proj-assert {"" ne [get-define TCL_EXEC_PREFIX]}
proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}}
set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION]
if {![file-isexec $with_tclsh]} {
set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh
@@ -648,19 +594,20 @@ proc sqlite-check-tcl {} {
}
define TCLSH_CMD $with_tclsh
if {$use_tcl} {
# Set up the TCLLIBDIR
# Set up the TCLLIBDIR and TCLLIB_RPATH
#
# 2024-10-28: calculation of TCLLIBDIR is now done via the shell
# in main.mk (search it for T.tcl.env.sh) so that
# in the main.mk (search it for T.tcllibdir) so that
# static/hand-written makefiles which import main.mk do not have
# to define that before importing main.mk. Even so, we export
# TCLLIBDIR from here, which will cause the makefile to use this
# one rather than to re-calculate it at make-time.
# TCLLIBDIR from here for the benefit of those who want to provide
# it at configure-time and have it "stick", without having to
# provide it on each make invocation or set it in their
# environment.
set tcllibdir [get-env TCLLIBDIR ""]
if {"" eq $tcllibdir} {
# Attempt to extract TCLLIBDIR from TCL's $auto_path
if {"" ne $with_tclsh &&
[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} {
foreach i $result {
if {[file isdir $i]} {
set tcllibdir $i/sqlite3
@@ -668,41 +615,32 @@ proc sqlite-check-tcl {} {
}
}
} else {
proj-warn "Cannot determine TCLLIBDIR."
# The makefile will fail fatally in this case if a target is
# invoked which requires TCLLIBDIR.
proj-warn "Cannot determine TCLLIBDIR"
}
}
#if {"" ne $tcllibdir} { msg-result "TCLLIBDIR = ${tcllibdir}"; }
set tclrpath ""
if {"" ne $tcllibdir} {
set rp [get-define SH_LINKRPATH]
set tclrpath [string map [list "%s" $tcllibdir] $rp]
# Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the
# rpath but (A) it includes an unexpand var ref to
# ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B)
# that flag is inherently compiler-dependent so it's not as
# portable as tclConfig.sh assumes. We'll instead use the rpath
# flag which autosetup determines for the current compiler.
}
define TCLLIBDIR $tcllibdir
define TCLLIB_RPATH $tclrpath
#msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]"
}; # find TCLLIBDIR
if {[file-isexec $with_tclsh]} {
if {[file exists $with_tclsh]} {
msg-result "Using tclsh: $with_tclsh"
if {$cfg ne ""} {
define HAVE_TCL 1
} else {
proj-warn "Found tclsh but no tclConfig.sh."
}
define HAVE_TCL 1
} else {
proj-warn "Cannot find a usable tclsh, so cannot run tests."
}
show-notices
# If TCL is not found: if it was explicitly requested then fail
# fatally, else just emit a warning. If we can find the APIs needed
# to generate a working JimTCL then that will suffice for build-time
# TCL purposes (see: proc sqlite-determine-codegen-tcl).
if {![get-define HAVE_TCL] &&
([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} {
proj-fatal "TCL support was requested but no tclConfig.sh could be found."
}
if {"" eq $cfg} {
proj-assert {0 == [get-define HAVE_TCL]}
proj-indented-notice {
WARNING: Cannot find a usable tclConfig.sh file. Use
--with-tcl=DIR to specify a directory where tclConfig.sh can be
found. SQLite does not use TCL internally, but some optional
components require TCL, including tests and sqlite3_analyzer.
}
}
}; # sqlite-check-tcl
sqlite-check-tcl
@@ -722,15 +660,13 @@ sqlite-check-tcl
# to an unexpanded makefile var name.
#
# - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible
# jimsh. The defaults may be passed on to configure as
# jimsh. The defaults may be pass on to configure as
# CFLAGS_JIMSH=...
set useJimForCodeGen 0 ; # Set to 1 when using jimsh for code generation.
# May affect later decisions.
proc sqlite-determine-codegen-tcl {} {
msg-result "Checking for TCL to use for code generation... "
define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}]
set cgtcl [opt-val with-tclsh jimsh]
set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS}
set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS}
define-push $flagsToRestore {
# We have to swap CC to CC_FOR_BUILD for purposes of the various
# [cc-...] tests below. Recall that --with-wasi-sdk may have
@@ -738,9 +674,6 @@ proc sqlite-determine-codegen-tcl {} {
# Per consulation with autosetup's creator, doing this properly
# requires us to [define-push] the whole $flagsToRestore list
# (plus a few others which are not relevant in this tree).
#
# These will get set to their previous values at the end of this
# block.
foreach flag $flagsToRestore {define $flag ""}
define CC [get-define CC_FOR_BUILD]
if {"jimsh" ne $cgtcl} {
@@ -751,26 +684,14 @@ proc sqlite-determine-codegen-tcl {} {
# These headers are technically optional for JimTCL but necessary if
# we want to use it for code generation:
set sysh [cc-check-includes dirent.h sys/time.h]
# jimsh0.c hard-codes #define's for HAVE_DIRENT_H and
# HAVE_SYS_TIME_H on the platforms it supports, so we do not
# need to add -D... flags for those. We check for them here only
# so that we can avoid the situation that we later, at
# make-time, try to compile jimsh but it then fails due to
# missing headers (i.e. fail earlier rather than later).
if {$sysh && [cc-check-functions realpath]} {
define-append CFLAGS_JIMSH -DHAVE_REALPATH
define BTCLSH "\$(JIMSH)"
set ::useJimForCodeGen 1
} elseif {$sysh && [cc-check-functions _fullpath]} {
# _fullpath() is a Windows API. It's not entirely clear
# whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H}
# to CFLAGS_JIMSH in this case. On MinGW32 we definitely do
# not want to because it already hard-codes them. On _MSC_VER
# builds it does not.
# _fullpath() is a Windows API
define-append CFLAGS_JIMSH -DHAVE__FULLPATH
define BTCLSH "\$(JIMSH)"
set ::useJimForCodeGen 1
} elseif {[file-isexec [get-define TCLSH_CMD]]} {
} elseif {[file exists [get-define TCLSH_CMD]]} {
set cgtcl [get-define TCLSH_CMD]
define BTCLSH "\$(TCLSH_CMD)"
} else {
@@ -788,7 +709,7 @@ proc sqlite-determine-codegen-tcl {} {
}
}
set cgtcl [get-define TCLSH_CMD]
if {![file-isexec $cgtcl]} {
if {![file exists $cgtcl]} {
proj-fatal "Cannot find a tclsh to use for code generation."
}
define BTCLSH "\$(TCLSH_CMD)"
@@ -822,22 +743,23 @@ proj-if-opt-truthy threadsafe {
########################################################################
# Do we want temporary databases in memory?
#
apply {{} {
if {1} {
set ts [opt-val with-tempstore no]
set tsn 1
msg-checking "Use an in-RAM database for temporary tables? "
msg-checking "Use an in-ram database for temporary tables? "
switch -- $ts {
never { set tsn 0 }
no { set tsn 1 }
yes { set tsn 2 }
always { set tsn 3 }
default {
user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
user-error "Invalid with-tempstore value \[$ts]. Use one of: never, no, yes, always"
}
}
msg-result $ts
define TEMP_STORE $tsn
}}
unset ts tsn
}
########################################################################
# sqlite-check-line-editing jumps through proverbial hoops to try to
@@ -847,7 +769,7 @@ apply {{} {
# - HAVE_LINENOISE to 0, 1, or 2
# - HAVE_EDITLINE to 0 or 1
#
# Only one of ^^^ those will be set to non-0.
# Only one of ^^^ those will be set to 1.
#
# - LDFLAGS_READLINE = linker flags or empty string
#
@@ -863,8 +785,7 @@ apply {{} {
#
# Order of checks:
#
# 1) --with-linenoise trumps all others and skips all of the
# complexities involved with the remaining options.
# 1) --with-linenoise trumps all others
#
# 2) --editline trumps --readline
#
@@ -872,7 +793,7 @@ apply {{} {
#
# 4) Default to automatic search for optional readline
#
# 5) Try to find readline or editline. If it's not found AND the
# 5) Try to find readline resp. editline. If it's not found AND the
# corresponding --FEATURE flag was explicitly given, fail fatally,
# else fail silently.
proc sqlite-check-line-editing {} {
@@ -882,9 +803,7 @@ proc sqlite-check-line-editing {} {
define HAVE_EDITLINE 0
define LDFLAGS_READLINE ""
define CFLAGS_READLINE ""
set failIfNotFound 0 ; # Gets set to 1 for explicit --FEATURE requests
# so that we know whether to fail fatally or not
# if the library is not found.
set failIfNotFound 0 ; # Set to 1 for explicit --FEATURE requests
set libsForReadline {readline edit} ; # -l<LIB> names to check for readline().
# The libedit check changes this.
set editLibName "readline" ; # "readline" or "editline"
@@ -922,10 +841,6 @@ proc sqlite-check-line-editing {} {
define CFLAGS_READLINE "-I$dirLn $lnC"
define HAVE_LINENOISE $lnVal
sqlite-add-shell-opt -DHAVE_LINENOISE=$lnVal
if {$::useJimForCodeGen && 2 == $lnVal} {
define-append CFLAGS_JIMSH -DUSE_LINENOISE [get-define CFLAGS_READLINE]
user-notice "Adding linenoise support to jimsh."
}
return "linenoise ($flavor)"
} elseif {[opt-bool editline]} {
# libedit mimics libreadline and on some systems does not have its
@@ -933,8 +848,8 @@ proc sqlite-check-line-editing {} {
#
# shell.c historically expects HAVE_EDITLINE to be set for
# libedit, but it then expects to see <editline/readline.h>, which
# some system's don't actually have despite having libedit. If we
# end up finding <editline/readline.h> below, we will use
# some system's don't actually have, despite having libedit. If
# we end up finding <editline/readline.h> below, we will use
# -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either
# case, we will link against libedit.
set failIfNotFound 1
@@ -958,9 +873,11 @@ proc sqlite-check-line-editing {} {
} else {
set v [file dirname $v]
if {[string match */readline $v]} {
# Special case: if the path includes .../readline/readline.h,
# set the -I to one dir up from that because our sources
# #include <readline/readline.h> or <editline/readline.h>.
# Special case: if the path includes .../readline/readline.h, set
# the -I to one dir up from that because our sources include
# <readline/readline.h> or <editline/readline.h>. Reminder: if
# auto.def is being run by jimsh0 then [file normalize] will not
# work!
set v [file dirname $v]
}
proj-opt-set with-readline-cflags "-I$v"
@@ -1045,8 +962,8 @@ proc sqlite-check-line-editing {} {
set rlInc [join $rlInc]
define LDFLAGS_READLINE $rlLib
define CFLAGS_READLINE $rlInc
proj-assert {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}
proj-assert {$editLibName in {readline editline}}
proj-assert {expr {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}}
proj-assert {expr {$editLibName in {readline editline}}}
sqlite-add-shell-opt -D${editLibDef}=1
msg-result "Using $editLibName flags: $rlInc $rlLib"
# Check whether rl_completion_matches() has a signature we can use
@@ -1066,7 +983,8 @@ proc sqlite-check-line-editing {} {
return 0;
}
}]} {
proj-warn "readline-style completion disabled due to rl_completion_matches() signature mismatch"
user-notice "WARNING: readline-style completion disabled due to rl_completion_matches() signature mismatch"
show-notices
sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION
}
return $editLibName
@@ -1075,6 +993,7 @@ proc sqlite-check-line-editing {} {
if {$failIfNotFound} {
proj-fatal "Explicit --$editLibName failed to find a matching library."
}
return "none"
}; # sqlite-check-line-editing
msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]"
@@ -1188,13 +1107,11 @@ sqlite-check-emsdk
# the required linker flags (which may be empty even if the math APIs
# are found, depending on the OS).
proc affirm-have-math {featureName} {
if {"" eq [get-define LDFLAGS_MATH ""]} {
if {![msg-quiet proj-check-function-in-lib log m]} {
user-error "Missing math APIs for $featureName"
}
define LDFLAGS_MATH [get-define lib_log ""]
undefine lib_log
if {![msg-quiet proj-check-function-in-lib log m]} {
user-error "Missing math APIs for $featureName"
}
define LDFLAGS_MATH [get-define lib_log ""]
undefine lib_log
}
########################################################################
@@ -1237,8 +1154,8 @@ foreach {boolFlag featureFlag ifSetEvalThis} {
}
########################################################################
# Invert the above loop's logic for some SQLITE_OMIT_... cases. If
# config option $boolFlag is false, [sqlite-add-feature-flag
# Invert the above loop's logic for some explicit SQLITE_OMIT_...
# cases. If config option $boolFlag is set, [sqlite-add-feature-flag
# $featureFlag], where $featureFlag is intended to be
# -DSQLITE_OMIT_...
foreach {boolFlag featureFlag} {
@@ -1254,19 +1171,38 @@ foreach {boolFlag featureFlag} {
#########################################################################
# Show the final feature flag sets:
if {1} {
set oFF [get-define OPT_FEATURE_FLAGS]
if {"" ne $oFF} {
define OPT_FEATURE_FLAGS [lsort -unique $oFF]
msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
}
set oFF [get-define OPT_SHELL]
if {"" ne $oFF} {
define OPT_SHELL [lsort -unique $oFF]
msg-result "Shell options: [get-define OPT_SHELL]"
}
unset oFF
set oFF [get-define OPT_FEATURE_FLAGS]
if {"" ne $oFF} {
define OPT_FEATURE_FLAGS [lsort -unique $oFF]
msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
}
set oFF [get-define OPT_SHELL]
if {"" ne $oFF} {
define OPT_SHELL [lsort -unique $oFF]
msg-result "Shell options: [get-define OPT_SHELL]"
}
unset oFF
########################################################################
# Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only
# needs (-DHAVE_REALPATH or -DHAVE__FULLPATH) and -DHAVE_DIRENT_H to
# be compatible with our code generators. It can, however, be slightly
# extended via easy-to-detect features, should we need them.
if {0 && "" ne [get-define CFLAGS_JIMSH]} {
foreach jimFunc {opendir fsync isascii} {
if {[cc-check-functions $jimFunc]} {
define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc]
}
}
#These are hard-coded into jimsh0.c, so we must not -D them:
#foreach jimDef {HAVE_UNISTD_H HAVE_DIRENT_H} {
# if {[is-defined $jimDef]} {
# define-append CFLAGS_JIMSH -D$jimDef
# }
#}
define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available
}; # JimTCL
########################################################################
# "Re-export" the autoconf-conventional --XYZdir flags into something
+15 -42
View File
@@ -46,21 +46,15 @@ Autosetup API Tips
This section briefly covers only APIs which are frequently useful in
day-to-day maintenance and might not be immediately recognized as such
obvious from a casual perusal of [auto.def][]. The complete docs of
those with `proj-` prefix can be found in [proj.tcl][]. The others are
scattered around [the TCL files in ./autosetup](/dir/autosetup).
obvious from a casual perusal of `auto.def`. Their complete docs can be
found in [proj.tcl][].
In (mostly) alphabetical order:
- **`file-isexec filename`**\
Should be used in place of `[file executable]`, as it will also
check for `${filename}.exe` on Windows platforms. However, on such
platforms is also assumes that _any_ existing file is executable.
- **`get-env VAR ?default?`**\
Will fetch an "environment variable"
from the first of either: (1) a KEY=VALUE passed to the configure
script or (2) the system's environment variables. Not to be confused
from the first of either: (A) a KEY=VALUE passed to the configure
script or (B) the system's environment variables. Not to be confused
with `getenv`, which only does the latter and is rarely, if ever,
useful in this tree.
- **`proj-get-env VAR ?default?`**\
@@ -69,47 +63,34 @@ In (mostly) alphabetical order:
trimmed contents. This can be used, e.g., to set a developer's
local preferences for the default `CFLAGS`.
- **`define-for-opt flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\
`[define $defineName]` to either `$yesVal` or `$noVal`, depending on
whether `--$flag` is truthy or not. `$checkingMsg` is a
human-readable description of the check being made, e.g. "enable foo
bar baz?" If no `checkingMsg` is provided, the operation is silent.\
Potential TODO: change the final two args to `-yes` and `-no`
flags. They're rarely needed, though: search [auto.def][] for
`TSTRNNR_OPTS` for an example of where they are used.
- **`proj-fatal msg`**\
Emits `$msg` to stderr and exits with non-zero.
- **`proj-define-if-opt-truthy flag defineName checkingMsg ?yesVal=1? ?noVal=0?`**\
Defines `defineName` to either `yesVal` or `noVal`, depending on
whether `--flag` is truthy or not.
- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\
Evals `thenScript` if the given `--flag` is truthy, else it
evals the optional `elseScript`.
- **`proj-indented-notice ?-error? ?-notice? msg`**\
- **`proj-indented-notice ?-error? msg`**\
Breaks its `msg` argument into lines, trims them, and emits them
with consistent indentation. Exactly how it emits depends on the
flags passed to it (or not), as covered in its docs. This will stick
out starkly from normal output and is intended to be used only for
important notices.
with consistent indentation. If the `-error` flag is used, it then
exits with a non-0 result code. This will stick out starkly from
normal output and is intended to be used only for important notices.
- **`proj-opt-truthy flag`**\
Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on,
enabled, yes, true).
enabled, yes).
- **`proj-opt-was-provided FLAG`**\
Returns 1 if `--FLAG` was explicitly provided to configure,
else 0. This distinction can be used to determine, e.g., whether
`--with-readline` was provided or whether we're searching for
readline by default. In the former case, failure to find it should
be treated as fatal, where in the latter case it's not.
be treated as fatal.
- **`proj-val-truthy value`**\
Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition
of "truthy."
- **`proj-warn msg`**\
Emits `$msg` to stderr. Closely-related is autosetup's `user-notice`
(described below).
Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled,
yes).
- **`sqlite-add-feature-flag ?-shell? FLAG...`**\
Adds the given feature flag to the CFLAGS which are specific to building
@@ -121,14 +102,6 @@ In (mostly) alphabetical order:
- **`sqlite-add-shell-opt FLAG...`**\
The shell-specific counterpart of `sqlite-add-feature-flag`.
- **`user-notice msg`**\
Queues `$msg` to be sent to stderr, but does not emit it until
either `show-notices` is called or the next time autosetup would
output something (it internally calls `show-notices`). This can be
used to generate warnings between a "checking for..." message and
its resulting "yes/no/whatever" message in such a way as to not
spoil the layout of such messages.
<a name="tclcompat"></a>
Ensuring TCL Compatibility
========================================================================
+25
View File
@@ -0,0 +1,25 @@
# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# Auto-load module for 'make' build system integration
use init
autosetup_add_init_type make {Simple "make" build system} {
autosetup_check_create auto.def \
{# Initial auto.def created by 'autosetup --init=make'
use cc
# Add any user options here
options {
}
make-config-header config.h
make-template Makefile.in
}
if {![file exists Makefile.in]} {
puts "Note: I don't see Makefile.in. You will probably need to create one."
}
}
+27 -57
View File
@@ -61,8 +61,7 @@ set proj_(isatty) [isatty? stdout]
#
# Emits a warning message to stderr.
proc proj-warn {msg} {
show-notices
puts stderr "WARNING: $msg"
puts stderr [proj-bold "WARNING: $msg"]
}
########################################################################
# @proj-error msg
@@ -70,28 +69,21 @@ proc proj-warn {msg} {
# Emits an error message to stderr and exits with non-0.
proc proj-fatal {msg} {
show-notices
puts stderr "ERROR: $msg"
puts stderr [proj-bold "ERROR: $msg"]
exit 1
}
########################################################################
# @proj-assert script
#
# Kind of like a C assert: if uplevel (eval) of [expr {$script}] is
# false, a fatal error is triggered. The error message, by default,
# includes the body of the failed assertion, but if $descr is set then
# that is used instead.
proc proj-assert {script {descr ""}} {
# Kind of like a C assert if uplevel (eval) of $script is false,
# triggers a fatal error.
proc proj-assert {script} {
if {1 == [get-env proj-assert 0]} {
msg-result [proj-bold "asserting: $script"]
msg-result [proj-bold "asserting: [string trim $script]"]
}
set x {expr }
append x \{ $script \}
if {![uplevel 1 $x]} {
if {"" eq $descr} {
set descr $script
}
proj-fatal "Assertion failed: $descr"
if {![uplevel 1 $script]} {
proj-fatal "Assertion failed: $script"
}
}
@@ -109,37 +101,23 @@ proc proj-bold {str} {
}
########################################################################
# @proj-indented-notice ?-error? ?-notice? msg
# @proj-indented-notice ?-error? msg
#
# Takes a multi-line message and emits it with consistent indentation.
# Takes a multi-line message and emits it with consistent indentation
# using [user-notice] (which means its rendering will (A) go to stderr
# and (B) be delayed until the next time autosetup goes to output a
# message).
#
# If the -notice flag it used then it emits using [user-notice], which
# means its rendering will (A) go to stderr and (B) be delayed until
# the next time autosetup goes to output a message. If -notice
# is not used, it will send the message to stdout without delay.
#
# If the -error flag is provided then it renders the message
# immediately to stderr and then exits.
# If its first argument is -error then it renders the message
# immediately and then exits.
proc proj-indented-notice {args} {
set fErr ""
set outFunc "puts"
while {[llength $args] > 1} {
switch -exact -- [lindex $args 0] {
-error {
set args [lassign $args fErr]
}
-notice {
set args [lassign $args -]
set outFunc "user-notice"
}
default {
break
}
}
if {"-error" eq [lindex $args 0]} {
set args [lassign $args fErr]
}
set lines [split [join $args] \n]
foreach line $lines {
$outFunc " [string trimleft $line]"
user-notice " [string trimleft $line]"
}
if {"" ne $fErr} {
show-notices
@@ -326,14 +304,6 @@ proc proj-first-bin-of {args} {
# passes --foo-bar to configure, even if that invocation would resolve
# to the default value of baz. If the user does not explicitly pass in
# --foo-bar (with or without a value) then this returns 0.
#
# Note: unlike most functions which deal with configure --flags, this
# one does not validate that $key refers to a pre-defined flag. i.e.
# it accepts arbitrary keys, even those not defined via an [options]
# call. [proj-opt-set] manipulates the internal list of flags, such
# that new options set via that function will cause this function to
# return true. (That's an unintended and unavoidable side-effect, not
# specifically a feature which should be made use of.)
proc proj-opt-was-provided {key} {
dict exists $::autosetup(optset) $key
}
@@ -360,9 +330,9 @@ proc proj-opt-set {flag {val 1}} {
# @proj-val-truthy val
#
# Returns 1 if $val appears to be a truthy value, else returns
# 0. Truthy values are any of {1 on true yes enabled}
# 0. Truthy values are any of {1 on enabled yes}
proc proj-val-truthy {val} {
expr {$val in {1 on true yes enabled}}
expr {$val in {1 on enabled yes}}
}
########################################################################
@@ -393,13 +363,13 @@ proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} {
}
########################################################################
# @proj-define-for-opt flag def ?msg? ?iftrue? ?iffalse?
# @proj-define-if-opt-truthy flag def ?msg? ?iftrue? ?iffalse?
#
# If [proj-opt-truthy $flag] then [define $def $iftrue] else [define
# $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and
# a [msg-results ...] which corresponds to the result. Returns 1 if
# the opt-truthy check passes, else 0.
proc proj-define-for-opt {flag def {msg ""} {iftrue 1} {iffalse 0}} {
proc proj-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} {
if {"" ne $msg} {
msg-checking "$msg "
}
@@ -609,8 +579,7 @@ proc proj-check-compile-commands {{configFlag {}}} {
########################################################################
# @proj-touch filename
#
# Runs the 'touch' external command on one or more files, ignoring any
# errors.
# Runs the 'touch' command on one or more files, ignoring any errors.
proc proj-touch {filename} {
catch { exec touch {*}$filename }
}
@@ -1183,7 +1152,7 @@ proc proj-which-linenoise {dotH} {
# In that make invocation, $(libdir) would, at make-time, normally be
# hard-coded to /foo/lib, rather than /blah/lib. That happens because
# the autosetup exports conventional $prefix-based values for the
# numerous autoconfig-compatible XYZdir vars at configure-time. What
# numerious autoconfig-compatible XYZdir vars at configure-time. What
# we would normally want, however, is that --libdir derives from the
# make-time $(prefix). The distinction between configure-time and
# make-time is the significant factor there.
@@ -1200,10 +1169,11 @@ proc proj-which-linenoise {dotH} {
# reference, e.g. libdir=${exec_prefix}/lib. Ergo, if
# --exec-prefix=FOO is passed to configure, libdir will still derive,
# at make-time, from whatever exec_prefix is passed to make, and will
# use FOO if exec_prefix is not overridden at make-time. Without this
# use FOO if exec_prefix is not overridden. Without this
# post-processing, libdir would be cemented in as FOO/lib at
# configure-time, so could be tedious to override properly via a make
# configure-time, so would be tedious to override properly via a make
# invocation.
#
proc proj-remap-autoconf-dir-vars {} {
set prefix [get-define prefix]
set exec_prefix [get-define exec_prefix $prefix]
+73
View File
@@ -0,0 +1,73 @@
# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# Auto-load module for 'tmake' build system integration
use init
autosetup_add_init_type tmake "Tcl-based tmake build system" {
autosetup_check_create auto.def \
{# Initial auto.def created by 'autosetup --init=tmake'
# vim:set syntax=tcl:
use cc cc-lib cc-db cc-shared
use tmake
# Add any user options here
# Really want a --configure that takes over the rest of the command line
options {
}
cc-check-tools ar ranlib
set objdir [get-env BUILDDIR objdir]
make-config-header $objdir/include/autoconf.h
make-tmake-settings $objdir/settings.conf {[A-Z]*} *dir lib_*
}
autosetup_check_create project.spec \
{# Initial project.spec created by 'autosetup --init=tmake'
tmake-require-version 0.7.3
# vim:set syntax=tcl:
define? DESTDIR _install
# XXX If configure creates additional/different files than include/autoconf.h
# that should be reflected here
Autosetup include/autoconf.h
# e.g. for autoconf.h
IncludePaths include
ifconfig !CONFIGURED {
# Not configured, so don't process subdirs
AutoSubDirs off
# And don't process this file any further
ifconfig false
}
}
set configure [readfile configure]
# XXX Do we need also need to support a system install of tmake?
if {[string first {#@TMAKEUPDATED@} $configure] < 0} {
if {[regsub {#@@INITCHECK@@#} $configure \
{test -z "$TMAKE" -a -x "$dir/tmake" \&\& exec "$dir/tmake" --force --configure "$@"; #@TMAKEUPDATED@} configure]} {
writefile configure $configure\n
exec chmod +x configure
puts "Updated configure to invoke local tmake."
if {![file exec autosetup/tmake]} {
puts "Warning: autosetup/tmake is missing."
puts " Install it with: tmake --install=autosetup"
}
} else {
puts "Warning: configure isn't created by a recent autosetup, not updating."
}
} else {
puts "I see configure for tmake already exists."
}
if {![file exists build.spec]} {
puts "Note: I don't see build.spec. Try running: tmake --genie"
}
}
+52
View File
@@ -0,0 +1,52 @@
# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/
# All rights reserved
# @synopsis:
#
# The 'tmake' module makes it easy to support the tmake build system.
#
# The following variables are set:
#
## CONFIGURED - to indicate that the project is configured
use system
options {}
define CONFIGURED
# @make-tmake-settings outfile patterns ...
#
# Examines all defined variables which match the given patterns (defaults to '*')
# and writes a tmake-compatible .conf file defining those variables.
# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include:
#
## define ABC {3 monkeys}
#
# If the file would be unchanged, it is not written.
#
# Typical usage is:
#
## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*}
proc make-tmake-settings {file args} {
file mkdir [file dirname $file]
set lines {}
if {[llength $args] == 0} {
set args *
}
foreach n [lsort [dict keys [all-defines]]] {
foreach p $args {
if {[string match $p $n]} {
set value [get-define $n]
lappend lines "define $n [list $value]"
break
}
}
}
set buf [join $lines \n]
write-if-changed $file $buf {
msg-result "Created $file"
}
}
+1 -6
View File
@@ -2344,15 +2344,10 @@ static int fts3PoslistPhraseMerge(
if( *p1==POS_COLUMN ){
p1++;
p1 += fts3GetVarint32(p1, &iCol1);
/* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN
** entry, so this is actually end-of-doclist. */
if( iCol1==0 ) return 0;
}
if( *p2==POS_COLUMN ){
p2++;
p2 += fts3GetVarint32(p2, &iCol2);
/* As above, iCol2==0 indicates corruption. */
if( iCol2==0 ) return 0;
}
while( 1 ){
@@ -5523,7 +5518,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX);
aTmp = sqlite3_malloc64(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
+18 -1
View File
@@ -306,8 +306,25 @@ struct Fts5PhraseIter {
** It is the output of the tokenizer module. For tokendata=1 tables, this
** includes any embedded 0x00 and trailing data.
**
** This API may be slow in some cases if the token identified by parameters
** iIdx and iToken matched a prefix token in the query. In most cases, the
** first call to this API for each prefix token in the query is forced
** to scan the portion of the full-text index that matches the prefix
** token to collect the extra data required by this API. If the prefix
** token matches a large number of token instances in the document set,
** this may be a performance problem.
**
** If the user knows in advance that a query may use this API for a
** prefix token, FTS5 may be configured to collect all required data as part
** of the initial querying of the full-text index, avoiding the second scan
** entirely. This also causes prefix queries that do not use this API to
** run more slowly and use more memory. FTS5 may be configured in this way
** either on a per-table basis using the [FTS5 insttoken | 'insttoken']
** option, or on a per-query basis using the
** [fts5_insttoken | fts5_insttoken()] user function.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
** "detail=none" or "detail=column" option.
**
** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
** If parameter iCol is less than zero, or greater than or equal to the
+10 -2
View File
@@ -247,7 +247,8 @@ struct Fts5Config {
char *zRank; /* Name of rank function */
char *zRankArgs; /* Arguments to rank function */
int bSecureDelete; /* 'secure-delete' */
int nDeleteMerge; /* 'deletemerge' */
int nDeleteMerge; /* 'deletemerge' */
int bPrefixInsttoken; /* 'prefix-insttoken' */
/* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
char **pzErrmsg;
@@ -504,7 +505,14 @@ int sqlite3Fts5StructureTest(Fts5Index*, void*);
/*
** Used by xInstToken():
*/
int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*);
int sqlite3Fts5IterToken(
Fts5IndexIter *pIndexIter,
const char *pToken, int nToken,
i64 iRowid,
int iCol,
int iOff,
const char **ppOut, int *pnOut
);
/*
** Insert or remove data to or from the index. Each time a document is
+13
View File
@@ -1026,6 +1026,19 @@ int sqlite3Fts5ConfigSetValue(
}else{
pConfig->bSecureDelete = (bVal ? 1 : 0);
}
}
else if( 0==sqlite3_stricmp(zKey, "insttoken") ){
int bVal = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
bVal = sqlite3_value_int(pVal);
}
if( bVal<0 ){
*pbBadkey = 1;
}else{
pConfig->bPrefixInsttoken = (bVal ? 1 : 0);
}
}else{
*pbBadkey = 1;
}
+9 -10
View File
@@ -3046,7 +3046,7 @@ static int fts5ExprPopulatePoslistsCb(
int rc = sqlite3Fts5PoslistWriterAppend(
&pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
);
if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){
int iCol = p->iOff>>32;
int iTokOff = p->iOff & 0x7FFFFFFF;
rc = sqlite3Fts5IndexIterWriteTokendata(
@@ -3239,15 +3239,14 @@ int sqlite3Fts5ExprInstToken(
return SQLITE_RANGE;
}
pTerm = &pPhrase->aTerm[iToken];
if( pTerm->bPrefix==0 ){
if( pExpr->pConfig->bTokendata ){
rc = sqlite3Fts5IterToken(
pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
);
}else{
*ppOut = pTerm->pTerm;
*pnOut = pTerm->nFullTerm;
}
if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){
rc = sqlite3Fts5IterToken(
pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm,
iRowid, iCol, iOff+iToken, ppOut, pnOut
);
}else{
*ppOut = pTerm->pTerm;
*pnOut = pTerm->nFullTerm;
}
return rc;
}
+527 -196
View File
@@ -6203,6 +6203,383 @@ static void fts5MergePrefixLists(
*p1 = out;
}
/*
** Iterate through a range of entries in the FTS index, invoking the xVisit
** callback for each of them.
**
** Parameter pToken points to an nToken buffer containing an FTS index term
** (i.e. a document term with the preceding 1 byte index identifier -
** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits
** all entries for terms that have pToken/nToken as a prefix. If bPrefix
** is false, then only entries with pToken/nToken as the entire key are
** visited.
**
** If the current table is a tokendata=1 table, then if bPrefix is true then
** each index term is treated separately. However, if bPrefix is false, then
** all index terms corresponding to pToken/nToken are collapsed into a single
** term before the callback is invoked.
**
** The callback invoked for each entry visited is specified by paramter xVisit.
** Each time it is invoked, it is passed a pointer to the Fts5Index object,
** a copy of the 7th paramter to this function (pCtx) and a pointer to the
** iterator that indicates the current entry. If the current entry is the
** first with a new term (i.e. different from that of the previous entry,
** including the very first term), then the final two parameters are passed
** a pointer to the term and its size in bytes, respectively. If the current
** entry is not the first associated with its term, these two parameters
** are passed 0.
**
** If parameter pColset is not NULL, then it is used to filter entries before
** the callback is invoked.
*/
static int fts5VisitEntries(
Fts5Index *p, /* Fts5 index object */
Fts5Colset *pColset, /* Columns filter to apply, or NULL */
u8 *pToken, /* Buffer containing token */
int nToken, /* Size of buffer pToken in bytes */
int bPrefix, /* True for a prefix scan */
void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int),
void *pCtx /* Passed as second argument to xVisit() */
){
const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0)
| FTS5INDEX_QUERY_SKIPEMPTY
| FTS5INDEX_QUERY_NOOUTPUT;
Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
int bNewTerm = 1;
Fts5Structure *pStruct = fts5StructureRead(p);
fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
fts5IterSetOutputCb(&p->rc, p1);
for( /* no-op */ ;
fts5MultiIterEof(p, p1)==0;
fts5MultiIterNext2(p, p1, &bNewTerm)
){
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
int nNew = 0;
const u8 *pNew = 0;
p1->xSetOutputs(p1, pSeg);
if( p->rc ) break;
if( bNewTerm ){
nNew = pSeg->term.n;
pNew = pSeg->term.p;
if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break;
}
xVisit(p, pCtx, p1, pNew, nNew);
}
fts5MultiIterFree(p1);
fts5StructureRelease(pStruct);
return p->rc;
}
/*
** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
** array of these for each row it visits (so all iRowid fields are the same).
** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an
** array of these for the entire query (in which case iRowid fields may take
** a variety of values).
**
** Each instance in the array indicates the iterator (and therefore term)
** associated with position iPos of rowid iRowid. This is used by the
** xInstToken() API.
**
** iRowid:
** Rowid for the current entry.
**
** iPos:
** Position of current entry within row. In the usual ((iCol<<32)+iOff)
** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()).
**
** iIter:
** If the Fts5TokenDataIter iterator that the entry is part of is
** actually an iterator (i.e. with nIter>0, not just a container for
** Fts5TokenDataMap structures), then this variable is an index into
** the apIter[] array. The corresponding term is that which the iterator
** at apIter[iIter] currently points to.
**
** Or, if the Fts5TokenDataIter iterator is just a container object
** (nIter==0), then iIter is an index into the term.p[] buffer where
** the term is stored.
**
** nByte:
** In the case where iIter is an index into term.p[], this variable
** is the size of the term in bytes. If iIter is an index into apIter[],
** this variable is unused.
*/
struct Fts5TokenDataMap {
i64 iRowid; /* Row this token is located in */
i64 iPos; /* Position of token */
int iIter; /* Iterator token was read from */
int nByte; /* Length of token in bytes (or 0) */
};
/*
** An object used to supplement Fts5Iter for tokendata=1 iterators.
**
** This object serves two purposes. The first is as a container for an array
** of Fts5TokenDataMap structures, which are used to find the token required
** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and
** aMap[] variables.
*/
struct Fts5TokenDataIter {
int nMapAlloc; /* Allocated size of aMap[] in entries */
int nMap; /* Number of valid entries in aMap[] */
Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */
/* The following are used for prefix-queries only. */
Fts5Buffer terms;
/* The following are used for other full-token tokendata queries only. */
int nIter;
int nIterAlloc;
Fts5PoslistReader *aPoslistReader;
int *aPoslistToIter;
Fts5Iter *apIter[1];
};
/*
** The two input arrays - a1[] and a2[] - are in sorted order. This function
** merges the two arrays together and writes the result to output array
** aOut[]. aOut[] is guaranteed to be large enough to hold the result.
**
** Duplicate entries are copied into the output. So the size of the output
** array is always (n1+n2) entries.
*/
static void fts5TokendataMerge(
Fts5TokenDataMap *a1, int n1, /* Input array 1 */
Fts5TokenDataMap *a2, int n2, /* Input array 2 */
Fts5TokenDataMap *aOut /* Output array */
){
int i1 = 0;
int i2 = 0;
assert( n1>=0 && n2>=0 );
while( i1<n1 || i2<n2 ){
Fts5TokenDataMap *pOut = &aOut[i1+i2];
if( i2>=n2 || (i1<n1 && (
a1[i1].iRowid<a2[i2].iRowid
|| (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos)
))){
memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap));
i1++;
}else{
memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap));
i2++;
}
}
}
/*
** Append a mapping to the token-map belonging to object pT.
*/
static void fts5TokendataIterAppendMap(
Fts5Index *p,
Fts5TokenDataIter *pT,
int iIter,
int nByte,
i64 iRowid,
i64 iPos
){
if( p->rc==SQLITE_OK ){
if( pT->nMap==pT->nMapAlloc ){
int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
int nAlloc = nNew * sizeof(Fts5TokenDataMap);
Fts5TokenDataMap *aNew;
aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc);
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
return;
}
pT->aMap = aNew;
pT->nMapAlloc = nNew;
}
pT->aMap[pT->nMap].iRowid = iRowid;
pT->aMap[pT->nMap].iPos = iPos;
pT->aMap[pT->nMap].iIter = iIter;
pT->aMap[pT->nMap].nByte = nByte;
pT->nMap++;
}
}
/*
** Sort the contents of the pT->aMap[] array.
**
** The sorting algorithm requries a malloc(). If this fails, an error code
** is left in Fts5Index.rc before returning.
*/
static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){
Fts5TokenDataMap *aTmp = 0;
int nByte = pT->nMap * sizeof(Fts5TokenDataMap);
aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( aTmp ){
Fts5TokenDataMap *a1 = pT->aMap;
Fts5TokenDataMap *a2 = aTmp;
i64 nHalf;
for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){
int i1;
for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){
int n1 = MIN(nHalf, pT->nMap-i1);
int n2 = MIN(nHalf, pT->nMap-i1-n1);
fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]);
}
SWAPVAL(Fts5TokenDataMap*, a1, a2);
}
if( a1!=pT->aMap ){
memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap));
}
sqlite3_free(aTmp);
#ifdef SQLITE_DEBUG
{
int ii;
for(ii=1; ii<pT->nMap; ii++){
Fts5TokenDataMap *p1 = &pT->aMap[ii-1];
Fts5TokenDataMap *p2 = &pT->aMap[ii];
assert( p1->iRowid<p2->iRowid
|| (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos)
);
}
}
#endif
}
}
/*
** Delete an Fts5TokenDataIter structure and its contents.
*/
static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
if( pSet ){
int ii;
for(ii=0; ii<pSet->nIter; ii++){
fts5MultiIterFree(pSet->apIter[ii]);
}
fts5BufferFree(&pSet->terms);
sqlite3_free(pSet->aPoslistReader);
sqlite3_free(pSet->aMap);
sqlite3_free(pSet);
}
}
/*
** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata()
** to pass data to prefixIterSetupTokendataCb().
*/
typedef struct TokendataSetupCtx TokendataSetupCtx;
struct TokendataSetupCtx {
Fts5TokenDataIter *pT; /* Object being populated with mappings */
int iTermOff; /* Offset of current term in terms.p[] */
int nTermByte; /* Size of current term in bytes */
};
/*
** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This
** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each
** position in the current position-list. It doesn't matter that some of
** these may be out of order - they will be sorted later.
*/
static void prefixIterSetupTokendataCb(
Fts5Index *p,
void *pCtx,
Fts5Iter *p1,
const u8 *pNew,
int nNew
){
TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx;
int iPosOff = 0;
i64 iPos = 0;
if( pNew ){
pSetup->nTermByte = nNew-1;
pSetup->iTermOff = pSetup->pT->terms.n;
fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1);
}
while( 0==sqlite3Fts5PoslistNext64(
p1->base.pData, p1->base.nData, &iPosOff, &iPos
) ){
fts5TokendataIterAppendMap(p,
pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos
);
}
}
/*
** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries().
*/
typedef struct PrefixSetupCtx PrefixSetupCtx;
struct PrefixSetupCtx {
void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
i64 iLastRowid;
int nMerge;
Fts5Buffer *aBuf;
int nBuf;
Fts5Buffer doclist;
TokendataSetupCtx *pTokendata;
};
/*
** fts5VisitEntries() callback used by fts5SetupPrefixIter()
*/
static void prefixIterSetupCb(
Fts5Index *p,
void *pCtx,
Fts5Iter *p1,
const u8 *pNew,
int nNew
){
PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx;
const int nMerge = pSetup->nMerge;
if( p1->base.nData>0 ){
if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){
int i;
for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){
int i1 = i*nMerge;
int iStore;
assert( i1+nMerge<=pSetup->nBuf );
for(iStore=i1; iStore<i1+nMerge; iStore++){
if( pSetup->aBuf[iStore].n==0 ){
fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]);
fts5BufferZero(&pSetup->doclist);
break;
}
}
if( iStore==i1+nMerge ){
pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]);
for(iStore=i1; iStore<i1+nMerge; iStore++){
fts5BufferZero(&pSetup->aBuf[iStore]);
}
}
}
pSetup->iLastRowid = 0;
}
pSetup->xAppend(
p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist
);
pSetup->iLastRowid = p1->base.iRowid;
}
if( pSetup->pTokendata ){
prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew);
}
}
static void fts5SetupPrefixIter(
Fts5Index *p, /* Index to read from */
int bDesc, /* True for "ORDER BY rowid DESC" */
@@ -6213,38 +6590,41 @@ static void fts5SetupPrefixIter(
Fts5Iter **ppIter /* OUT: New iterator */
){
Fts5Structure *pStruct;
Fts5Buffer *aBuf;
int nBuf = 32;
int nMerge = 1;
PrefixSetupCtx s;
TokendataSetupCtx s2;
void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*);
void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*);
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
xMerge = fts5MergeRowidLists;
xAppend = fts5AppendRowid;
}else{
nMerge = FTS5_MERGE_NLIST-1;
nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
xMerge = fts5MergePrefixLists;
xAppend = fts5AppendPoslist;
memset(&s, 0, sizeof(s));
memset(&s2, 0, sizeof(s2));
s.nMerge = 1;
s.iLastRowid = 0;
s.nBuf = 32;
if( iIdx==0
&& p->pConfig->eDetail==FTS5_DETAIL_FULL
&& p->pConfig->bPrefixInsttoken
){
s.pTokendata = &s2;
s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT));
}
aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
s.xMerge = fts5MergeRowidLists;
s.xAppend = fts5AppendRowid;
}else{
s.nMerge = FTS5_MERGE_NLIST-1;
s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */
s.xMerge = fts5MergePrefixLists;
s.xAppend = fts5AppendPoslist;
}
s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf);
pStruct = fts5StructureRead(p);
assert( p->rc!=SQLITE_OK || (aBuf && pStruct) );
assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) );
if( p->rc==SQLITE_OK ){
const int flags = FTS5INDEX_QUERY_SCAN
| FTS5INDEX_QUERY_SKIPEMPTY
| FTS5INDEX_QUERY_NOOUTPUT;
void *pCtx = (void*)&s;
int i;
i64 iLastRowid = 0;
Fts5Iter *p1 = 0; /* Iterator used to gather data from index */
Fts5Data *pData;
Fts5Buffer doclist;
int bNewTerm = 1;
memset(&doclist, 0, sizeof(doclist));
/* If iIdx is non-zero, then it is the number of a prefix-index for
** prefixes 1 character longer than the prefix being queried for. That
@@ -6252,94 +6632,43 @@ static void fts5SetupPrefixIter(
** corresponding to the prefix itself. That one is extracted from the
** main term index here. */
if( iIdx!=0 ){
int dummy = 0;
const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT;
pToken[0] = FTS5_MAIN_PREFIX;
fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1);
fts5IterSetOutputCb(&p->rc, p1);
for(;
fts5MultiIterEof(p, p1)==0;
fts5MultiIterNext2(p, p1, &dummy)
){
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
p1->xSetOutputs(p1, pSeg);
if( p1->base.nData ){
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
iLastRowid = p1->base.iRowid;
}
}
fts5MultiIterFree(p1);
fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx);
}
pToken[0] = FTS5_MAIN_PREFIX + iIdx;
fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1);
fts5IterSetOutputCb(&p->rc, p1);
fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx);
for( /* no-op */ ;
fts5MultiIterEof(p, p1)==0;
fts5MultiIterNext2(p, p1, &bNewTerm)
){
Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ];
int nTerm = pSeg->term.n;
const u8 *pTerm = pSeg->term.p;
p1->xSetOutputs(p1, pSeg);
assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
if( bNewTerm ){
if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
}
if( p1->base.nData==0 ) continue;
if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){
for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
int i1 = i*nMerge;
int iStore;
assert( i1+nMerge<=nBuf );
for(iStore=i1; iStore<i1+nMerge; iStore++){
if( aBuf[iStore].n==0 ){
fts5BufferSwap(&doclist, &aBuf[iStore]);
fts5BufferZero(&doclist);
break;
}
}
if( iStore==i1+nMerge ){
xMerge(p, &doclist, nMerge, &aBuf[i1]);
for(iStore=i1; iStore<i1+nMerge; iStore++){
fts5BufferZero(&aBuf[iStore]);
}
}
}
iLastRowid = 0;
}
xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist);
iLastRowid = p1->base.iRowid;
}
assert( (nBuf%nMerge)==0 );
for(i=0; i<nBuf; i+=nMerge){
assert( (s.nBuf%s.nMerge)==0 );
for(i=0; i<s.nBuf; i+=s.nMerge){
int iFree;
if( p->rc==SQLITE_OK ){
xMerge(p, &doclist, nMerge, &aBuf[i]);
s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]);
}
for(iFree=i; iFree<i+nMerge; iFree++){
fts5BufferFree(&aBuf[iFree]);
for(iFree=i; iFree<i+s.nMerge; iFree++){
fts5BufferFree(&s.aBuf[iFree]);
}
}
fts5MultiIterFree(p1);
pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING);
pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING);
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = doclist.n;
if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n);
pData->nn = pData->szLeaf = s.doclist.n;
if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n);
fts5MultiIterNew2(p, pData, bDesc, ppIter);
}
fts5BufferFree(&doclist);
if( p->rc==SQLITE_OK && s.pTokendata ){
fts5TokendataIterSortMap(p, s2.pT);
(*ppIter)->pTokenDataIter = s2.pT;
s2.pT = 0;
}
}
fts5TokendataIterDelete(s2.pT);
fts5BufferFree(&s.doclist);
fts5StructureRelease(pStruct);
sqlite3_free(aBuf);
sqlite3_free(s.aBuf);
}
@@ -6593,38 +6922,6 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
pSeg->pLeaf = 0;
}
/*
** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an
** array of these for each row it visits. Or, for an iterator used by an
** "ORDER BY rank" query, it accumulates an array of these for the entire
** query.
**
** Each instance in the array indicates the iterator (and therefore term)
** associated with position iPos of rowid iRowid. This is used by the
** xInstToken() API.
*/
struct Fts5TokenDataMap {
i64 iRowid; /* Row this token is located in */
i64 iPos; /* Position of token */
int iIter; /* Iterator token was read from */
};
/*
** An object used to supplement Fts5Iter for tokendata=1 iterators.
*/
struct Fts5TokenDataIter {
int nIter;
int nIterAlloc;
int nMap;
int nMapAlloc;
Fts5TokenDataMap *aMap;
Fts5PoslistReader *aPoslistReader;
int *aPoslistToIter;
Fts5Iter *apIter[1];
};
/*
** This function appends iterator pAppend to Fts5TokenDataIter pIn and
** returns the result.
@@ -6661,54 +6958,6 @@ static Fts5TokenDataIter *fts5AppendTokendataIter(
return pRet;
}
/*
** Delete an Fts5TokenDataIter structure and its contents.
*/
static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){
if( pSet ){
int ii;
for(ii=0; ii<pSet->nIter; ii++){
fts5MultiIterFree(pSet->apIter[ii]);
}
sqlite3_free(pSet->aPoslistReader);
sqlite3_free(pSet->aMap);
sqlite3_free(pSet);
}
}
/*
** Append a mapping to the token-map belonging to object pT.
*/
static void fts5TokendataIterAppendMap(
Fts5Index *p,
Fts5TokenDataIter *pT,
int iIter,
i64 iRowid,
i64 iPos
){
if( p->rc==SQLITE_OK ){
if( pT->nMap==pT->nMapAlloc ){
int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64;
int nByte = nNew * sizeof(Fts5TokenDataMap);
Fts5TokenDataMap *aNew;
aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte);
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
return;
}
pT->aMap = aNew;
pT->nMapAlloc = nNew;
}
pT->aMap[pT->nMap].iRowid = iRowid;
pT->aMap[pT->nMap].iPos = iPos;
pT->aMap[pT->nMap].iIter = iIter;
pT->nMap++;
}
}
/*
** The iterator passed as the only argument must be a tokendata=1 iterator
** (pIter->pTokenDataIter!=0). This function sets the iterator output
@@ -6749,7 +6998,7 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
pIter->base.iRowid = iRowid;
if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){
fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1);
fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1);
}else
if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){
int nReader = 0;
@@ -7002,6 +7251,7 @@ static Fts5Iter *fts5SetupTokendataIter(
pRet = fts5MultiIterAlloc(p, 0);
}
if( pRet ){
pRet->nSeg = 0;
pRet->pTokenDataIter = pSet;
if( pSet ){
fts5IterSetOutputsTokendata(pRet);
@@ -7017,7 +7267,6 @@ static Fts5Iter *fts5SetupTokendataIter(
return pRet;
}
/*
** Open a new iterator to iterate though all rowid that match the
** specified token or token prefix.
@@ -7042,6 +7291,11 @@ int sqlite3Fts5IndexQuery(
int bTokendata = pConfig->bTokendata;
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
/* The NOTOKENDATA flag is set when each token in a tokendata=1 table
** should be treated individually, instead of merging all those with
** a common prefix into a single entry. This is used, for example, by
** queries performed as part of an integrity-check, or by the fts5vocab
** module. */
if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){
bTokendata = 0;
}
@@ -7072,7 +7326,7 @@ int sqlite3Fts5IndexQuery(
}
if( bTokendata && iIdx==0 ){
buf.p[0] = '0';
buf.p[0] = FTS5_MAIN_PREFIX;
pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset);
}else if( iIdx<=pConfig->nPrefix ){
/* Straight index lookup */
@@ -7085,7 +7339,7 @@ int sqlite3Fts5IndexQuery(
fts5StructureRelease(pStruct);
}
}else{
/* Scan multiple terms in the main index */
/* Scan multiple terms in the main index for a prefix query. */
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
if( pRet==0 ){
@@ -7121,7 +7375,8 @@ int sqlite3Fts5IndexQuery(
int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
assert( pIter->pIndex->rc==SQLITE_OK );
if( pIter->pTokenDataIter ){
if( pIter->nSeg==0 ){
assert( pIter->pTokenDataIter );
fts5TokendataIterNext(pIter, 0, 0);
}else{
fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
@@ -7158,7 +7413,8 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
*/
int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
if( pIter->pTokenDataIter ){
if( pIter->nSeg==0 ){
assert( pIter->pTokenDataIter );
fts5TokendataIterNext(pIter, 1, iMatch);
}else{
fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
@@ -7177,14 +7433,60 @@ const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
return (z ? &z[1] : 0);
}
/*
** pIter is a prefix query. This function populates pIter->pTokenDataIter
** with an Fts5TokenDataIter object containing mappings for all rows
** matched by the query.
*/
static int fts5SetupPrefixIterTokendata(
Fts5Iter *pIter,
const char *pToken, /* Token prefix to search for */
int nToken /* Size of pToken in bytes */
){
Fts5Index *p = pIter->pIndex;
Fts5Buffer token = {0, 0, 0};
TokendataSetupCtx ctx;
memset(&ctx, 0, sizeof(ctx));
fts5BufferGrow(&p->rc, &token, nToken+1);
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
if( p->rc==SQLITE_OK ){
/* Fill in the token prefix to search for */
token.p[0] = FTS5_MAIN_PREFIX;
memcpy(&token.p[1], pToken, nToken);
token.n = nToken+1;
fts5VisitEntries(
p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx
);
fts5TokendataIterSortMap(p, ctx.pT);
}
if( p->rc==SQLITE_OK ){
pIter->pTokenDataIter = ctx.pT;
}else{
fts5TokendataIterDelete(ctx.pT);
}
fts5BufferFree(&token);
return fts5IndexReturn(p);
}
/*
** This is used by xInstToken() to access the token at offset iOff, column
** iCol of row iRowid. The token is returned via output variables *ppOut
** and *pnOut. The iterator passed as the first argument must be a tokendata=1
** iterator (pIter->pTokenDataIter!=0).
**
** pToken/nToken:
*/
int sqlite3Fts5IterToken(
Fts5IndexIter *pIndexIter,
const char *pToken, int nToken,
i64 iRowid,
int iCol,
int iOff,
@@ -7192,13 +7494,22 @@ int sqlite3Fts5IterToken(
){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
Fts5TokenDataMap *aMap = pT->aMap;
i64 iPos = (((i64)iCol)<<32) + iOff;
Fts5TokenDataMap *aMap = 0;
int i1 = 0;
int i2 = pT->nMap;
int i2 = 0;
int iTest = 0;
assert( pT || (pToken && pIter->nSeg>0) );
if( pT==0 ){
int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken);
if( rc!=SQLITE_OK ) return rc;
pT = pIter->pTokenDataIter;
}
i2 = pT->nMap;
aMap = pT->aMap;
while( i2>i1 ){
iTest = (i1 + i2) / 2;
@@ -7221,9 +7532,15 @@ int sqlite3Fts5IterToken(
}
if( i2>i1 ){
Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
*ppOut = (const char*)pMap->aSeg[0].term.p+1;
*pnOut = pMap->aSeg[0].term.n-1;
if( pIter->nSeg==0 ){
Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter];
*ppOut = (const char*)pMap->aSeg[0].term.p+1;
*pnOut = pMap->aSeg[0].term.n-1;
}else{
Fts5TokenDataMap *p = &aMap[iTest];
*ppOut = (const char*)&pT->terms.p[p->iIter];
*pnOut = aMap[iTest].nByte;
}
}
return SQLITE_OK;
@@ -7235,7 +7552,9 @@ int sqlite3Fts5IterToken(
*/
void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
if( pIter && pIter->pTokenDataIter ){
if( pIter && pIter->pTokenDataIter
&& (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL)
){
pIter->pTokenDataIter->nMap = 0;
}
}
@@ -7255,17 +7574,29 @@ int sqlite3Fts5IndexIterWriteTokendata(
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
Fts5Index *p = pIter->pIndex;
int ii;
i64 iPos = (((i64)iCol)<<32) + iOff;
assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL );
assert( pIter->pTokenDataIter );
for(ii=0; ii<pT->nIter; ii++){
Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
}
if( ii<pT->nIter ){
fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff);
assert( pIter->pTokenDataIter || pIter->nSeg>0 );
if( pIter->nSeg>0 ){
/* This is a prefix term iterator. */
if( pT==0 ){
pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT));
pIter->pTokenDataIter = pT;
}
if( pT ){
fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos);
fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken);
}
}else{
int ii;
for(ii=0; ii<pT->nIter; ii++){
Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term;
if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break;
}
if( ii<pT->nIter ){
fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos);
}
}
return fts5IndexReturn(p);
}
+27 -2
View File
@@ -93,6 +93,7 @@ struct Fts5Global {
#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
#define FTS5_INSTTOKEN_SUBTYPE 73
/*
** Each auxiliary function registered with the FTS5 module is represented
@@ -632,7 +633,6 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
if( p->usable==0 || iCol<0 ){
/* As there exists an unusable MATCH constraint this is an
** unusable plan. Return SQLITE_CONSTRAINT. */
idxStr[iIdxStr] = 0;
return SQLITE_CONSTRAINT;
}else{
if( iCol==nCol+1 ){
@@ -1418,6 +1418,7 @@ static int fts5FilterMethod(
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
int iCol; /* Column on LHS of MATCH operator */
char **pzErrmsg = pConfig->pzErrmsg;
int bPrefixInsttoken = pConfig->bPrefixInsttoken;
int i;
int iIdxStr = 0;
Fts5Expr *pExpr = 0;
@@ -1453,6 +1454,9 @@ static int fts5FilterMethod(
rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
if( rc!=SQLITE_OK ) goto filter_out;
if( zText==0 ) zText = "";
if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){
pConfig->bPrefixInsttoken = 1;
}
iCol = 0;
do{
@@ -1593,6 +1597,7 @@ static int fts5FilterMethod(
filter_out:
sqlite3Fts5ExprFree(pExpr);
pConfig->pzErrmsg = pzErrmsg;
pConfig->bPrefixInsttoken = bPrefixInsttoken;
return rc;
}
@@ -3652,6 +3657,19 @@ static void fts5LocaleFunc(
}
}
/*
** Implementation of fts5_insttoken() function.
*/
static void fts5InsttokenFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apArg /* Function arguments */
){
assert( nArg==1 );
sqlite3_result_value(pCtx, apArg[0]);
sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
@@ -3781,10 +3799,17 @@ static int fts5Init(sqlite3 *db){
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(
db, "fts5_locale", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE,
p, fts5LocaleFunc, 0, 0
);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(
db, "fts5_insttoken", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
p, fts5InsttokenFunc, 0, 0
);
}
}
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
+5 -17
View File
@@ -730,9 +730,8 @@ static int SQLITE_TCLAPI f5tTokenize(
int objc,
Tcl_Obj *CONST objv[]
){
char *pCopy = 0;
char *zText = 0;
Tcl_Size nText = 0;
char *zText;
Tcl_Size nText;
sqlite3 *db = 0;
fts5_api *pApi = 0;
Fts5Tokenizer *pTok = 0;
@@ -779,33 +778,22 @@ static int SQLITE_TCLAPI f5tTokenize(
return TCL_ERROR;
}
if( nText>0 ){
pCopy = sqlite3_malloc(nText);
if( pCopy==0 ){
tokenizer.xDelete(pTok);
Tcl_AppendResult(interp, "error in sqlite3_malloc()", (char*)0);
return TCL_ERROR;
}else{
memcpy(pCopy, zText, nText);
}
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
ctx.bSubst = (objc==5);
ctx.pRet = pRet;
ctx.zInput = pCopy;
ctx.zInput = zText;
rc = tokenizer.xTokenize(
pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, pCopy,(int)nText, xTokenizeCb2
pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText,(int)nText, xTokenizeCb2
);
tokenizer.xDelete(pTok);
sqlite3_free(pCopy);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", (char*)0);
Tcl_DecrRefCount(pRet);
return TCL_ERROR;
}
Tcl_Free((void*)azArg);
Tcl_SetObjResult(interp, pRet);
Tcl_DecrRefCount(pRet);
+3 -6
View File
@@ -1354,7 +1354,7 @@ static int fts5TriTokenize(
int ii;
const unsigned char *zIn = (const unsigned char*)pText;
const unsigned char *zEof = &zIn[nText];
u32 iCode = 0;
u32 iCode;
int aStart[3]; /* Input offset of each character in aBuf[] */
UNUSED_PARAM(unusedFlags);
@@ -1363,8 +1363,8 @@ static int fts5TriTokenize(
for(ii=0; ii<3; ii++){
do {
aStart[ii] = zIn - (const unsigned char*)pText;
if( zIn>=zEof ) return SQLITE_OK;
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) return SQLITE_OK;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );
WRITE_UTF8(zOut, iCode);
@@ -1385,11 +1385,8 @@ static int fts5TriTokenize(
/* Read characters from the input up until the first non-diacritic */
do {
iNext = zIn - (const unsigned char*)pText;
if( zIn>=zEof ){
iCode = 0;
break;
}
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );
+86 -42
View File
@@ -22,34 +22,40 @@ ifcapable !fts5 {
}
foreach_detail_mode $testprefix {
foreach {tn insttoken} {
1 0
2 1
} {
reset_db
sqlite3_fts5_register_origintext db
do_execsql_test 1.0 {
do_execsql_test $tn.1.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize="origintext unicode61", detail=%DETAIL%
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance);
}
do_execsql_test 1.1 {
do_execsql_test $tn.1.1 {
INSERT INTO ft VALUES('Hello world');
}
do_execsql_test 1.2 {
do_execsql_test $tn.1.2 {
INSERT INTO ft(ft) VALUES('integrity-check');
}
proc b {x} { string map [list "\0" "."] $x }
db func b b
do_execsql_test 1.3 {
do_execsql_test $tn.1.3 {
select b(term) from vocab;
} {
hello.Hello
world
}
do_execsql_test 1.4 {
do_execsql_test $tn.1.4 {
SELECT rowid FROM ft('Hello');
} {1}
@@ -88,33 +94,34 @@ proc document {} {
db func document document
sqlite3_fts5_register_origintext db
do_execsql_test 2.0 {
do_execsql_test $tn.2.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize="origintext unicode61", detail=%DETAIL%
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
INSERT INTO ft(ft, rank) VALUES('pgsz', 128);
CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance);
}
do_test 2.1 {
do_test $tn.2.1 {
for {set ii 0} {$ii < 500} {incr ii} {
execsql { INSERT INTO ft VALUES( document() ) }
}
} {}
do_execsql_test 2.2 {
do_execsql_test $tn.2.2 {
INSERT INTO ft(ft) VALUES('integrity-check');
}
do_execsql_test 2.3 {
do_execsql_test $tn.2.3 {
INSERT INTO ft(ft, rank) VALUES('merge', 16);
}
do_execsql_test 2.4 {
do_execsql_test $tn.2.4 {
INSERT INTO ft(ft) VALUES('integrity-check');
}
do_execsql_test 2.5 {
do_execsql_test $tn.2.5 {
INSERT INTO ft(ft) VALUES('optimize');
}
@@ -122,10 +129,11 @@ do_execsql_test 2.5 {
reset_db
sqlite3_fts5_register_origintext db
do_execsql_test 3.0 {
do_execsql_test $tn.3.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize="origintext unicode61", detail=%DETAIL%
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance);
INSERT INTO ft(rowid, x) VALUES(1, 'hello');
@@ -137,16 +145,17 @@ do_execsql_test 3.0 {
#db func b b
#execsql_pp { SELECT b(term) FROM vocab }
do_execsql_test 3.1.1 { SELECT rowid FROM ft('hello') } 1
do_execsql_test 3.1.2 { SELECT rowid FROM ft('Hello') } 2
do_execsql_test 3.1.3 { SELECT rowid FROM ft('HELLO') } 3
do_execsql_test $tn.3.1.1 { SELECT rowid FROM ft('hello') } 1
do_execsql_test $tn.3.1.2 { SELECT rowid FROM ft('Hello') } 2
do_execsql_test $tn.3.1.3 { SELECT rowid FROM ft('HELLO') } 3
do_execsql_test 3.2 {
do_execsql_test $tn.3.2 {
CREATE VIRTUAL TABLE ft2 USING fts5(x,
tokenize="origintext unicode61",
tokendata=1,
detail=%DETAIL%
);
INSERT INTO ft2(ft2, rank) VALUES('insttoken', $insttoken);
CREATE VIRTUAL TABLE vocab2 USING fts5vocab(ft2, instance);
INSERT INTO ft2(rowid, x) VALUES(1, 'hello');
@@ -160,11 +169,18 @@ do_execsql_test 3.2 {
#db func b b
#execsql_pp { SELECT b(term) FROM vocab }
do_execsql_test 3.3.1 { SELECT rowid FROM ft2('hello') } {1 2 3}
do_execsql_test 3.3.2 { SELECT rowid FROM ft2('Hello') } {1 2 3}
do_execsql_test 3.3.3 { SELECT rowid FROM ft2('HELLO') } {1 2 3}
do_execsql_test $tn.3.3.1 { SELECT rowid FROM ft2('hello') } {1 2 3}
do_execsql_test $tn.3.3.2 { SELECT rowid FROM ft2('Hello') } {1 2 3}
do_execsql_test $tn.3.3.3 { SELECT rowid FROM ft2('HELLO') } {1 2 3}
do_execsql_test 3.3.4 { SELECT rowid FROM ft2('hello*') } {1 2 3 10}
do_execsql_test $tn.3.3.4 { SELECT rowid FROM ft2('hello*') } {1 2 3 10}
do_execsql_test $tn.3.3.5.1 { SELECT rowid FROM ft2('HELLO') ORDER BY rowid DESC} {
3 2 1
}
do_execsql_test $tn.3.3.5.2 { SELECT rowid FROM ft2('HELLO') ORDER BY +rowid DESC} {
3 2 1
}
#-------------------------------------------------------------------------
#
@@ -176,36 +192,37 @@ proc querytoken {cmd iPhrase iToken} {
}
sqlite3_fts5_create_function db querytoken querytoken
do_execsql_test 4.0 {
do_execsql_test $tn.4.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize='origintext unicode61', tokendata=1, detail=%DETAIL%
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
INSERT INTO ft VALUES('one two three four');
}
do_execsql_test 4.1 {
do_execsql_test $tn.4.1 {
SELECT rowid, querytoken(ft, 0, 0) FROM ft('TwO')
} {1 two.TwO}
do_execsql_test 4.2 {
do_execsql_test $tn.4.2 {
SELECT rowid, querytoken(ft, 0, 0) FROM ft('one TWO ThreE')
} {1 one}
do_execsql_test 4.3 {
do_execsql_test $tn.4.3 {
SELECT rowid, querytoken(ft, 1, 0) FROM ft('one TWO ThreE')
} {1 two.TWO}
if {"%DETAIL%"=="full"} {
# Phrase queries are only supported for detail=full.
#
do_execsql_test 4.4 {
do_execsql_test $tn.4.4 {
SELECT rowid, querytoken(ft, 0, 2) FROM ft('"one TWO ThreE"')
} {1 three.ThreE}
do_catchsql_test 4.5 {
do_catchsql_test $tn.4.5 {
SELECT rowid, querytoken(ft, 0, 3) FROM ft('"one TWO ThreE"')
} {1 SQLITE_RANGE}
do_catchsql_test 4.6 {
do_catchsql_test $tn.4.6 {
SELECT rowid, querytoken(ft, 1, 0) FROM ft('"one TWO ThreE"')
} {1 SQLITE_RANGE}
do_catchsql_test 4.7 {
do_catchsql_test $tn.4.7 {
SELECT rowid, querytoken(ft, -1, 0) FROM ft('"one TWO ThreE"')
} {1 SQLITE_RANGE}
}
@@ -221,14 +238,15 @@ proc insttoken {cmd iIdx iToken} {
sqlite3_fts5_create_function db insttoken insttoken
fts5_aux_test_functions db
do_execsql_test 5.0 {
do_execsql_test $tn.5.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize='origintext unicode61', tokendata=1, detail=%DETAIL%
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
INSERT INTO ft VALUES('one ONE One oNe oNE one');
}
do_execsql_test 5.1 {
do_execsql_test $tn.5.1 {
SELECT insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
insttoken(ft, 2, 0),
@@ -240,13 +258,37 @@ do_execsql_test 5.1 {
one one.ONE one.One one.oNe one.oNE one
}
do_execsql_test 5.2 {
do_execsql_test $tn.5.2 {
SELECT insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
insttoken(ft, 2, 0),
insttoken(ft, 3, 0),
insttoken(ft, 4, 0),
insttoken(ft, 5, 0)
FROM ft('on*');
} {
one one.ONE one.One one.oNe one.oNE one
}
do_execsql_test $tn.5.3 {
SELECT insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
insttoken(ft, 2, 0),
insttoken(ft, 3, 0),
insttoken(ft, 4, 0),
insttoken(ft, 5, 0)
FROM ft(fts5_insttoken('on*'));
} {
one one.ONE one.One one.oNe one.oNE one
}
do_execsql_test $tn.5.4 {
SELECT insttoken(ft, 1, 0) FROM ft('one');
} {
one.ONE
}
do_execsql_test 5.3 {
do_execsql_test $tn.5.5 {
SELECT fts5_test_poslist(ft) FROM ft('one');
} {
{0.0.0 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5}
@@ -260,10 +302,11 @@ do_execsql_test 5.3 {
#
reset_db
sqlite3_fts5_register_origintext db
do_execsql_test 6.0 {
do_execsql_test $tn.6.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, y, tokenize='origintext unicode61', detail=%DETAIL%, tokendata=0
);
INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken);
INSERT INTO ft VALUES('One Two', 'Three two');
INSERT INTO ft VALUES('three Three', 'one One');
@@ -279,34 +322,35 @@ proc tokens {cmd} {
}
sqlite3_fts5_create_function db tokens tokens
do_execsql_test 6.1 {
do_execsql_test $tn.6.1 {
SELECT rowid, tokens(ft) FROM ft('One');
} {1 one.One 2 one.One}
do_execsql_test 6.2 {
do_execsql_test $tn.6.2 {
SELECT rowid, tokens(ft) FROM ft('on*');
} {1 {{}} 2 {{} {}}}
} {1 one.One 2 {one one.One}}
do_execsql_test 6.3 {
do_execsql_test $tn.6.3 {
SELECT rowid, tokens(ft) FROM ft('Three*');
} {1 {{}} 2 {{}}}
} {1 three.Three 2 three.Three}
fts5_aux_test_functions db
do_catchsql_test 6.4 {
do_catchsql_test $tn.6.4 {
SELECT fts5_test_insttoken(ft, -1, 0) FROM ft('one');
} {1 SQLITE_RANGE}
do_catchsql_test 6.5 {
do_catchsql_test $tn.6.5 {
SELECT fts5_test_insttoken(ft, 1, 0) FROM ft('one');
} {1 SQLITE_RANGE}
do_catchsql_test 6.6 {
do_catchsql_test $tn.6.6 {
CREATE VIRTUAL TABLE ft2 USING fts5(x, tokendata=2);
} {1 {malformed tokendata=... directive}}
do_catchsql_test 6.7 {
do_catchsql_test $tn.6.7 {
CREATE VIRTUAL TABLE ft2 USING fts5(x, content='', tokendata=11);
} {1 {malformed tokendata=... directive}}
}
}
finish_test
+50 -10
View File
@@ -22,6 +22,11 @@ ifcapable !fts5 {
}
foreach_detail_mode $testprefix {
foreach {tn insttoken} {
1 0
2 1
} {
reset_db
sqlite3_fts5_register_origintext db
@@ -32,21 +37,25 @@ foreach_detail_mode $testprefix {
}
sqlite3_fts5_create_function db insttoken insttoken
do_execsql_test 1.0 {
do_execsql_test $tn.1.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%
);
}
do_execsql_test $tn.1.0.1 {
INSERT INTO ft(ft, rank) VALUES('insttoken', 1);
}
do_execsql_test 1.1 {
do_execsql_test $tn.1.1 {
INSERT INTO ft VALUES('Hello world HELLO WORLD hello');
}
do_execsql_test 1.2 {
do_execsql_test $tn.1.2 {
SELECT fts5_test_poslist(ft) FROM ft('hello');
} {{0.0.0 0.0.2 0.0.4}}
do_execsql_test 1.3 {
do_execsql_test $tn.1.3 {
SELECT
insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
@@ -54,7 +63,15 @@ foreach_detail_mode $testprefix {
FROM ft('hello');
} {hello.Hello hello.HELLO hello}
do_execsql_test 1.4 {
do_execsql_test $tn.1.3.1 {
SELECT
insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
insttoken(ft, 2, 0)
FROM ft('hel*');
} {hello.Hello hello.HELLO hello}
do_execsql_test $tn.1.4 {
SELECT
insttoken(ft, 0, 0),
insttoken(ft, 1, 0),
@@ -62,7 +79,7 @@ foreach_detail_mode $testprefix {
FROM ft('hello') ORDER BY rank;
} {hello.Hello hello.HELLO hello}
do_execsql_test 1.5 {
do_execsql_test $tn.1.5 {
CREATE VIRTUAL TABLE ft2 USING fts5(
x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%
);
@@ -71,11 +88,11 @@ foreach_detail_mode $testprefix {
INSERT INTO ft2(rowid, x) VALUES(3, 'THREE one two three THREE');
}
do_execsql_test 1.6 {
do_execsql_test $tn.1.6 {
SELECT insttoken(ft2, 0, 0), rowid FROM ft2('three') ORDER BY rank;
} {three.THREE 3 three 1 three 2}
do_execsql_test 1.7 {
do_execsql_test $tn.1.7 {
INSERT INTO ft2(rowid, x) VALUES(10, 'aaa bbb BBB');
INSERT INTO ft2(rowid, x) VALUES(12, 'bbb bbb bbb');
INSERT INTO ft2(rowid, x) VALUES(13, 'bbb bbb bbb');
@@ -92,9 +109,32 @@ foreach_detail_mode $testprefix {
INSERT INTO ft2(rowid, x) VALUES(24, 'aaa bbb BBB');
}
do_execsql_test 1.8 { SELECT rowid FROM ft2('aaa AND bbb'); } {10 24}
do_execsql_test 1.9 { SELECT rowid FROM ft2('bbb AND aaa'); } {10 24}
do_execsql_test $tn.1.8 { SELECT rowid FROM ft2('aaa AND bbb'); } {10 24}
do_execsql_test $tn.1.9 { SELECT rowid FROM ft2('bbb AND aaa'); } {10 24}
do_execsql_test $tn.2.0 {
CREATE VIRTUAL TABLE ft3 USING fts5(
x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%,
prefix=2
);
}
do_execsql_test $tn.2.1 {
INSERT INTO ft3(rowid, x) VALUES(1, 'one');
INSERT INTO ft3(rowid, x) VALUES(2, 'ONE');
INSERT INTO ft3(rowid, x) VALUES(3, 'ONT');
INSERT INTO ft3(rowid, x) VALUES(4, 'on');
INSERT INTO ft3(rowid, x) VALUES(5, 'On');
}
do_execsql_test $tn.2.2 {
SELECT rowid FROM ft3('on*');
} {1 2 3 4 5}
do_execsql_test $tn.2.3 {
SELECT rowid, insttoken(ft3, 0, 0) FROM ft3('on*');
} {1 one 2 one.ONE 3 ont.ONT 4 on 5 on.On}
}
}
finish_test
+209
View File
@@ -0,0 +1,209 @@
# 2014 Jan 08
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests focused on phrase queries.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5origintext6
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
proc insert_data {tbl} {
db eval "
INSERT INTO $tbl (rowid, x, y) VALUES
(1, 'ChH BDd HhG efc BjJ BGi GBG FdD','ciJ AFf ADf fBJ fhC GFI JEH fcA'),
(2, 'deg AIG Fie jII cCd Hbf igF fEE','GeA Ija gJg EDc HFi DDI dCf aDd'),
(3, 'IJC hga deC Jfa Aeg hfh CcH dfb','ajD hgC Jaf IfH CHe jIG AjD adF'),
(4, 'FiH GJH IDA AiG bBc CGG Eih bIH','hHg JaH aii IHE Ggd gcH gji CGc'),
(5, 'ceg CAd jFI GAB BGg EeC IdH acG','bBC eIG ifH eDE Adj bjb GCj ebA'),
(6, 'Eac Fbh aFF Eea jeG EIj HCc JJH','hbd giE Gfe eiI dEF abE cJf cAb'),
(7, 'dic hAc jEC AiG FEF jHc HiD HBI','aEd ebE Gfi AJG EBA faj GiG jjE'),
(8, 'Fca iEe EgE jjJ gce ijf EGc EBi','gaI dhH bFg CFc HeC CjI Jfg ccH'),
(9, 'cfd iaa HCf iHJ HjG ffh ABb ibi','CfG bia Dai eii Ejg Jeg fCg hDb'),
(10, 'Jjf hJC IID HJj bGB EbJ cgg eBj','jci jhi JAF jIg Bei Bcd cAC AJd'),
(11, 'egG Cdi bFf fEB hfH jDH jia Efd','FAd eCg fAi aiC baC eJG acF iGE'),
(12, 'Ada Gde CJI ADG gJA Cbb ccF iAB','eAE ajC FBB ccd Jgh fJg ieg hGE'),
(13, 'gBb fDG Jdd HdD fiJ Bed Cig iGg','heC FeI iaj gdg ebB giC HaD FIe'),
(14, 'FiI iDd Ffe igI bgB EJf FHG hDF','cjC AeI abf Fah cbJ ffH jEb aib'),
(15, 'jaF hBI jIH Gdh FEc Fij hgj jFh','dGA ADH feh AAI AfJ DbC gBi hGH'),
(16, 'gjH BGg iGj aFE CAH edI idf HEH','hIf DDg fjB hGi cHF BCH FjG Bgd'),
(17, 'iaI JGH hji gcj Dda eeG jDd CBi','cHg jeh caG gIc feF ihG hgJ Abj'),
(18, 'jHI iDB eFf AiH EFB CDb IAj GbC','Ghe dEI gdI jai gib dAG BIa djb'),
(19, 'abI fHG Ccf aAc FDa fiC agF bdB','afi hde IgE bGF cfg DHD diE aca'),
(20, 'IFh eDJ jfh cDg dde JGJ GAf fIJ','IBa EfH faE aeI FIF baJ FGj EIH'),
(21, 'Dee bFC bBA dEI CEj aJI ghA dCH','hBA ddA HJh dfj egI Dij dFE bGE'),
(22, 'JFE BCj FgA afc Jda FGD iHJ HDh','eAI jHe BHD Gah bbD Bgj gbh eGB'),
(23, 'edE CJE FjG aFI edA Cea FId iFe','ABG jcA ddj EEc Dcg hAI agA biA'),
(24, 'AgE cfc eef cGh aFB DcH efJ hcH','eGF HaB diG fgi bdc iGJ FGJ fFB'),
(25, 'aCa AgI GhC DDI hGJ Hgc Gcg bbG','iID Fga jHa jIj idj DFD bAC AFJ'),
(26, 'gjC JGh Fge faa eCA iGG gHE Gai','bDi hFE BbI DHD Adb Fgi hCa Hij'),
(27, 'Eji jEI jhF DFC afH cDh AGc dHA','IDe GcA ChF DIb Bif HfH agD DGh'),
(28, 'gDD AEE Dfg ICf Cbi JdE jgH eEi','eEb dBG FDE jgf cAI FaJ jaA cDd'),
(29, 'cbe Gec hgB Egi bca dHg bAJ jBf','EFB DgD GJc fDb EeE bBA GFC Hbe'),
(30, 'Adc eHB afI hDc Bhh baE hcJ BBd','JAH deg bcF Dab Bgj Gbb JHi FIB'),
(31, 'agF dIj AJJ Hfg cCG hED Igc fHC','JEf eia dHf Ggc Agj geD bEE Gei'),
(32, 'DAd cCe cbJ FjG gJe gba dJA GCf','eAf hFc bGE ABI hHA IcE abF CCE'),
(33, 'fFh jJe DhJ cDJ EBi AfD eFI IhG','fEG GCc Bjd EFF ggg CFe EHd ciB'),
(34, 'Ejb BjI eAF HaD eEJ FaG Eda AHC','Iah hgD EJG fdD cIE Daj IFf eJh'),
(35, 'aHG eCe FjA djJ dAJ jiJ IaE GGB','Acg iEF JfB FIC Eei ggj dic Iii'),
(36, 'Fdb EDF GaF JjB ehH IgC hgi DCG','cag DHI Fah hAJ bbh egG Hia hgJ'),
(37, 'HGg icC JEC AFJ Ddh dhi hfC Ich','fEg bED Bff hCJ EiA cIf bfG cGA'),
(38, 'aEJ jGI BCi FaA ebA BHj cIJ GcC','dCH ADd bGB cFE AgF geD cbG jIc'),
(39, 'JFB bBi heA BFA hgB Ahj EIE CgI','EIJ JFG FJE GeA Hdg HeH ACh GiA'),
(40, 'agB DDC CED igC Dfc DhI eiC fHi','dAB dcg iJF cej Fcc cAc AfB Fdd'),
(41, 'BdF DHj Ege hcG DEd eFa dCf gBb','FBG ChB cej iGd Hbh fCc Ibe Abh'),
(42, 'Bgc DjI cbC jGD bdb hHB IJA IJH','heg cii abb IGf eDe hJc dii fcE'),
(43, 'fhf ECa FiA aDh Jbf CiB Jhe ajD','GFE bIF aeD gDE BIE Jea DfC BEc'),
(44, 'GjE dBj DbJ ICF aDh EEH Ejb jFb','dJj aEc IBg bEG Faf fjA hjf FAF'),
(45, 'BfA efd IIJ AHG dDF eGg dIJ Gcb','Bfj jeb Ahc dAE ACH Dfb ieb dhC'),
(46, 'Ibj ege geC dJh CIi hbD EAG fGA','DEb BFe Bjg FId Fhg HeF JAc BbE'),
(47, 'dhB afC hgG bEJ aIe Cbe iEE JCD','bdg Ajc FGA jbh Jge iAj fIA jbE'),
(48, 'egH iDi bfH iiI hGC jFF Hfd AHB','bjE Beb iCc haB gIH Dea bga dfd'),
(49, 'jgf chc jGc Baj HBb jdE hgh heI','FFB aBd iEB EIG HGf Bbj EIi JbI'),
(50, 'jhe EGi ajA fbH geh EHe FdC bij','jDE bBC gbH HeE dcH iBH IFE AHi'),
(51, 'aCb JiD cgJ Bjj iAI Hbe IAF FhH','ijf bhE Jdf FED dCH bbG HcJ ebH');
"
}
foreach_detail_mode $testprefix {
foreach external {0 1 2} {
reset_db
proc tokens {cmd} {
set ret [list]
for {set iTok 0} {$iTok < [$cmd xInstCount]} {incr iTok} {
set txt [$cmd xInstToken $iTok 0]
set txt [string map [list "\0" "."] $txt]
lappend ret $txt
}
set ret
}
sqlite3_fts5_create_function db tokens tokens
sqlite3_fts5_register_origintext db
set E(0) internal
set E(1) external
set E(2) contentless
set e $E($external)
db eval { CREATE TABLE ex(x, y) }
switch -- $external {
0 {
do_execsql_test 1.$e.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%
);
}
}
1 {
do_execsql_test 1.$e.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%,
content=ex
);
}
}
2 {
do_execsql_test 1.$e.0 {
CREATE VIRTUAL TABLE ft USING fts5(
x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%,
content=
);
}
}
}
insert_data ex
insert_data ft
proc prefixquery {prefix bInst bYOnly} {
set ret [list]
db eval { SELECT rowid, x, y FROM ex ORDER BY rowid } {
set row [list]
set bSeen 0
set T [concat $x $y]
if {$bYOnly} { set T $y }
foreach w $T {
if {[string match -nocase $prefix $w]} {
set bSeen 1
if {$bInst} {
set v [string tolower $w]
if {$w != $v} { append v ".$w" }
lappend row $v
}
}
}
if {$bSeen} {
lappend ret $rowid
lappend ret $row
}
}
set ret
}
proc do_prefixquery_test {tn prefix} {
set bInst [expr {$::e!="contentless" || "%DETAIL%"=="full"}]
set expect [prefixquery $prefix $bInst 0]
set expect2 [prefixquery $prefix $bInst 1]
uplevel [list do_execsql_test $tn.1 "
SELECT rowid, tokens(ft) FROM ft('$prefix')
" $expect]
uplevel [list do_execsql_test $tn.2 "
SELECT rowid, tokens(ft) FROM ft(fts5_insttoken('$prefix'))
" $expect]
db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 1) }
uplevel [list do_execsql_test $tn.3 "
SELECT rowid, tokens(ft) FROM ft('$prefix')
" $expect]
db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 0) }
if {"%DETAIL%"!="none"} {
uplevel [list do_execsql_test $tn.4 "
SELECT rowid, tokens(ft) FROM ft('y: $prefix')
" $expect2]
uplevel [list do_execsql_test $tn.5 "
SELECT rowid, tokens(ft) FROM ft(fts5_insttoken('y: $prefix'))
" $expect2]
db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 1) }
uplevel [list do_execsql_test $tn.6 "
SELECT rowid, tokens(ft) FROM ft('y: $prefix')
" $expect2]
db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 0) }
}
}
do_prefixquery_test 1.$e.1 a*
do_prefixquery_test 1.$e.2 b*
do_prefixquery_test 1.$e.3 c*
do_prefixquery_test 1.$e.4 d*
do_prefixquery_test 1.$e.5 e*
do_prefixquery_test 1.$e.6 f*
do_prefixquery_test 1.$e.7 g*
do_prefixquery_test 1.$e.8 h*
do_prefixquery_test 1.$e.9 i*
do_prefixquery_test 1.$e.10 j*
}}
finish_test
+105
View File
@@ -0,0 +1,105 @@
# 2014 Jan 08
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests focused on phrase queries.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5tokendata
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $testprefix {
sqlite3_fts5_register_origintext db
fts5_aux_test_functions db
proc b {x} { string map [list "\0" "."] $x }
db func b b
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ft USING fts5(a, b, tokendata=1,
tokenize="origintext unicode61", detail=%DETAIL%
);
CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance);
}
do_execsql_test 1.1 {
INSERT INTO ft(rowid, a, b) VALUES
(1, 'Pedagog Pedal Pedant', 'Peculier Day Today'),
(2, 'Pedant pedantic pecked', 'Peck Penalize Pen');
INSERT INTO ft(rowid, a, b) VALUES
(3, 'Penalty Pence Penciled', 'One Two Three'),
(4, 'Pedant Pedal Pedant', 'Peculier Day Today');
}
do_execsql_test 1.2 {
SELECT DISTINCT b(term) FROM vocab
} {
day.Day one.One peck.Peck pecked peculier.Peculier pedagog.Pedagog
pedal.Pedal pedant.Pedant pedantic pen.Pen penalize.Penalize
penalty.Penalty pence.Pence penciled.Penciled three.Three
today.Today two.Two
}
do_execsql_test 1.3.1 {
SELECT rowid FROM ft('pe*')
} {
1 2 3 4
}
do_execsql_test 1.3.2 {
SELECT rowid FROM ft('pe*') ORDER BY rowid DESC
} {
4 3 2 1
}
if {"%DETAIL%"!="none"} {
do_execsql_test 1.3.3 {
SELECT rowid FROM ft WHERE a MATCH 'pe*' ORDER BY rowid DESC
} {
4 3 2 1
}
}
do_execsql_test 1.4 {
SELECT rowid, b( fts5_test_insttoken(ft, 0, 0) ) FROM ft('pedant')
} {
1 pedant.Pedant
2 pedant.Pedant
4 pedant.Pedant
}
do_execsql_test 1.5 {
SELECT rowid, b( fts5_test_insttoken(ft, 0, 0) ) FROM ft('pe*')
} {
1 pedagog.Pedagog
2 pedant.Pedant
3 penalty.Penalty
4 pedant.Pedant
}
do_execsql_test 1.6 {
SELECT rowid, fts5_test_poslist(ft) FROM ft('pe*')
} {
1 {0.0.0 0.0.1 0.0.2 0.1.0}
2 {0.0.0 0.0.1 0.0.2 0.1.0 0.1.1 0.1.2}
3 {0.0.0 0.0.1 0.0.2}
4 {0.0.0 0.0.1 0.0.2 0.1.0}
}
}
finish_test
-12
View File
@@ -350,17 +350,5 @@ do_execsql_test 11.1 {
INSERT INTO t4 VALUES( str('') );
}
do_test 12.0 {
sqlite3_fts5_tokenize db trigram "abcd"
} {abc 0 3 bcd 1 4}
do_test 12.1 {
sqlite3_fts5_tokenize db trigram "a"
} {}
do_test 12.2 {
sqlite3_fts5_tokenize db trigram ""
} {}
finish_test
+12 -35
View File
@@ -148,20 +148,10 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
#ifndef SQLITE_USE_STDIO_FOR_CONSOLE
DWORD nRead = 0;
if( IsConsole(in)
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
){
b1[nRead] = 0;
}else
#endif
{
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
sqlite3_free(b1);
return 0;
}
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
sqlite3_free(b1);
return 0;
}
WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
sqlite3_free(b1);
@@ -217,33 +207,20 @@ int sqlite3_fputs(const char *z, FILE *out){
** any translation. */
return fputs(z, out);
}else{
/* One must use UTF16 in order to get unicode support when writing
** to the console on Windows.
/* When writing to the command-prompt in Windows, it is necessary
** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
** use O_U8TEXT for everything in text mode.
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
#ifndef SQLITE_STDIO_FOR_CONSOLE
DWORD nWr = 0;
if( IsConsole(out)
&& WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
){
/* If writing to the console, then the WriteConsoleW() is all we
** need to do. */
}else
#endif
{
/* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
** then write using the standard library. */
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
}
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
}
sqlite3_free(b1);
return 0;
+2 -19
View File
@@ -624,16 +624,6 @@ static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
** Shared-memory operations.
*/
static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
static const char *azLockName[] = {
"WRITE",
"CKPT",
"RECOVER",
"READ0",
"READ1",
"READ2",
"READ3",
"READ4",
};
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
@@ -647,15 +637,8 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
if( flags & ~(0xf) ){
sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
}
if( ofst>=0 && ofst<sizeof(azLockName)/sizeof(azLockName[0]) ){
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst, azLockName[ofst],
n, &zLck[1]);
}else{
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst,
n, &zLck[1]);
}
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
+1 -53
View File
@@ -525,6 +525,7 @@ do_test 7.1 {
} {1 {file is not a database}}
reset_db
breakpoint
do_test 8.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
@@ -551,58 +552,5 @@ do_test 8.1 {
list [catch { $R finish } msg] $msg
} {0 {}}
reset_db
do_test 9.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 16384 pagesize 4096t 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 ........
| 32: 00 00 00 0r 00 00 00 00 00 00 00 06 00 00 00 04 ..
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ........
| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a .......j
| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .
| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..tablet
| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6econ
| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45
| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 )
| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WOWID^..
| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 6tt_d
| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a z
| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.ABLE '
| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20id
| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20
| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEYB)]..
| 3744: 17 23 23 01 81 B1 74 61 62 6c 65 74 74 74 5f 63 _c
| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e o_conten
| 3776: 7 04 01 03 00 011 54 45 20 54 41 42 4c 45 20 27 t.CRLE '
| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20
| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INIMARY
| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 7EY(s
| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 T
| 3936: 48 4f 55 54 20 52 4f 57 49 4 58 58 02 07 17 1d 1d ..
| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 .tt_data
| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 2ATE
| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 '
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (iR PRIM
| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42k B
| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c
| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettTE VI
| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 t
| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 U5(a, b)
| page 4 offset 12288
| 0: 0a 00 00 00 03 0f ea 00 0f fa 0f f2 0f ea 00 00 ........
| 4064: 00 00 00 00 00 00 00 00 00 00 07 04 01 01 01 05 ..
| 4080: 06 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02 ........
| end ro2.t
}]} {}
do_test 9.1 {
set R [sqlite3_recover_init db main test.db2]
catch { $R run }
list [catch { $R finish } msg] $msg
} {0 {}}
finish_test
-2
View File
@@ -1825,8 +1825,6 @@ static int recoverWriteDataStep(sqlite3_recover *p){
recoverError(p, SQLITE_NOMEM, 0);
}
p1->nVal = iField+1;
}else if( pTab->nCol==0 ){
p1->nVal = pTab->nCol;
}
p1->iPrevCell = iCell;
p1->iPrevPage = iPage;
+38 -96
View File
@@ -263,48 +263,17 @@ all: sqlite3.h sqlite3.c
########################################################################
########################################################################
#
# $(CFLAGS.env) holds the any $(CFLAGS) provided at configure- or
# make-time (the latter overriding the former).
#
# $(CFLAGS) should ideally only contain flags which are relevant for
# all binaries built for the target platform. However, many people
# like to pass it to "make" without realizing that it applies to
# dozens of deliverables, and they override core flags (like -fPIC)
# when doing so. To help work around that, we expect all core-most
# CFLAGS, e.g. -fPIC, to be set in $(CFLAGS.core). That enables people
# to pass their other CFLAGS without triggering, e.g., "recompile with
# -fPIC" errors.
#
# Historical note: the pre-3.48 build does not honor CPPFLAGS passed
# to make, so we do not do so here. Both the legacy and 3.48+ builds
# support CPPFLAGS passed at configure-time, and combines them with
# the configure-time CFLAGS.
# dozens of apps, and they override core flags when doing so. To help
# work around that, we expect core-most CFLAGS (only), e.g. -fPIC, to
# be set in $(CFLAGS.core). That enables people to pass their other
# CFLAGS without triggering, e.g., "recompile with -fPIC" errors.
#
CFLAGS.core ?=
CFLAGS.env = $(CFLAGS)
T.cc += $(CFLAGS.core) $(CFLAGS.env)
#
# $(LDFLAGS.configure) represents any LDFLAGS=... the client passes to
# the configure process. The historical build enabled passing-on of
# user-provided LDFLAGS at configure-time but not make-time. That
# behavior is not possible to fully emulate here because this makefile
# is not filtered by the configure script, so we instead
# "soft-enforce" it by using a level of indirection, which clients who
# read this can (but are not advised to!) bypass by passing
# LDFLAGS.configure=... to this makefile. (We do not guaranty this
# variable name to be stable, so do not rely on that capability!)
#
# A significant difference from the legacy build:
#
# The legacy build applied such LDFLAGS to all link operations for all
# deliverables. The 3.48+ build applies them (as of this writing) more
# selectively: search this file LDFLAGS.configure to see where they're
# set. As of this writing, they only affect targets which use
# $(LDFLAGS.libsqlite3) - see that var's docs for details.
#
LDFLAGS.configure ?=
T.cc += $(CFLAGS.core) $(CFLAGS)
#
# The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the
@@ -377,8 +346,8 @@ T.link = $(T.cc.sqlite) $(T.link.extras)
T.link.shared = $(T.link) $(LDFLAGS.shobj)
#
# $(LDFLAGS.libsqlite3) should be used with any deliverable for which
# any of the following apply:
# LDFLAGS.libsqlite3 should be used with any deliverable for which any
# of the following apply:
#
# - Results in building libsqlite3.so
# - Compiles sqlite3.c in to an application
@@ -392,8 +361,7 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj)
LDFLAGS.libsqlite3 = \
$(LDFLAGS.rpath) $(LDFLAGS.pthread) \
$(LDFLAGS.math) $(LDFLAGS.dlopen) \
$(LDFLAGS.zlib) $(LDFLAGS.icu) \
$(LDFLAGS.configure)
$(LDFLAGS.zlib) $(LDFLAGS.icu)
#
# $(install-dir.XYZ) = dirs for installation.
@@ -457,7 +425,6 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) $(TOP)/auto.def
@if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi
@if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi
@if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi
@if [ x = "x$(PACKAGE_VERSION)" ]; then echo "PACKAGE_VERSION must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi
@if [ x = "x$(B.cc)" ]; then echo "Missing B.cc var" 1>&2; exit 1; fi
@if [ x = "x$(T.cc)" ]; then echo "Missing T.cc var" 1>&2; exit 1; fi
@if [ x = "x$(B.tclsh)" ]; then echo "Missing B.tclsh var" 1>&2; exit 1; fi
@@ -981,8 +948,8 @@ T.tcl.env.sh = ./.tclenv.sh
$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST)
@if [ x = "x$(TCL_CONFIG_SH)" ]; then \
echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \
fi; \
if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \
fi
@if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \
ld= ; \
for d in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \
if [ -d "$$d" ]; then ld=$$d; break; fi; \
@@ -990,8 +957,7 @@ $(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST)
if [ x = "x$$ld" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \
echo "TCLLIBDIR=$$ld/sqlite3"; \
fi > $@; \
echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@; \
echo "Created $@"
echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@
#
# $(T.tcl.env.source) is shell code to be run as part of any
@@ -1006,7 +972,7 @@ T.tcl.env.source = . $(T.tcl.env.sh) || exit $$?
# and $(T.link) which first invoke $(T.tcl.env.source). Any targets which used them
# must have a dependency on $(T.tcl.env.sh)
#
T.compile.tcl = $(T.tcl.env.source); $(T.compile) $(CFLAGS.intree_includes)
T.compile.tcl = $(T.tcl.env.source); $(T.compile)
T.link.tcl = $(T.tcl.env.source); $(T.link)
#
@@ -1323,7 +1289,7 @@ window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON)
$(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c
tclsqlite.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON)
$(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC \
$(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC $(CFLAGS.intree_includes) \
-c $(TOP)/src/tclsqlite.c
tclsqlite-shell.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON)
@@ -1334,11 +1300,7 @@ tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON)
tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO)
$(T.link.tcl) -o $@ tclsqlite-shell.o \
$(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC \
$(LDFLAGS.libsqlite3)
tclsqlite3$(T.exe)-1: tclsqlite3$(T.exe)
tclsqlite3$(T.exe)-0 tclsqlite3$(T.exe)-:
tcl: tclsqlite3$(T.exe)-$(HAVE_TCL)
$(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
# Rules to build opcodes.c and opcodes.h
#
@@ -1481,9 +1443,6 @@ install: install-headers
#
pkgIndex.tcl:
echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@
pkgIndex.tcl-1: pkgIndex.tcl
pkgIndex.tcl-0 pkgIndex.tcl-:
tcl: pkgIndex.tcl-$(HAVE_TCL)
libtclsqlite3.SO = libtclsqlite3$(T.dll)
$(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ)
$(T.tcl.env.source); \
@@ -1496,8 +1455,7 @@ $(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ)
$(libtclsqlite3.SO)-1: $(libtclsqlite3.SO)
$(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-:
libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL)
tcl: libtcl
all: tcl
all: libtcl
install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl
$(T.tcl.env.source); \
@@ -1505,7 +1463,6 @@ install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl
$(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$TCLLIBDIR"; \
$(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$TCLLIBDIR"
install-tcl-0 install-tcl-:
@echo "TCL support disabled, so not installing $(libtclsqlite3.SO)"
install-tcl: install-tcl-$(HAVE_TCL)
install: install-tcl
@@ -1515,10 +1472,7 @@ tclsqlite3.c: sqlite3.c
echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
#
# $(CFLAGS.tclextension) = CFLAGS for the tclextension* targets.
#
CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS.env) $(OPT_FEATURE_FLAGS) $(OPTS)
CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS)
#
# Build the SQLite TCL extension in a way that make it compatible
# with whatever version of TCL is running as $TCLSH_CMD, possibly defined
@@ -1732,8 +1686,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c
$(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \
$(LDFLAGS.libsqlite3)
$(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $(LDFLAGS.libsqlite3)
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \
$(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \
@@ -1741,15 +1694,14 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c
$(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) \
$$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
$(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
# xbin: target for generic binaries which aren't usually built. It is
# used primarily for testing the build process.
xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe)
xbin: sqltclsh$(T.exe)
sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/expert.c sqlite3.c
$(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3)
xbin: sqlite3_expert$(T.exe)
@@ -1767,17 +1719,16 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@
sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c
$(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC \
$(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
$(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
xbin: sqlite3_checker$(T.exe)
dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o
$(T.link) -DDBDUMP_STANDALONE -o $@ \
$(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3)
$(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3)
xbin: dbdump$(T.exe)
dbtotxt$(T.exe): $(TOP)/tool/dbtotxt.c
$(T.link)-o $@ $(TOP)/tool/dbtotxt.c $(LDFLAGS.configure)
$(T.link)-o $@ $(TOP)/tool/dbtotxt.c
xbin: dbtotxt$(T.exe)
showdb$(T.exe): $(TOP)/tool/showdb.c sqlite3.o
@@ -1797,23 +1748,20 @@ showwal$(T.exe): $(TOP)/tool/showwal.c sqlite3.o
xbin: showwal$(T.exe)
showshm$(T.exe): $(TOP)/tool/showshm.c
$(T.link) -o $@ $(TOP)/tool/showshm.c $(LDFLAGS.configure)
$(T.link) -o $@ $(TOP)/tool/showshm.c
xbin: showshm$(T.exe)
index_usage$(T.exe): $(TOP)/tool/index_usage.c sqlite3.o
$(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o \
$(LDFLAGS.libsqlite3)
$(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3)
xbin: index_usage$(T.exe)
# Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION
changeset$(T.exe): $(TOP)/ext/session/changeset.c sqlite3.o
$(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o \
$(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3)
xbin: changeset$(T.exe)
changesetfuzz$(T.exe): $(TOP)/ext/session/changesetfuzz.c sqlite3.o
$(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o \
$(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3)
xbin: changesetfuzz$(T.exe)
rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o
@@ -1825,7 +1773,7 @@ atrc$(T.exe): $(TOP)/test/atrc.c sqlite3.o
xbin: atrc$(T.exe)
LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h
$(T.link) -I. -o $@ $(TOP)/tool/logest.c $(LDFLAGS.configure)
$(T.link) -I. -o $@ $(TOP)/tool/logest.c
xbin: LogEst$(T.exe)
wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o
@@ -1833,20 +1781,17 @@ wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o
xbin: wordcount$(T.exe)
speedtest1$(T.exe): $(TOP)/test/speedtest1.c sqlite3.c Makefile
$(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c \
$(LDFLAGS.libsqlite3)
$(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3)
xbin: speedtest1$(T.exe)
startup$(T.exe): $(TOP)/test/startup.c sqlite3.c
$(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 \
-o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3)
$(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3)
xbin: startup$(T.exe)
KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c
$(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c \
$(LDFLAGS.libsqlite3)
$(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3)
xbin: kvtest$(T.exe)
#
@@ -1857,8 +1802,7 @@ rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
$(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3)
loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB)
$(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) \
-o $@ $(LDFLAGS.libsqlite3)
$(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3)
xbin: loadfts$(T.exe)
# This target will fail if the SQLite amalgamation contains any exported
@@ -1904,8 +1848,7 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_lookaside1.c
threadtest3$(T.exe): sqlite3.o $(THREADTEST3_SRC)
$(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o \
-o $@ $(LDFLAGS.libsqlite3)
$(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest3$(T.exe)
threadtest: threadtest3$(T.exe)
@@ -1965,7 +1908,7 @@ install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin)
#install: install-rsync
install-man1: $(install-dir.man1)
$(INSTALL.noexec) "$(TOP)/sqlite3.1" "$(install-dir.man1)"
$(INSTALL.noexec) $(TOP)/sqlite3.1 "$(install-dir.man1)"
install: install-man1
#
@@ -1995,7 +1938,7 @@ verify-source: ./src-verify$(B.exe)
fuzzershell$(T.exe): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(FUZZERSHELL_OPT) \
$(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3)
$(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: fuzzershell$(T.exe)
xbin: fuzzershell$(T.exe)
@@ -2033,7 +1976,7 @@ run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe)
ossshell$(T.exe): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
$(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
$(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: ossshell$(T.exe)
xbin: ossshell$(T.exe)
@@ -2042,8 +1985,7 @@ sessionfuzz$(T.exe): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
fuzzy: sessionfuzz$(T.exe)
dbfuzz$(T.exe): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c \
$(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: dbfuzz$(T.exe)
xbin: dbfuzz$(T.exe)
@@ -2185,7 +2127,7 @@ sqlite3.def: $(LIBOBJ)
sqlite3.dll: $(LIBOBJ) sqlite3.def
$(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \
-Wl,"--strip-all" $(LIBOBJ) $(LDFLAGS.configure)
-Wl,"--strip-all" $(LIBOBJ)
#
# Emit a list of commonly-used targets
+45 -41
View File
@@ -1,9 +1,9 @@
C Fix\sa\sstate\smakefile\sdependency\swhich\srefered\sto\sthe\snow-removed\ssqlite_cfg.h.in.
D 2024-11-14T16:00:45.775
C Update\sdocumentation\sin\sfts5.h.
D 2024-11-26T20:16:34.989
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
F Makefile.in d941328627467c1bc2f13861b0bf5dc1e0c4669c072eec20b37285777f41d289
F Makefile.in 3a54957d16c3f4666922f170a19b4b51dc13be039c29394dd38caa95ade5d731
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
@@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F auto.def 7dbe7bebe9c3bea4de674053339964b4b26cff5e2fdc20948acc723b5080bffd
F auto.def 05eedbf203a070fc84d9d26071f7ddf2a30f2118ab0204db46e91dbfec8a50b8
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
@@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0
F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd
F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4
F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e
F autosetup/README.md f12fd1556b50ff33ebf5c1476f4640c6010b3093ba8d75ba12b5417884011d5e
F autosetup/README.md 78f434bc13029a7ddf4d62fb0c82216f1dceaee448239022a1ce49230925b4c9
F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x
F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x
F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x
@@ -47,10 +47,13 @@ F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034
F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360
F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78
F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f
F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82
F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
F autosetup/proj.tcl 9772d3f89634089add92e2238551a59a5c764d501327f6eb433dca7f98138802
F autosetup/proj.tcl 504fb46e15a0c6b4b161484a0a24f62b9c165fb901d189c0e523d9a93f1b24c2
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f
F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
@@ -76,7 +79,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 9f8ce82bbf4ec0636e6170e58f17b04817fa4c39b2d5126ac06f005d485f6d5e
F ext/fts3/fts3.c 59ae8c42ed3c39478faa6d122687e467ac34c98a63282e834f7df9cb5076c450
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682
F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
@@ -103,20 +106,20 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7ede551eac3ead62baa
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15
F ext/fts5/fts5.h 6b4b92df890965567360db5f1ead24fd13a72cb23b95e4ed2ff58d1d89f7aa42
F ext/fts5/fts5Int.h bf0d3efa144f36e00f9b5206626aec2f436f58186a0835092394f2202e9828e3
F ext/fts5/fts5.h df1741b4dbf8446f663ba30ce6eca51ef1cef0dbc481806273fc8a0cc159f4b8
F ext/fts5/fts5Int.h 6abff7dd770dc5969c994c281e6e77fc277ce414d56cc4a62c145cc7036b0b67
F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
F ext/fts5/fts5_config.c a6633d88596758941c625b526075b85d3d9fd1089d8d9eab5db6e8a71fd347ad
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8
F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6
F ext/fts5/fts5_main.c 0b60324001e26d79e8a12e544883792f59a58717f6dce9fb1f8878f0e0196530
F ext/fts5/fts5_index.c cef6791bd9f9db4305494292d6dd5d24a7379aabf370a4d6b559e16b740fa88e
F ext/fts5/fts5_main.c b2ec6bf97fc378906c0e78c61f10ca8e64f15e03237f2521f7d81736983be378
F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c
F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329
F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
F ext/fts5/fts5_tokenize.c 87ab719f0556172da3414f1741c11bb4d333ebecde157945a55478bfe6e46c44
F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9
F ext/fts5/fts5_unicode2.c 6f9b0fb79a8facaed76628ffd4eb9c16d7f2b84b52872784f617cf3422a9b043
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0
@@ -212,11 +215,12 @@ F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618
F ext/fts5/test/fts5optimize.test 264b9101721c17d06d1d174feb743fda3ddc89fad41dee980fef821428258e47
F ext/fts5/test/fts5optimize2.test 795d4ae5f66a7239cf8d5aef4c2ea96aeb8bcd907bd9be0cfe22064fc71a44ed
F ext/fts5/test/fts5optimize3.test 1653029284e10e0715246819893ba30565c4ead0d0fc470adae92c353ea857d3
F ext/fts5/test/fts5origintext.test 2015f69bc8abd111152a8e66211fd2d45026378001e07c054159aa4f84e6691d
F ext/fts5/test/fts5origintext.test 3b73aa036ce5244bb7c5782c5441b979585bdca026accf75d16026a2a8119c09
F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b37f29cad3a8b8d5ac6f9ba
F ext/fts5/test/fts5origintext3.test 45c33cf0c91a9ca0e36d298462db3edc7c8fe45fd185649a9dbfd66bb670058b
F ext/fts5/test/fts5origintext3.test 4988b6375acc3bbb0515667765f57e389caf449814af9c1095c053f7de2b4223
F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8
F ext/fts5/test/fts5origintext5.test ee12b440ec335e5b422d1668aca0051b52ff28b6ee67073e8bbc29f509fd562b
F ext/fts5/test/fts5origintext6.test 09eb1347cb0dceaebbebf3d3e6bd5d24c7c1006efddc2984540450324bbdafa4
F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c
F ext/fts5/test/fts5plan.test f8b0d752a818059a934cdc96c0f77de058a67a0a57bb3a8181d28307ab5b1626
F ext/fts5/test/fts5porter.test 15b514fac8690b58e99c330efe5bf5615bc43f2fae4a3cca3f923dbaff55a0c0
@@ -245,10 +249,11 @@ F ext/fts5/test/fts5synonym.test becc8cea6cfc958a50b30c572c68cbfdf7455971d0fe988
F ext/fts5/test/fts5synonym2.test 58f357b997cf2fedeeb9d0de4db9f880fa96fa2fe27a743bfe7d7b96895bdd87
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
F ext/fts5/test/fts5tokendata.test 7cad79af82e8e81b7a36b450087233d2fca051bb0d584421afc375d6dd26d6f6
F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98
F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6
F ext/fts5/test/fts5tokenizer3.test eea778f7bb7024c3e904e28915f9d53286141671b138722148be22a9c758bdc3
F ext/fts5/test/fts5trigram.test a55fde7065ae69a0f82c5a7a5bf5286a97de11ae4bff6537fd3e27ca9a01416f
F ext/fts5/test/fts5trigram.test 9927c9e9b35116ea00748c8e41d9cbc2b95a6c90845cd82a59c11fedfd16404a
F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61
F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
@@ -438,7 +443,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f
F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634
F ext/misc/sqlite3_stdio.c 5657afb6ec81bef31790973528980af778e0e1388a93db780d33007336efe6e6
F ext/misc/sqlite3_stdio.c c34b4aba8aec6c1ca7058a7a6319a37ab629135091600aee202390a8cd20e842
F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176
F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321
F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc
@@ -450,7 +455,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d
F ext/misc/vfstrace.c 72b7cda31777173b0ca78c6c92968c17aba635682205945e394fff27b377bb81
F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594accaaca
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
@@ -509,7 +514,7 @@ F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a
F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3
F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e
F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49
F ext/recover/recovercorrupt2.test 7347ccc9c36a925d99b56689c791423b45294834198f17575183fd500f52d85d
F ext/recover/recovercorrupt2.test 1418f1710debc24ff38276cedfcea234beb37a34205708e7e3e6d76cc4a979db
F ext/recover/recovercorrupt3.test 2e7b9a1b528ca23ed382cec6f64e3fcbbd0f8e852add7562397fd8df83f335d5
F ext/recover/recovercorrupt4.test 3e2794145dad2517c018cb68b96f59d4d55b18b3d6271e1d37852cfd7a30b50c
F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1
@@ -519,7 +524,7 @@ F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52
F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
F ext/recover/sqlite3recover.c 788438a6735108d14ca82cf39c59abf8cde2ee384b962fb93e975eb24f2732fe
F ext/recover/sqlite3recover.c e822ecbb05a04a5c85d1309765fcd6cf392d100d02d2227cd7720c9d6921a17a
F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -696,7 +701,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk cd92df46e074ce11466d43530cfe23cef48ac541aee4714181369e3fe92df05a
F main.mk 3dbee6d7e7678b79531b78048fea187146cb7e0352047ed774003ba4df1fb93a
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -706,6 +711,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91
F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532
F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb
F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80
@@ -737,7 +743,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c 9f4286302727f58fddc03a820d24cb7618a1e27473501792fbe979726f846d1f
F src/main.c f6daba376adac080fe9287c6746fb15e12c7e47d022f2e9f2986ed364b7e0329
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -758,8 +764,8 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d
F src/os_unix.c c84a3add1e480499261a41d77d3f87d18f27aaebec6376655c177a3886a5b67c
F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
@@ -775,12 +781,12 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
F src/shell.c.in 45e69e4e69576847a5b49aeac624c9ffad5666697ce037d38bc331a56733765f
F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6
F src/shell.c.in bb8ca98e903ea1dc60cee7e0a82017879662a2e4ce1f43889da87e8d4d774a5d
F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1
F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153
@@ -862,7 +868,7 @@ F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b
F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514
F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f
F src/window.c 6c386af5972a58f9a9847bba9d7ca70c4c682391ab8478d94a6e046b22a0dbb3
F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
@@ -1153,7 +1159,6 @@ F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d0
F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c
F test/fork-test.c 9ac2e6423a1d38df3d6be0e8ac15608b545de21e2b19d9d876254c5931b63edb
F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4
F test/fp-speed-1.c b37de94eba034e1703668816225f54510ec60fb0685406608cc707afe6b8234d
F test/fpconv1.test d5d8aa0c427533006c112fb1957cdd1ea68c1d0709470dabb9ca02c2e4c06ad8
@@ -1186,10 +1191,9 @@ F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d
F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57
F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8
F test/fts3corrupt4.test a451033ae31db9c5979a7612dee80fb4f221db104a2eeeabd1c9adcc8e8fe95a
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525
F test/fts3corrupt7.test 1da31776e24bb91d3c028e663456b61280b121a74496ccf2fef3fe33790ad2b0
F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de
@@ -1678,7 +1682,7 @@ F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb
F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb
F test/sqllimits1.test 7fa5027c2686e0a752f9a35616966eabfb9959ce041701b091932692c4bb6448
F test/sqllimits1.test dee96a51b83ef866d06ec3c687d4c951d97b02549facc5be88c9dfcb215b98bf
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/starschema1.test a84205f97fe278a015ac39546c86b97228d22043af28f3a2ef809e8d5637ce1d
F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805
@@ -2066,9 +2070,9 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652
F test/window6.test 311de885bd7e453134fa6747680bfb4a1be87c91720bf58703db945891e7d30b
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl c57364e64d816f6e26df60437e1202e2c1031c7b818a1a67535d1006862a026a
F test/window8.test 3d931e58802b8ab8063da00f0cf30aa3351640238a952c0efb5a129e2349a4bb
F test/window9.test 7b98a7916dd87763ea35f56ea023e3b29e99744582204ccf2937a3bac411cd4d
F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f79c
F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed
F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf
F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2
@@ -2198,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916
R c8ff2644822f8bbab8e63072254a5a68
U stephan
Z 54ae5ab64b4869b51425727dae4b6b51
P 211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa
R ce521c664e19e9b02f777e0b20a87e4f
U dan
Z 1b49bcb3c99dc54eba71f1872e2bcc4a
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216
f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9
+194
View File
@@ -0,0 +1,194 @@
/* sqlite_cfg.h.in - autosetup input template for sqlite_cfg.h. */
/* Define to 1 if you have the <dlfcn.h> header file. */
/*#undef HAVE_DLFCN_H*/
@if HAVE_DLFCN_H
#define HAVE_DLFCN_H @HAVE_DLFCN_H@
@endif
/* Define to 1 if you have the `fdatasync' function. */
/*#undef HAVE_FDATASYNC*/
#define HAVE_FDATASYNC @HAVE_FDATASYNC@
/* Define to 1 if you have the `gmtime_r' function. */
/*#undef HAVE_GMTIME_R*/
#define HAVE_GMTIME_R @HAVE_GMTIME_R@
/* Define to 1 if the system has the type `int16_t'. */
/*#undef HAVE_INT16_T*/
#define HAVE_INT16_T @HAVE_INT16_T@
/* Define to 1 if the system has the type `int32_t'. */
/*#undef HAVE_INT32_T*/
#define HAVE_INT32_T @HAVE_INT32_T@
/* Define to 1 if the system has the type `int64_t'. */
/*#undef HAVE_INT64_T*/
#define HAVE_INT64_T @HAVE_INT64_T@
/* Define to 1 if the system has the type `int8_t'. */
/*#undef HAVE_INT8_T*/
#define HAVE_INT8_T @HAVE_INT8_T@
/* Define to 1 if the system has the type `intptr_t'. */
/*#undef HAVE_INTPTR_T*/
#define HAVE_INTPTR_T @HAVE_INTPTR_T@
/* Define to 1 if you have the <inttypes.h> header file. */
/*#undef HAVE_INTTYPES_H*/
#define HAVE_INTTYPES_H @HAVE_INTTYPES_H@
/* Define to 1 if you have the `isnan' function. */
/*#undef HAVE_ISNAN*/
#define HAVE_ISNAN @HAVE_ISNAN@
/* Define to 1 if you have the `localtime_r' function. */
/*#undef HAVE_LOCALTIME_R*/
#define HAVE_LOCALTIME_R @HAVE_LOCALTIME_R@
/* Define to 1 if you have the `localtime_s' function. */
/*#undef HAVE_LOCALTIME_S*/
#define HAVE_LOCALTIME_S @HAVE_LOCALTIME_S@
/* Define to 1 if you have the <malloc.h> header file. */
/*#undef HAVE_MALLOC_H*/
#define HAVE_MALLOC_H @HAVE_MALLOC_H@
/* Define to 1 if you have the `malloc_usable_size' function. */
/*#undef HAVE_MALLOC_USABLE_SIZE*/
#define HAVE_MALLOC_USABLE_SIZE @HAVE_MALLOC_USABLE_SIZE@
/* Define to 1 if you have the <memory.h> header file. */
/*#undef HAVE_MEMORY_H*/
#define HAVE_MEMORY_H @HAVE_MEMORY_H@
/* Define to 1 if you have the `pread' function. */
/*#undef HAVE_PREAD*/
#define HAVE_PREAD @HAVE_PREAD@
/* Define to 1 if you have the `pread64' function. */
/*#undef HAVE_PREAD64*/
#define HAVE_PREAD64 @HAVE_PREAD64@
/* Define to 1 if you have the `pwrite' function. */
/*#undef HAVE_PWRITE*/
#define HAVE_PWRITE @HAVE_PWRITE@
/* Define to 1 if you have the `pwrite64' function. */
/*#undef HAVE_PWRITE64*/
#define HAVE_PWRITE64 @HAVE_PWRITE64@
/* Define to 1 if you have the <stdint.h> header file. */
/*#undef HAVE_STDINT_H*/
#define HAVE_STDINT_H @HAVE_STDINT_H@
/* Define to 1 if you have the <stdlib.h> header file. */
/*#undef HAVE_STDLIB_H*/
#define HAVE_STDLIB_H @HAVE_STDLIB_H@
/* Define to 1 if you have the `strchrnul' function. */
/*#undef HAVE_STRCHRNUL*/
#define HAVE_STRCHRNUL @HAVE_STRCHRNUL@
/* Define to 1 if you have the <strings.h> header file. */
/*#undef HAVE_STRINGS_H*/
#define HAVE_STRINGS_H @HAVE_STRINGS_H@
/* Define to 1 if you have the <string.h> header file. */
/*#undef HAVE_STRING_H*/
#define HAVE_STRING_H @HAVE_STRING_H@
/* Define to 1 if you have the <sys/stat.h> header file. */
/*#undef HAVE_SYS_STAT_H*/
#define HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@
/* Define to 1 if you have the <sys/types.h> header file. */
/*#undef HAVE_SYS_TYPES_H*/
#define HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
/* Define to 1 if the system has the type `uint16_t'. */
/*#undef HAVE_UINT16_T*/
#define HAVE_UINT16_T @HAVE_UINT16_T@
/* Define to 1 if the system has the type `uint32_t'. */
/*#undef HAVE_UINT32_T*/
#define HAVE_UINT32_T @HAVE_UINT32_T@
/* Define to 1 if the system has the type `uint64_t'. */
/*#undef HAVE_UINT64_T*/
#define HAVE_UINT64_T @HAVE_UINT64_T@
/* Define to 1 if the system has the type `uint8_t'. */
/*#undef HAVE_UINT8_T*/
#define HAVE_UINT8_T @HAVE_UINT8_T@
/* Define to 1 if the system has the type `uintptr_t'. */
/*#undef HAVE_UINTPTR_T*/
#define HAVE_UINTPTR_T @HAVE_UINTPTR_T@
/* Define to 1 if you have the <unistd.h> header file. */
/*#undef HAVE_UNISTD_H*/
#define HAVE_UNISTD_H @HAVE_UNISTD_H@
/* Define to 1 if you have the `usleep' function. */
/*#undef HAVE_USLEEP*/
#define HAVE_USLEEP @HAVE_USLEEP@
/* Define to 1 if you have the `utime' function. */
/*#undef HAVE_UTIME*/
#define HAVE_UTIME @HAVE_UTIME@
/* Define to 1 if you have the <zlib.h> header file. */
/*#undef HAVE_ZLIB_H*/
#define HAVE_ZLIB_H @HAVE_ZLIB_H@
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/*#undef LT_OBJDIR*/
/*#define LT_OBJDIR @LT_OBJDIR@*/
/* Define to the address where bug reports for this package should be sent. */
/*#undef PACKAGE_BUGREPORT*/
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
/*#undef PACKAGE_NAME*/
#define PACKAGE_NAME "sqlite"
/* Define to the full name and version of this package. */
/*#undef PACKAGE_STRING*/
#define PACKAGE_STRING "sqlite @RELEASE@"
/* Define to the one symbol short name of this package. */
/*#undef PACKAGE_TARNAME*/
#define PACKAGE_TARNAME "sqlite"
/* Define to the home page for this package. */
/*#undef PACKAGE_URL*/
#define PACKAGE_URL @PACKAGE_URL@
/* Define to the version of this package. */
/*#undef PACKAGE_VERSION*/
#define PACKAGE_VERSION @VERSION@
/* Define to 1 if you have the ANSI C header files. */
/*#undef STDC_HEADERS*/
#define STDC_HEADERS 1 /* @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*/
/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/
/*@if _FILE_OFFSET_BITS != ""*/
/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/
/*@endif*/
/* Define for large files, on AIX-style hosts. */
/*#undef _LARGE_FILES*/
/*@if _LARGE_FILES*/
/*#define _LARGE_FILES @_LARGE_FILES@*/
/*@endif*/
+2 -2
View File
@@ -2925,8 +2925,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
if( newLimit>aHardLimit[limitId] ){
newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
}else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){
newLimit = SQLITE_MIN_LENGTH;
}else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
newLimit = 1;
}
db->aLimit[limitId] = newLimit;
}
-5
View File
@@ -3987,11 +3987,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
case SQLITE_FCNTL_NULL_IO: {
osClose(pFile->h);
pFile->h = -1;
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
-5
View File
@@ -3599,11 +3599,6 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
#endif
case SQLITE_FCNTL_NULL_IO: {
(void)osCloseHandle(pFile->h);
pFile->h = NULL;
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = 0;
int rc = winGetTempname(pFile->pVfs, &zTFile);
+4 -104
View File
@@ -2109,7 +2109,7 @@ static void output_c_string(FILE *out, const char *z){
** Output the given string as quoted according to JSON quoting rules.
*/
static void output_json_string(FILE *out, const char *z, i64 n){
unsigned char c;
char c;
static const char *zq = "\"";
static long ctrlMask = ~0L;
static const char *zDQBS = "\"\\";
@@ -2129,7 +2129,7 @@ static void output_json_string(FILE *out, const char *z, i64 n){
z = pcEnd;
}
if( z >= pcLimit ) break;
c = (unsigned char)*(z++);
c = *(z++);
switch( c ){
case '"': case '\\':
cbsSay = (char)c;
@@ -2144,7 +2144,7 @@ static void output_json_string(FILE *out, const char *z, i64 n){
if( cbsSay ){
ace[1] = cbsSay;
sqlite3_fputs(ace, out);
}else if( c<=0x1f || c>=0x7f ){
}else if( c<=0x1f || c==0x7f ){
sqlite3_fprintf(out, "\\u%04x", c);
}else{
ace[1] = (char)c;
@@ -4886,9 +4886,9 @@ static int run_schema_dump_query(
}else{
rc = SQLITE_CORRUPT;
}
sqlite3_free(zErr);
free(zQ2);
}
sqlite3_free(zErr);
return rc;
}
@@ -4951,7 +4951,6 @@ static const char *(azHelp[]) = {
#if SQLITE_SHELL_HAVE_RECOVER
".dbinfo ?DB? Show status information about the database",
#endif
".dbtotxt Hex dump of the database file",
".dump ?OBJECTS? Render database content as SQL",
" Options:",
" --data-only Output only INSERT statements",
@@ -6623,101 +6622,6 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
}
#endif /* SQLITE_SHELL_HAVE_RECOVER */
/*
** Implementation of the ".dbtotxt" command.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){
sqlite3_stmt *pStmt = 0;
sqlite3_int64 nPage = 0;
int pgSz = 0;
const char *zFilename;
const char *zTail;
char *zName = 0;
int rc, i, j;
unsigned char bShow[256]; /* Characters ok to display */
memset(bShow, '.', sizeof(bShow));
for(i=' '; i<='~'; i++){
if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i;
}
rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
pgSz = sqlite3_column_int(pStmt, 0);
sqlite3_finalize(pStmt);
pStmt = 0;
if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error;
rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
nPage = sqlite3_column_int64(pStmt, 0);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nPage<1 ) goto dbtotxt_error;
rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ){
zTail = zFilename = "unk.db";
}else{
zFilename = (const char*)sqlite3_column_text(pStmt, 2);
if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
zTail = strrchr(zFilename, '/');
#if defined(_WIN32)
if( zTail==0 ) zTail = strrchr(zFilename, '\\');
#endif
if( zTail ) zFilename = zTail;
}
zName = strdup(zTail);
shell_check_oom(zName);
sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
nPage*pgSz, pgSz, zName);
sqlite3_finalize(pStmt);
pStmt = 0;
rc = sqlite3_prepare_v2(p->db,
"SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0);
const u8 *aData = sqlite3_column_blob(pStmt, 1);
int seenPageLabel = 0;
for(i=0; i<pgSz; i+=16){
const u8 *aLine = aData+i;
for(j=0; j<16 && aLine[j]==0; j++){}
if( j==16 ) continue;
if( !seenPageLabel ){
sqlite3_fprintf(p->out, "| page %lld offset %lld\n", pgno, pgno*pgSz);
seenPageLabel = 1;
}
sqlite3_fprintf(p->out, "| %5d:", i);
for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
sqlite3_fprintf(p->out, " ");
for(j=0; j<16; j++){
unsigned char c = (unsigned char)aLine[j];
sqlite3_fprintf(p->out, "%c", bShow[c]);
}
sqlite3_fprintf(p->out, "\n");
}
}
sqlite3_finalize(pStmt);
sqlite3_fprintf(p->out, "| end %s\n", zName);
free(zName);
return 0;
dbtotxt_error:
if( rc ){
sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
}
sqlite3_finalize(pStmt);
free(zName);
return 1;
}
/*
** Print the given string as an error message.
*/
@@ -8895,10 +8799,6 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
rc = shell_dbtotxt_command(p, nArg, azArg);
}else
if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
if( nArg==2 ){
p->autoEQPtest = 0;
+1 -11
View File
@@ -1100,11 +1100,6 @@ struct sqlite3_io_methods {
** pointed to by the pArg argument. This capability is used during testing
** and only needs to be supported when SQLITE_TEST is defined.
**
** <li>[[SQLITE_FCNTL_NULL_IO]]
** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
** or file handle for the [sqlite3_file] object such that it will no longer
** read or write to the database file.
**
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
** be advantageous to block on the next WAL lock if the lock is not immediately
@@ -1258,7 +1253,6 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_EXTERNAL_READER 40
#define SQLITE_FCNTL_CKSM_FILE 41
#define SQLITE_FCNTL_RESET_CACHE 42
#define SQLITE_FCNTL_NULL_IO 43
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -2637,14 +2631,10 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** deleted by the most recently completed INSERT, UPDATE or DELETE
** statement on the database connection specified by the only parameter.
** The two functions are identical except for the type of the return value
** and that if the number of rows modified by the most recent INSERT, UPDATE,
** and that if the number of rows modified by the most recent INSERT, UPDATE
** or DELETE is greater than the maximum value supported by type "int", then
** the return value of sqlite3_changes() is undefined. ^Executing any other
** type of SQL statement does not modify the value returned by these functions.
** For the purposes of this interface, a CREATE TABLE AS SELECT statement
** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
** added to the new table by the CREATE TABLE AS SELECT statement are not
** counted.
**
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
-1
View File
@@ -23,7 +23,6 @@
#ifndef SQLITE_MAX_LENGTH
# define SQLITE_MAX_LENGTH 1000000000
#endif
#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */
/*
** This is the maximum number of
+14 -16
View File
@@ -1670,7 +1670,6 @@ static void windowAggStep(
int regArg;
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
int i;
int addrIf = 0;
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -1687,18 +1686,6 @@ static void windowAggStep(
}
regArg = reg;
if( pWin->pFilter ){
int regTmp;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pMWin->regStartRowid==0
&& (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
&& (pWin->eStart!=TK_UNBOUNDED)
@@ -1718,13 +1705,25 @@ static void windowAggStep(
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
assert( pWin->pFilter==0 );
assert( pFunc->zName==nth_valueName
|| pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
}else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pWin->bExprArgs ){
int iOp = sqlite3VdbeCurrentAddr(v);
int iEnd;
@@ -1755,9 +1754,8 @@ static void windowAggStep(
if( pWin->bExprArgs ){
sqlite3ReleaseTempRange(pParse, regArg, nArg);
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}
-310
View File
@@ -1,310 +0,0 @@
/*
** The program demonstrates how a child process created using fork()
** can continue to use SQLite for a database that the parent had opened and
** and was writing into when the fork() occurred.
**
** This program executes the following steps:
**
** 1. Create a new database file. Open it, and populate it.
** 2. Start a transaction and make changes.
** ^-- close the transaction prior to fork() if --commit-before-fork
** 3. Fork()
** 4. In the child, close the database connection. Special procedures
** are needed to close the database connection in the child. See the
** implementation below.
** 5. Commit the transaction in the parent.
** 6. Verify that the transaction committed in the parent.
** 7. In the child, after a delay to allow time for (5) and (6),
** open a new database connection and verify that the transaction
** committed by (5) is seen.
** 8. Add make further changes and commit them in the child, using the
** new database connection.
** 9. In the parent, after a delay to account for (8), verify that
** the new transaction added by (8) can be seen.
**
** Usage:
**
** fork-test FILENAME [options]
**
** Options:
**
** --wal Run the database in WAL mode
** --vfstrace Enable VFS tracing for debugging
** --commit-before-fork COMMIT prior to the fork() in step 3
** --delay-after-4 N Pause for N seconds after step 4
**
** How To Compile:
**
** gcc -O0 -g -Wall -I$(SQLITESRC) \
** f1.c $(SQLITESRC)/ext/misc/vfstrace.c $(SQLITESRC/sqlite3.c \
** -ldl -lpthread -lm
**
** Test procedure:
**
** (1) Run "fork-test x1.db". Verify no I/O errors occur and that
** both parent and child see all three rows in the t1 table.
**
** (2) Repeat (1) adding the --wal option.
**
** (3) Repeat (1) and (2) adding the --commit-before-fork option.
**
** (4) Repeat all prior steps adding the --delay-after-4 option with
** a timeout of 15 seconds or so. Then, while both parent and child
** are paused, run the CLI against the x1.db database from a separate
** window and verify that all the correct file locks are still working
** correctly.
**
** Take-Aways:
**
** * If a process has open SQLite database connections when it fork()s,
** the child can call exec() and all it well. Nothing special needs
** to happen.
**
** * If a process has open SQLite database connections when it fork()s,
** the child can do anything that does not involve using SQLite without
** causing problems in the parent. No special actions are needed in
** the child.
**
** * If a process has open SQLite database connections when it fork()s,
** the child can call sqlite3_close() on those database connections
** as long as there were no pending write transactions when the fork()
** occurred.
**
** * If a process has open SQLite database connections that are in the
** middle of a write transaction and then the processes fork()s, the
** child process should close the database connections using the
** procedures demonstrated in Step 4 below before trying to do anything
** else with SQLite.
**
** * If a child process can safely close SQLite database connections that
** it inherited via fork() using the procedures shown in Step 4 below
** even if the database connections were not involved in a write
** transaction at the time of the fork(). The special procedures are
** required if a write transaction was active. They are optional
** otherwise. No harm results from using the special procedures when
** they are not necessary.
**
** * Child processes that use SQLite should open their own database
** connections. They should not attempt to use a database connection
** that is inherited from the parent.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "sqlite3.h"
/*
** Process ID of the parent
*/
static pid_t parentPid = 0;
/*
** Return either "parent" or "child", as appropriate.
*/
static const char *whoAmI(void){
return getpid()==parentPid ? "parent" : "child";
}
/*
** This is an sqlite3_exec() callback routine that prints all results.
*/
static int execCallback(void *pNotUsed, int nCol, char **aVal, char **aCol){
int i;
const char *zWho = whoAmI();
for(i=0; i<nCol; i++){
const char *zVal = aVal[i];
const char *zCol = aCol[i];
if( zVal==0 ) zVal = "NULL";
if( zCol==0 ) zCol = "NULL";
printf("%s: %s = %s\n", zWho, zCol, zVal);
fflush(stdout);
}
return 0;
}
/*
** Execute one or more SQL statements.
*/
static void sqlExec(sqlite3 *db, const char *zSql, int bCallback){
int rc;
char *zErr = 0;
printf("%s: %s\n", whoAmI(), zSql);
fflush(stdout);
rc = sqlite3_exec(db, zSql, bCallback ? execCallback : 0, 0, &zErr);
if( rc || zErr!=0 ){
printf("%s: %s: rc=%d: %s\n",
whoAmI(), zSql, rc, zErr);
exit(1);
}
}
/*
** Trace callback for the vfstrace extension.
*/
static int vfsTraceCallback(const char *zMsg, void *pNotUsed){
printf("%s: %s", whoAmI(), zMsg);
fflush(stdout);
return 0;
}
/* External VFS module provided by ext/misc/vfstrace.c
*/
extern int vfstrace_register(
const char *zTraceName, // Name of the newly constructed VFS
const char *zOldVfsName, // Name of the underlying VFS
int (*xOut)(const char*,void*), // Output routine. ex: fputs
void *pOutArg, // 2nd argument to xOut. ex: stderr
int makeDefault // Make the new VFS the default
);
int main(int argc, char **argv){
sqlite3 *db;
int rc;
int i;
int useWal = 0;
const char *zFilename = 0;
pid_t child = 0, c2;
int status;
int bCommitBeforeFork = 0;
int nDelayAfter4 = 0;
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]=='-' && z[1]=='-' && z[2]!=0 ) z++;
if( strcmp(z, "-wal")==0 ){
useWal = 1;
}else if( strcmp(z, "-commit-before-fork")==0 ){
bCommitBeforeFork = 1;
}else if( strcmp(z, "-delay-after-4")==0 && i+1<argc ){
i++;
nDelayAfter4 = atoi(argv[i]);
}else if( strcmp(z, "-vfstrace")==0 ){
vfstrace_register("vfstrace", 0, vfsTraceCallback, 0, 1);
}else if( z[0]=='-' ){
printf("unknown option: \"%s\"\n", argv[i]);
exit(1);
}else if( zFilename!=0 ){
printf("unknown argument: \"%s\"\n", argv[i]);
exit(1);
}else{
zFilename = argv[i];
}
}
if( zFilename==0 ){
printf("Usage: %s FILENAME\n", argv[0]);
return 1;
}
/** Step 1 **/
printf("Step 1:\n");
parentPid = getpid();
unlink(zFilename);
rc = sqlite3_open(zFilename, &db);
if( rc ){
printf("sqlite3_open() returns %d\n", rc);
exit(1);
}
if( useWal ){
sqlExec(db, "PRAGMA journal_mode=WAL;", 0);
}
sqlExec(db, "CREATE TABLE t1(x);", 0);
sqlExec(db, "INSERT INTO t1 VALUES('First row');", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
/** Step 2 **/
printf("Step 2:\n");
sqlExec(db, "BEGIN IMMEDIATE;", 0);
sqlExec(db, "INSERT INTO t1 VALUES('Second row');", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
if( bCommitBeforeFork ) sqlExec(db, "COMMIT", 0);
/** Step 3 **/
printf("Step 3:\n"); fflush(stdout);
child = fork();
if( child!=0 ){
printf("Parent = %d\nChild = %d\n", getpid(), child);
}
/** Step 4 **/
if( child==0 ){
int k;
printf("Step 4:\n"); fflush(stdout);
/***********************************************************************
** The following block of code closes the database connection without
** rolling back or changing any files on disk. This is necessary to
** preservce the pending transaction in the parent.
*/
for(k=0; 1/*exit-by-break*/; k++){
const char *zDbName = sqlite3_db_name(db, k);
sqlite3_file *pJrnl = 0;
if( k==1 ) continue;
if( zDbName==0 ) break;
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_NULL_IO, 0);
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_JOURNAL_POINTER, &pJrnl);
if( pJrnl && pJrnl->pMethods && pJrnl->pMethods->xFileControl ){
pJrnl->pMethods->xFileControl(pJrnl, SQLITE_FCNTL_NULL_IO, 0);
}
}
sqlite3_close(db);
/*
** End of special close procedures for SQLite database connections
** inherited via fork().
***********************************************************************/
printf("%s: database connection closed\n", whoAmI()); fflush(stdout);
}else{
/* Pause the parent briefly to give the child a chance to close its
** database connection */
sleep(1);
}
if( nDelayAfter4>0 ){
printf("%s: Delay for %d seconds\n", whoAmI(), nDelayAfter4);
fflush(stdout);
sleep(nDelayAfter4);
printf("%s: Continue after %d delay\n", whoAmI(), nDelayAfter4);
fflush(stdout);
}
/** Step 5 **/
if( child!=0 ){
printf("Step 5:\n");
if( !bCommitBeforeFork ) sqlExec(db, "COMMIT", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
}
/** Step 7 **/
if( child==0 ){
sleep(2);
printf("Steps 7 and 8:\n");
rc = sqlite3_open(zFilename, &db);
if( rc ){
printf("Child unable to reopen the database. rc = %d\n", rc);
exit(1);
}
sqlExec(db, "SELECT * FROM t1;", 1);
/** Step 8 **/
sqlExec(db, "INSERT INTO t1 VALUES('Third row');", 0);
sqlExec(db, "SELECT * FROM t1;", 1);
sleep(1);
return 0;
}
c2 = wait(&status);
printf("Process %d finished with status %d\n", c2, status);
/** Step 9 */
if( child!=0 ){
printf("Step 9:\n");
sqlExec(db, "SELECT * FROM t1;", 1);
}
return 0;
}
+4 -26
View File
@@ -4403,32 +4403,10 @@ do_catchsql_test 25.5 {
INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ;
} {0 {}}
if {$tcl_platform(byteOrder)=="littleEndian"} {
# The SQLITE_CORRUPT error depends on the specific random byte
# sequence generated by SQLite's PRNG. But the SQLite PRNG
# uses ChaCha20, which generates a different byte sequence on
# big-endian and little-endian platforms. The SQLITE_CORRUPT
# error only comes up when the pseudo-random byte sequence is
# the one generated on little-endian platforms.
#
# See Forum thread:
# https://sqlite.org/forum/forumpost/b5f89d813babfd88
#
do_catchsql_test 25.6a {
INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
do_catchsql_test 25.6b {
INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
} else {
do_catchsql_test 25.6a {
INSERT INTO t1(t1) SELECT x FROM t2;
} {0 {}}
do_catchsql_test 25.6b {
INSERT INTO t1(t1) SELECT x FROM t2;
} {0 {}}
}
do_catchsql_test 25.6 {
INSERT INTO t1(t1) SELECT x FROM t2;
INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
-280
View File
@@ -1,280 +0,0 @@
# 2024 November 7
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS3 module.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts3corrupt7
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
sqlite3_fts3_may_be_corrupt 1
database_may_be_corrupt
extra_schema_checks 0
#-------------------------------------------------------------------------
reset_db
do_test 1.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename x.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 04 00 00 00 07 .....@ ........
| 32: 00 00 00 02 00 00 00 01 00 00 00 04 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
| 96: 00 2e 82 40 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...@...........!
| 112: 0e b9 0d c8 0e 7e 0d a4 7d a4 00 00 00 00 00 00 .....~..........
| 2512: 00 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 ................
| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl
| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB
| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3......
| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir
| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE
| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi
| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER
| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta
| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER
| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc
| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl
| 3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74 ock INTEGER,root
| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE
| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1.
| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit
| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s
| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir
| 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##.
| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen
| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 tst1_segments.CR
| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid
| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB
| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet
| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do
| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d cid INTEGER PRIM
| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a',
| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')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 33 LE t1 USING fts3
| 4032: 28 61 2c 62 2c 63 29 00 00 00 39 00 00 00 00 00 (a,b,c)...9.....
| page 2 offset 4096
| 0: 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 ................
| 16: 00 00 00 00 02 00 00 00 00 05 00 00 00 03 02 00 ................
| 32: 00 00 00 05 00 00 00 03 02 00 00 00 00 05 00 00 ................
| 48: 00 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00 ................
| 64: 00 05 00 00 00 03 02 00 00 00 00 05 00 00 00 03 ................
| 80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05 ................
| 96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00 ................
| 112: 00 00 03 03 00 00 00 23 02 00 00 00 00 03 00 00 .......#........
| 128: 00 23 02 00 00 00 00 03 00 00 4d 5a 14 00 ae 7c .#........MZ...|
| 1088: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 ................
| page 3 offset 8192
| 0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74 ....%.H........t
| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$......
| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5....
| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$..
| 80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H..............
| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7f 00 .........?%.....
| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5.
| 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 45 42 4.0 20160609 DEB
| 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54 UG ENABLE DBSTAT
| 2944: 20 56 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53 VTAB ENABLE FTS
| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN
| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA
| 2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLE JSON1 ENABLE
| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE
| 3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 RTREE MAX MEMORY
| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L
| 3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OAD EXTENSION TH
| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%.
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE..
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS
| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 00 00 IONXRTRIM....3..
| 4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 TABLE t1(a INTEG
| 4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41 ER PRIMARY KEY A
| 4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c UTOINCREMENT,.b,
| 4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c c,d,e,f,g,h,j,k,
| 4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29 l,m,n,o,p,q,r,s)
| page 5 offset 16384
| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................
| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253
| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606
| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5
| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%.
| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%...
| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu
| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%.
| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio
| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%...
| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%...
| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso
| 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%..
| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79 ..max.%....emory
| 3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04 .%....sys5.%....
| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree.
| 3216: 25 01 00 d0 0a 07 68 72 65 61 64 73 61 66 65 03 %.....hreadsafe.
| 3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P.
| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0
| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................
| 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 .....20160609...
| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4......
| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5.........
| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000......
| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<...
| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
| 3376: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................
| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................
| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi
| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d
| 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat...........
| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug...........
| 3472: 06 65 6e 61 62 6c 65 3f 07 02 00 01 02 00 01 02 .enable?........
| 3488: 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 ................
| 3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 ................
| 3520: 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 ................
| 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio
| 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts
| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5..
| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc...
| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09 .........eopoly.
| 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1
| 3632: 09 13 03 00 01 03 01 01 03 00 00 04 6c 6f 61 64 ............load
| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max.
| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory
| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5
| 3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca
| 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<.............
| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................
| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................
| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit...........
| 3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00 .rtree..........
| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<...........
| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................
| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................
| 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe...
| 3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04 .........vtab...
| 3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................
| 3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................
| 3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
| 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................
| 4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................
| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
| page 6 offset 20480
| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00 ................
| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................
| end x.db
}]} {}
do_catchsql_test 1.1 {
SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'rtree NEAR rtree NEAR "json1 enable"';
} {0 {}}
#-------------------------------------------------------------------------
reset_db
do_test 1.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename crash-10b0f1037e9c85.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 00 00 00 40 20 20 00 00 00 01 00 00 00 07 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
| 96: 00 2e 82 40 0d 00 00 00 06 00 00 00 0f 8d 0f 21 ...@...........!
| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~..........
| 3488: 00 00 00 00 21 ff 06 17 10 10 01 30 74 61 62 6c ....!......0tabl
| 3504: 65 74 32 74 32 00 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB
| 3520: 4c 45 20 74 32 28 70 29 81 33 00 07 17 1f 1f 01 LE t2(p).3......
| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir
| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE
| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi
| 3584: 72 27 28 6c 65 76 65 6c 20 09 4e 50 45 47 45 50 r'(level .NPEGEP
| 3600: 2c 69 64 78 20 09 4e 50 45 47 45 50 2c 73 74 61 ,idx .NPEGEP,sta
| 3616: 72 74 5f 62 6c 6f 63 6b 20 09 4e 50 45 47 45 50 rt_block .NPEGEP
| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc
| 3648: 6b 20 09 4e 50 45 47 45 50 2c 65 6e 64 5f 62 6c k .NPEGEP,end_bl
| 3664: 6f 63 6b 20 09 4e 50 45 47 45 50 2c 72 6f 6f 74 ock .NPEGEP,root
| 3680: 20 42 0c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 B.OB,PRIMARY KE
| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 00 Y(level, idx))1.
| 3712: 06 17 45 1f 01 00 00 00 00 00 00 73 71 6c 69 74 ..E........sqlit
| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s
| 3744: 65 67 64 69 72 5f 31 00 00 00 00 00 00 00 00 00 egdir_1.........
| 3760: 06 00 00 00 00 00 00 00 00 66 00 07 17 23 23 01 .........f...##.
| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen
| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 00 43 52 tst1_segments.CR
| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
| 3824: 65 67 6d 65 6e 74 73 27 28 0c 6f 63 6b 09 64 0a egments'(.ock.d.
| 3840: 20 09 4e 50 45 47 45 50 20 50 50 09 04 31 50 09 .NPEGEP PP..1P.
| 3856: 20 0b 45 09 0c 20 62 0c 6f 63 6b 20 42 0c 4f 42 .E.. b.ock B.OB
| 3872: 29 6a 00 07 17 20 20 01 81 1f 74 61 62 6c 65 74 )j... ...tablet
| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3904: 65 6e 74 00 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do
| 3936: 09 64 20 09 4e 50 45 47 45 50 20 50 50 09 0d 0c .d .NPEGEP PP...
| 3952: 50 09 20 0b 45 09 0c 20 27 03 03 01 27 0c 20 0a P. .E.. '...'. .
| 3968: 27 03 01 02 27 0c 20 27 03 02 03 27 29 38 00 06 '...'. '...')8..
| 3984: 17 10 10 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 33 LE t1 USING fts3
| page 5 offset 16384
| 0: 0d 00 00 00 02 00 00 00 00 00 0b a0 00 00 00 00 ................
| 2976: 82 0a 02 08 00 00 00 00 17 84 06 00 00 00 00 00 ................
| 2992: 00 01 00 04 00 00 00 00 00 08 00 00 00 00 00 00 ................
| 3008: 00 00 03 00 00 00 00 01 00 03 00 00 00 00 01 00 ................
| 3024: 03 00 00 00 00 07 00 00 00 00 00 00 00 03 00 00 ................
| 3040: 00 00 08 00 00 00 00 00 00 00 00 03 00 00 00 00 ................
| 3056: 06 00 00 00 00 00 00 03 00 00 00 00 04 00 00 00 ................
| 3072: 00 03 00 00 00 00 06 65 6e 61 62 6c 65 09 25 09 .......enable.%.
| 3088: 05 04 04 04 04 00 00 00 08 00 00 00 00 00 00 00 ................
| 3104: 00 03 00 00 00 00 04 00 00 00 00 03 00 00 00 00 ................
| 3120: 01 00 03 00 00 00 00 03 00 00 00 03 00 00 00 00 ................
| 3136: 06 00 00 00 00 00 00 03 00 00 00 00 05 6a 73 6f .............jso
| 3152: 6e 31 03 25 13 00 00 04 00 00 00 00 03 00 00 00 n1.%............
| 3168: 00 03 00 00 00 03 00 00 00 00 05 00 00 00 00 00 ................
| 3184: 03 00 00 00 00 04 00 00 00 00 03 00 00 00 00 04 ................
| 3200: 00 00 00 00 03 00 00 00 00 05 72 74 72 65 65 03 ..........rtree.
| 3216: 25 01 00 0d 0a 07 08 01 ff ff ff ff ff 01 00 00 %...............
| page 6 offset 20480
| 0: 0a 00 00 00 02 00 00 00 0f fb 0f f5 00 00 00 00 ................
| 4080: 00 00 00 00 00 05 04 09 00 01 02 04 00 00 00 00 ................
| end crash-10b0f1037e9c85.db
}]} {}
do_catchsql_test 2.1 {
SELECT 0 FROM t1 WHERE t1 MATCH 'rtree NEAR rtree"json1 enable"';
} {1 {database disk image is malformed}}
finish_test
-7
View File
@@ -75,13 +75,6 @@ do_test sqllimits1-1.23 {
sqlite3_limit db SQLITE_LIMIT_TOOBIG 123
} {-1}
# Minimum value for SQLITE_LIMIT_LENGTH is 30
#
do_test sqllimits1-1.30 {
sqlite3_limit db SQLITE_LIMIT_LENGTH 1
sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000000
} 30
# Decrease all limits by half. Verify that the new limits take.
#
-62
View File
@@ -489,68 +489,6 @@ execsql_test 9.2 {
FROM t1
}
==========
execsql_test 10.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER, b INTEGER);
INSERT INTO t1 VALUES (10, 1),
(20, -1),
(5, 2),
(15, 0),
(25, 3);
}
execsql_test 10.1 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
}
execsql_test 10.2 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS ();
}
execsql_test 10.3 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a);
}
execsql_test 10.4 {
SELECT
a, b, MIN(a) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
}
==========
execsql_test 11.0 {
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER, b INTEGER);
INSERT INTO t2 VALUES(1, 12);
INSERT INTO t2 VALUES(2, 10);
INSERT INTO t2 VALUES(3, 15);
INSERT INTO t2 VALUES(4, 22);
INSERT INTO t2 VALUES(5, 1);
INSERT INTO t2 VALUES(6, 4);
INSERT INTO t2 VALUES(7, 7);
INSERT INTO t2 VALUES(8, 6);
INSERT INTO t2 VALUES(9, 22);
INSERT INTO t2 VALUES(10, 2);
}
execsql_test 11.1 {
SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win
FROM t2
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING);
}
finish_test
-63
View File
@@ -6540,67 +6540,4 @@ do_execsql_test 9.2 {
FROM t1
} {}
#==========================================================================
do_execsql_test 10.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER, b INTEGER);
INSERT INTO t1 VALUES (10, 1),
(20, -1),
(5, 2),
(15, 0),
(25, 3);
} {}
do_execsql_test 10.1 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
} {5 2 5 10 1 5 15 0 10 20 -1 25 25 3 25}
do_execsql_test 10.2 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS ();
} {10 1 5 20 -1 5 5 2 5 15 0 5 25 3 5}
do_execsql_test 10.3 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a);
} {5 2 5 10 1 5 15 0 5 20 -1 5 25 3 5}
do_execsql_test 10.4 {
SELECT
a, b, MIN(a) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
} {5 2 5 10 1 5 15 0 10 20 -1 15 25 3 20}
#==========================================================================
do_execsql_test 11.0 {
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER, b INTEGER);
INSERT INTO t2 VALUES(1, 12);
INSERT INTO t2 VALUES(2, 10);
INSERT INTO t2 VALUES(3, 15);
INSERT INTO t2 VALUES(4, 22);
INSERT INTO t2 VALUES(5, 1);
INSERT INTO t2 VALUES(6, 4);
INSERT INTO t2 VALUES(7, 7);
INSERT INTO t2 VALUES(8, 6);
INSERT INTO t2 VALUES(9, 22);
INSERT INTO t2 VALUES(10, 2);
} {}
do_execsql_test 11.1 {
SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win
FROM t2
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING);
} {1 12 2 12 3 1 4 1 5 1 6 1 7 1 8 7 9 7 10 22}
finish_test
-58
View File
@@ -282,62 +282,4 @@ do_catchsql_test 9.1 {
FROM t1
} {1 {frame ending offset must be a non-negative number}}
#--------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 'a');
INSERT INTO t1 VALUES(2, 'b');
INSERT INTO t1 VALUES(3, 'c');
INSERT INTO t1 VALUES(4, 'd');
INSERT INTO t1 VALUES(5, 'e');
INSERT INTO t1 VALUES(6, 'f');
}
do_execsql_test 10.1 {
SELECT a, min(b) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 a
2 a
3 a
4 b
5 c
6 d
}
do_execsql_test 10.2 {
SELECT a, min(b) FILTER (WHERE a%2) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 a
2 a
3 a
4 c
5 c
6 e
}
do_execsql_test 10.3 {
SELECT a, min(b) FILTER (WHERE (a%2)=0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 b
2 b
3 b
4 b
5 d
6 d
}
do_catchsql_test 10.4 {
SELECT a, nth_value(b, 1) FILTER (WHERE (a%2)=0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {1 {FILTER clause may only be used with aggregate window functions}}
finish_test