Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2a3c7232b | |||
| 032bcf72fb | |||
| 67a3914e65 | |||
| 8acaa6d039 | |||
| 090b8649be | |||
| 32b4979559 | |||
| cd9b951e6b | |||
| b27a30c620 | |||
| d2a88e961a | |||
| 7d56669bc4 | |||
| 2eff8f2252 | |||
| acfd1e2ba8 | |||
| e25a267e81 |
+15
-25
@@ -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 $@
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
========================================================================
|
||||
|
||||
@@ -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
@@ -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]
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216
|
||||
f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9
|
||||
|
||||
+194
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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],
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user