diff --git a/Makefile.in b/Makefile.in
index 91135edba3..3bb66f13ff 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -136,7 +136,7 @@ HAVE_WASI_SDK = @HAVE_WASI_SDK@
libsqlite3.DLL.install-rules = @SQLITE_DLL_INSTALL_RULES@
# -fsanitize flags for the fuzzcheck-asap app
-CFLAGS.fuzzcheck.fsanitize = @CFLAGS_FUZZCHECK_FSANITIZE@
+CFLAGS.fuzzcheck-asan.fsanitize = @CFLAGS_ASAN_FSANITIZE@
T.cc.sqlite = $(T.cc) @TARGET_DEBUG@
@@ -340,5 +340,4 @@ distclean: distclean-autosetup
version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h
$(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c
-IS_CROSS_COMPILING = @IS_CROSS_COMPILING@
include $(TOP)/main.mk
diff --git a/auto.def b/auto.def
index dcc7371ec0..a1191cdd1e 100644
--- a/auto.def
+++ b/auto.def
@@ -12,7 +12,6 @@
#
# JimTCL: https://jim.tcl.tk
#
-
use sqlite-config
sqlite-configure canonical {
proj-if-opt-truthy dev {
@@ -46,7 +45,10 @@ sqlite-configure canonical {
define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools]
- define CFLAGS_FUZZCHECK_FSANITIZE [proj-check-fsanitize {address bounds-strict}]
+ if {[set fsan [join [opt-val asan-fsanitize] ","]] in {auto ""}} {
+ set fsan address,bounds-strict
+ }
+ define CFLAGS_ASAN_FSANITIZE [proj-check-fsanitize [split $fsan ", "]]
sqlite-handle-tcl
sqlite-handle-emsdk
diff --git a/autoconf/Makefile.in b/autoconf/Makefile.in
index e59864a20b..009398617c 100644
--- a/autoconf/Makefile.in
+++ b/autoconf/Makefile.in
@@ -50,6 +50,7 @@ CC = @CC@
ENABLE_LIB_SHARED = @ENABLE_LIB_SHARED@
ENABLE_LIB_STATIC = @ENABLE_LIB_STATIC@
+HAVE_WASI_SDK = @HAVE_WASI_SDK@
CFLAGS = @CFLAGS@ @CPPFLAGS@
#
@@ -71,11 +72,8 @@ LDFLAGS.rt = @LDFLAGS_RT@
LDFLAGS.icu = @LDFLAGS_ICU@
CFLAGS.icu = @CFLAGS_ICU@
-# When cross-compiling, we need to avoid the -s flag because it only
-# works on the build host's platform.
-INSTALL.strip.1 = $(INSTALL)
-INSTALL.strip.0 = $(INSTALL) -s
-INSTALL.strip = $(INSTALL.strip.@IS_CROSS_COMPILING@)
+# INSTALL reminder: we specifically do not strip binaries,
+# as discussed in https://sqlite.org/forum/forumpost/9a67df63eda9925c.
INSTALL.noexec = $(INSTALL) -m 0644
install-dir.bin = $(DESTDIR)$(bindir)
@@ -236,11 +234,14 @@ sqlite3$(T.exe): $(TOP)/shell.c $(sqlite3-shell-deps.$(ENABLE_STATIC_SHELL))
$(CFLAGS) $(CFLAGS.readline) $(CFLAGS.icu) \
$(LDFLAGS) $(LDFLAGS.readline)
-all: sqlite3$(T.exe)
+sqlite3$(T.exe)-1:
+sqlite3$(T.exe)-0: sqlite3$(T.exe)
+all: sqlite3$(T.exe)-$(HAVE_WASI_SDK)
-install-shell: sqlite3$(T.exe) $(install-dir.bin)
- $(INSTALL.strip) sqlite3$(T.exe) "$(install-dir.bin)"
-install: install-shell
+install-shell-0: sqlite3$(T.exe) $(install-dir.bin)
+ $(INSTALL) sqlite3$(T.exe) "$(install-dir.bin)"
+install-shell-1:
+install: install-shell-$(HAVE_WASI_SDK)
install-headers: $(TOP)/sqlite3.h $(install-dir.include)
$(INSTALL.noexec) $(TOP)/sqlite3.h $(TOP)/sqlite3ext.h "$(install-dir.include)"
diff --git a/autoconf/auto.def b/autoconf/auto.def
index 3ba900d957..85fa7d93ed 100644
--- a/autoconf/auto.def
+++ b/autoconf/auto.def
@@ -5,6 +5,16 @@
# "autoconf" bundle of the SQLite project.
use sqlite-config
sqlite-configure autoconf {
- sqlite-check-common-bins
+ sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
+ sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
+ proj-define-for-opt static-shell ENABLE_STATIC_SHELL \
+ "Link library statically into the CLI shell?"
+ if {![opt-bool shared] && ![opt-bool static-shell]} {
+ proj-opt-set shared 1
+ proj-indented-notice {
+ NOTICE: ignoring --disable-shared because --disable-static-shell
+ was specified.
+ }
+ }
}
diff --git a/autosetup/README.md b/autosetup/README.md
index 2d6cf723c0..a61f94fbda 100644
--- a/autosetup/README.md
+++ b/autosetup/README.md
@@ -14,7 +14,7 @@ build infrastructure. It is not an [Autosetup][] reference.
- Symbolic Names of Feature Flags
- Do Not Update Global Shared State
- [Updating Autosetup](#updating)
- - [Patching Autosetup for Project-local changes](#patching)
+ - ***[Patching Autosetup for Project-local changes](#patching)***
------------------------------------------------------------------------
@@ -42,12 +42,13 @@ following files:
(e.g. Fossil), and personal projects of SQLite's developers. It is
essentially an amalgamation of a decade's worth of autosetup-related
utility code.
-- [auto.def][]: the primary driver for the `./configure` process.
- When we talk about "the configure script," we're referring to
- this file.
- [sqlite-config.tcl][]: utility code which is too project-specific
for `proj.tcl`. We split this out of `auto.def` so that it can be
used by both `auto.def` and...
+- [auto.def][]: the primary driver for the `./configure` process.
+ When we talk about "the configure script," we're technically
+ referring to this file, though it actually contains very little
+ of the TCL code.
- [autoconf/auto.def][]: the main driver script for the "autoconf"
bundle's configure script. It is essentially a slightly trimmed-down
version of the main `auto.def` file. The `autoconf` dir was ported
@@ -61,11 +62,11 @@ 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 the relevant TCL files. The complete
-docs of those with `proj-` prefix can be found in [proj.tcl][] and
-those with an `sqlite-` prefix are in [sqlite-config.tcl][]. The
-others are scattered around [the TCL files in
-./autosetup](/dir/autosetup).
+from a casual perusal of the relevant TCL files. The complete docs of
+those with `proj-` prefix can be found in [proj.tcl][] and those with
+an `sqlite-` prefix are in [sqlite-config.tcl][]. The others are part
+of Autosetup's core packages and are scattered around [the TCL files
+in ./autosetup](/dir/autosetup).
In (mostly) alphabetical order:
@@ -83,19 +84,14 @@ In (mostly) alphabetical order:
Works like `get-env` but will, if that function finds no match,
look for a file named `./.env-$VAR` and, if found, return its
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?"
- 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.
+ local preferences for the default `CFLAGS`.\
+ Tip: adding `-O0` to `.env-CFLAGS` reduces rebuild times
+ considerably at the cost of performance in `make devtest` and the
+ like.
- **`proj-fatal msg`**\
- Emits `$msg` to stderr and exits with non-zero.
+ Emits `$msg` to stderr and exits with non-zero. Its differences from
+ autosetup's `user-error` are purely cosmetic.
- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\
Evals `thenScript` if the given `--flag` is truthy, else it
@@ -117,7 +113,10 @@ In (mostly) alphabetical order:
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, where in the latter case it's not.\
+ Unlike most functions which deal with `--flags`, this one does not
+ validate that `$FLAG` is a registered flag so will not fail fatally
+ if `$FLAG` is not registered as an Autosetup option.
- **`proj-val-truthy value`**\
Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition
@@ -139,6 +138,15 @@ In (mostly) alphabetical order:
The shell-specific counterpart of `sqlite-add-feature-flag` which
only adds the given flag(s) to the CLI-shell-specific CFLAGS.
+- **`sqlite-configure BUILD-NAME {script}`**\
+ This is where all configure `--flags` are defined for all known
+ build modes ("canonical" or "autoconf"). After processing all flags,
+ this function runs `$script`, which contains the build-mode-specific
+ configuration bits, and then runs any finalization bits which are
+ common to all build modes. The `auto.def` files are intended to contain
+ exactly two commands:
+ `use sqlite-config; sqlite-configure BUILD-NAME {script}`
+
- **`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
@@ -152,13 +160,18 @@ In (mostly) alphabetical order:
Ensuring TCL Compatibility
========================================================================
-It is important that any TCL files used by the configure process
-remain compatible with both [JimTCL][] and the canonical TCL. Though
-JimTCL has outstanding compatibility with canonical TCL, it does have
-a few corners with incompatibilities, e.g. regular expressions. If a
-script runs in JimTCL without using any JimTCL-specific features, then
-it's a certainty that it will run in canonical TCL as well. The
-opposite, however, is not _always_ the case.
+One of the significant benefits of using Autosetup is that (A) this
+project uses many TCL scripts in the build process and (B) Autosetup
+comes with a TCL interpreter named [JimTCL][].
+
+It is important that any TCL files used by the configure process and
+makefiles remain compatible with both [JimTCL][] and the canonical
+TCL. Though JimTCL has outstanding compatibility with canonical TCL,
+it does have a few corners with incompatibilities, e.g. regular
+expressions. If a script runs in JimTCL without using any
+JimTCL-specific features, then it's a certainty that it will run in
+canonical TCL as well. The opposite, however, is not _always_ the
+case.
When [`./configure`](/file/configure) is run, it goes through a
bootstrapping process to find a suitable TCL with which to run the
@@ -187,14 +200,17 @@ compatibility across TCL implementations:
before looking for a system-level `tclsh`. Be aware, though, that
`make distclean` will remove that file.
-**Note that `jimsh0` is distinctly different from the `jimsh`** which
-gets built for code-generation purposes. The latter requires
+**Note that `./jimsh0` is distinctly different from the `./jimsh`**
+which gets built for code-generation purposes. The latter requires
non-default build flags to enable features which are
platform-dependent, most notably to make its `[file normalize]` work.
This means, for example, that the configure script and its utility
APIs must not use `[file normalize]`, but autosetup provides a
TCL-only implementation of `[file-normalize]` (note the dash) for
-portable use in the configure script.
+portable use in the configure script. Contrariwise, code-generation
+scripts invoked via `make` may use `[file normalize]`, as they'll use
+`./jimsh` or `tclsh` instead of `./jimsh0`.
+
Known TCL Incompatibilities
------------------------------------------------------------------------
@@ -221,6 +237,7 @@ A summary of known incompatibilities in JimTCL
- `regsub` does not support the `\y` flag. A workaround is demonstrated
in [](/info/c2e5dd791cce3ec4).
+
Design Conventions
========================================================================
@@ -247,8 +264,9 @@ dots are not permitted.
The `X.y` convention is used in the makefiles primarily because the
person who did the initial port finds that considerably easier on the
eyes and fingers. In practice, the `X_Y` form of such exports is used
-exactly once in [Makefile.in][], where it's translated into into `X.y`
-form for consumption by [Makefile.in][] and [main.mk][]. For example:
+exactly once in [Makefile.in][], where it's translated from `@X_Y@`
+into into `X.y` form for consumption by [Makefile.in][] and
+[main.mk][]. For example:
>
```
@@ -265,9 +283,9 @@ of taste, for which there is no accounting.)
Do Not Update Global Shared State
------------------------------------------------------------------------
-In both the legacy Autotools-driven build and in common Autosetup
-usage, feature tests performed by the configure script may amend
-global flags such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's
+In both the legacy Autotools-driven build and common Autosetup usage,
+feature tests performed by the configure script may amend global flags
+such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's
appropriate for a makefile which builds a single deliverable, but less
so for makefiles which produce multiple deliverables. Drawbacks of
that approach include:
@@ -275,8 +293,8 @@ that approach include:
- It's unlikely that every single deliverable will require the same
core set of those flags.
- It can be difficult to determine the origin of any given change to
- that global state because those changes are hidden behind voodoo performed
- outside the immediate visibility of the configure script's
+ that global state because those changes are hidden behind voodoo
+ performed outside the immediate visibility of the configure script's
maintainer.
- It can force the maintainers of the configure script to place tests
in a specific order so that the resulting flags get applied at
@@ -357,12 +375,11 @@ Patching Autosetup for Project-local Changes
Autosetup reserves the flag name **`--debug`** for its own purposes,
and its own special handling of `--enable-...` flags makes `--debug`
-an alias for `--enable-debug`. As we have a long history of using
-`--enable-debug` for this project's own purposes, we patch autosetup
-to use the name `--autosetup-debug` in place of `--debug`. That
-requires (as of this writing) four small edits in
-[](/file/autosetup/autosetup), as demonstrated in [check-in
-3296c8d3](/info/3296c8d3).
+an alias for `--enable-debug`. As this project has a long history of
+using `--enable-debug`, we patch autosetup to use the name
+`--autosetup-debug` in place of `--debug`. That requires (as of this
+writing) four small edits in [](/file/autosetup/autosetup), as
+demonstrated in [check-in 3296c8d3](/info/3296c8d3).
If autosetup is upgraded and this patch is _not_ applied the invoking
`./configure` will fail loudly because of the declaration of the
diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl
index f367b01567..3e703d007a 100644
--- a/autosetup/proj.tcl
+++ b/autosetup/proj.tcl
@@ -75,22 +75,22 @@ proc proj-fatal {msg} {
}
########################################################################
-# @proj-assert script
+# @proj-assert script ?message?
#
# 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
+# includes the body of the failed assertion, but if $msg is set then
# that is used instead.
-proc proj-assert {script {descr ""}} {
+proc proj-assert {script {msg ""}} {
if {1 == [get-env proj-assert 0]} {
msg-result [proj-bold "asserting: $script"]
}
set x "expr \{ $script \}"
if {![uplevel 1 $x]} {
- if {"" eq $descr} {
- set descr $script
+ if {"" eq $msg} {
+ set msg $script
}
- proj-fatal "Assertion failed: $descr"
+ proj-fatal "Assertion failed: $msg"
}
}
@@ -188,7 +188,8 @@ proc proj-lshift_ {listVar {count 1}} {
# Expects to receive string input, which it splits on newlines, strips
# out any lines which begin with any number of whitespace followed by
# a '#', and returns a value containing the [append]ed results of each
-# remaining line with a \n between each.
+# remaining line with a \n between each. It does not strip out
+# comments which appear after the first non-whitespace character.
proc proj-strip-hash-comments {val} {
set x {}
foreach line [split $val \n] {
@@ -223,8 +224,8 @@ proc proj-cflags-without-werror {{var CFLAGS}} {
#
# - Does not make any global changes to the LIBS define.
#
-# - Strips out -W... warning flags from CFLAGS before running the
-# test, as these feature tests will often fail if -Werror is used.
+# - Strips out the -Werror flag from CFLAGS before running the test,
+# as these feature tests will often fail if -Werror is used.
#
# Returns the result of cc-check-function-in-lib (i.e. true or false).
# The resulting linker flags are stored in the [define] named
@@ -1039,12 +1040,22 @@ proc proj-check-soname {{libname "libfoo.so.0"}} {
# Checks whether CC supports -fsanitize=X, where X is each entry of
# the given list of flags. If any of those flags are supported, it
# returns the string "-fsanitize=X..." where X... is a comma-separated
-# list of all supported flags. If none of the given options are
-# supported then it returns an empty string.
+# list of all flags from the original set which are supported. If none
+# of the given options are supported then it returns an empty string.
+#
+# Example:
+#
+# set f [proj-check-fsanitize {address bounds-check just-testing}]
+#
+# Will, on many systems, resolve to "-fsanitize=address,bounds-check",
+# but may also resolve to "-fsanitize=address".
proc proj-check-fsanitize {{opts {address bounds-strict}}} {
set sup {}
foreach opt $opts {
- cc-with {} {
+ # -nooutput is used because -fsanitize=hwaddress will otherwise
+ # pass this test on x86_64, but then warn at build time that
+ # "hwaddress is not supported for this target".
+ cc-with {-nooutput 1} {
if {[cc-check-flags "-fsanitize=$opt"]} {
lappend sup $opt
}
@@ -1355,3 +1366,14 @@ proc proj-env-file {flag {dflt ""}} {
proc proj-get-env {var {dflt ""}} {
return [get-env $var [proj-env-file $var $dflt]]
}
+
+########################################################################
+# @proj-current-proc-name
+#
+# Returns the name of the _calling_ proc from ($lvl + 1) levels up the
+# call stack (where the caller's level will be 1 up from _this_
+# call). It is not legal to call this from the top scope.
+proc proj-current-proc-name {{lvl 0}} {
+ #uplevel [expr {$lvl + 1}] {lindex [info level 0] 0}
+ lindex [info level [expr {-$lvl - 1}]] 0
+}
diff --git a/autosetup/sqlite-config.tcl b/autosetup/sqlite-config.tcl
index 3644b4872a..15c0995500 100644
--- a/autosetup/sqlite-config.tcl
+++ b/autosetup/sqlite-config.tcl
@@ -1,6 +1,6 @@
# This file holds functions for autosetup which are specific to the
# sqlite build tree. They are in this file, instead of auto.def, so
-# that they can be reused in the TEA sub-tree. This file requires
+# that they can be reused in the autoconf sub-tree. This file requires
# functions from proj.tcl.
if {[string first " " $autosetup(srcdir)] != -1} {
@@ -13,9 +13,11 @@ if {[string first " " $autosetup(builddir)] != -1} {
}
use proj
-# We want this version info to be emitted up front, but we have to
-# 'use system' for --prefix=... to work. Ergo, this bit is up here
-# instead of in [sqlite-configure].
+#
+# We want the package version info to be emitted early on, but doing
+# so requires a bit of juggling. We have to [use system] for
+# --prefix=... to work and to emit the Host/Build system info, but we
+# don't want those to interfere with --help output.
define PACKAGE_VERSION [proj-file-content -trim $::autosetup(srcdir)/VERSION]
if {"--help" ni $::argv} {
msg-result "Configuring SQLite version [get-define PACKAGE_VERSION]"
@@ -24,20 +26,27 @@ use system ; # Will output "Host System" and "Build System" lines
if {"--help" ni $::argv} {
msg-result "Source dir = $::autosetup(srcdir)"
msg-result "Build dir = $::autosetup(builddir)"
-
use cc cc-db cc-shared cc-lib pkg-config
}
#
-# Object for communicating config-time state across various
+# Object for communicating certain config-time state across various
# auto.def-related pieces.
-#
-array set sqliteConfig [proj-strip-hash-comments {
+array set sqliteConfig [subst [proj-strip-hash-comments {
+ #
+ # Gets set by [sqlite-configure] (the main configure script driver).
+ build-mode unknown
#
# Gets set to 1 when using jimsh for code generation. May affect
# later decisions.
use-jim-for-codegen 0
#
+ # Set to 1 when cross-compiling This value may be changed by certain
+ # build options, so it's important that config code which checks for
+ # cross-compilation uses this var instead of
+ # [proj-is-cross-compiling].
+ is-cross-compiling [proj-is-cross-compiling]
+ #
# Pass msg-debug=1 to configure to enable obnoxiously loud output
# from [msg-debug].
msg-debug-enabled 0
@@ -50,15 +59,7 @@ array set sqliteConfig [proj-strip-hash-comments {
# (dump-defines-txt) but also a JSON file named after this option's
# value.
dump-defines-json ""
-}]
-
-#
-# Set to 1 when cross-compiling This value may be changed by certain
-# build options, so it's important that config code which checks for
-# cross-compilation uses this var instead of
-# [proj-is-cross-compiling].
-#
-set sqliteConfig(is-cross-compiling) [proj-is-cross-compiling]
+}]]
########################################################################
# Processes all configure --flags for this build, run build-specific
@@ -70,13 +71,18 @@ set sqliteConfig(is-cross-compiling) [proj-is-cross-compiling]
# $buildMode, with the caveat that _some_ build-specific code is
# encapsulated in the configuration finalization step.
#
-# The intent is that all build-mode-specific configuration goes inside
-# the $configScript argument to this function, and that an auto.def file
-# contains only two commands:
+# The intent is that all (or almost all) build-mode-specific
+# configuration goes inside the $configScript argument to this
+# function, and that an auto.def file contains only two commands:
#
# use sqlite-config
# sqlite-configure BUILD_NAME { build-specific configure script }
+#
+# There are snippets of build-mode-specific decision-making in
+# [sqlite-configure-finalize]
proc sqlite-configure {buildMode configScript} {
+ proj-assert {$::sqliteConfig(build-mode) eq "unknown"} \
+ "sqlite-configure must not be called more than once"
set allBuildModes {canonical autoconf}
if {$buildMode ni $allBuildModes} {
user-error "Invalid build mode: $buildMode. Expecting one of: $allBuildModes"
@@ -173,11 +179,6 @@ proc sqlite-configure {buildMode configScript} {
{*} {
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
- largefile=1
- => {This legacy flag has no effect on the library but may influence
- the contents of the generated sqlite_cfg.h}
- # ^^^ It's not clear that LFS support actually does anything,
- # as HAVE_LFS is not checked anywhere in the .c/.h/.in files.
load-extension=1 => {Disable loading of external extensions}
math=1 => {Disable math functions}
json=1 => {Disable JSON functions}
@@ -191,6 +192,9 @@ proc sqlite-configure {buildMode configScript} {
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
+ largefile=1
+ => {This legacy flag has no effect on the library but may influence
+ the generated sqlite_cfg.h by adding #define HAVE_LFS}
}
}
@@ -259,11 +263,11 @@ proc sqlite-configure {buildMode configScript} {
# Options for exotic/alternative build modes
alternative-builds {
- {canonical} {
- # Potential TODO: add --with-wasi-sdk support to the autoconf
- # build
+ {*} {
with-wasi-sdk:=/opt/wasi-sdk
=> {Top-most dir of the wasi-sdk for a WASI build}
+ }
+ {canonical} {
with-emsdk:=auto
=> {Top-most dir of the Emscripten SDK installation.
@@ -338,6 +342,10 @@ proc sqlite-configure {buildMode configScript} {
=> {Enable #line macros in the amalgamation}
dynlink-tools
=> {Dynamically link libsqlite3 to certain tools which normally statically embed it}
+ asan-fsanitize:=auto
+ => {Comma- or space-separated list of -fsanitize flags for use with the
+ fuzzcheck-asan tool. Only those which the compiler claims to support
+ will actually be used. May be provided multiple times.}
}
{*} {
dump-defines=0
@@ -367,85 +375,17 @@ proc sqlite-configure {buildMode configScript} {
dict incr xopts -level
return {*}$xopts $msg
}
- sqlite-post-options-init
+ sqlite-configure-phase1 $buildMode
uplevel 1 $configScript
sqlite-configure-finalize
}; # sqlite-configure
########################################################################
-# Performs late-stage config steps common to all supported
-# $::sqliteConfig(build-mode) values.
-proc sqlite-configure-finalize {} {
- set buildMode $::sqliteConfig(build-mode)
- set isCanonical [expr {$buildMode eq "canonical"}]
- set isAutoconf [expr {$buildMode eq "autoconf"}]
- proj-assert {$isCanonical || $isAutoconf} "Unknown build mode: $buildMode"
-
- define HAVE_LFS 0
- if {[opt-bool largefile]} {
- #
- # Insofar as we can determine HAVE_LFS has no effect on the
- # library. Perhaps it did back in the early 2000's. The
- # --enable/disable-largefile flag is retained because it's
- # harmless, but it doesn't do anything useful. It does have
- # visible side-effects, though: the generated sqlite_cfg.h may (or
- # may not) define HAVE_LFS.
- #
- cc-check-lfs
- }
-
- if {$isCanonical} {
- if {![opt-bool static]} {
- proj-indented-notice {
- NOTICE: static lib build may be implicitly re-activated by
- other components, e.g. some test apps.
- }
- }
- } else {
- proj-assert { $isAutoconf } "Invalid build mode"
- proj-define-for-opt static-shell ENABLE_STATIC_SHELL \
- "Link library statically into the CLI shell?"
- if {![opt-bool shared] && ![opt-bool static-shell]} {
- proj-opt-set shared 1
- proj-indented-notice {
- NOTICE: ignoring --disable-shared because --disable-static-shell
- was specified.
- }
- }
- }
- proj-define-for-opt shared ENABLE_LIB_SHARED "Build shared library?"
- proj-define-for-opt static ENABLE_LIB_STATIC "Build static library?"
-
- sqlite-handle-debug
- sqlite-handle-rpath
- sqlite-handle-soname
- sqlite-handle-threadsafe
- sqlite-handle-tempstore
- sqlite-handle-line-editing
- sqlite-handle-load-extension
- sqlite-handle-math
- sqlite-handle-icu
- sqlite-handle-env-quirks
- sqlite-handle-common-feature-flags
- sqlite-finalize-feature-flags
- ########################################################################
- # When cross-compiling, we have to avoid using the -s flag to
- # /usr/bin/install:
- # https://sqlite.org/forum/forumpost/9a67df63eda9925c
- define IS_CROSS_COMPILING $::sqliteConfig(is-cross-compiling)
- sqlite-process-dot-in-files
- sqlite-post-config-validation
- sqlite-dump-defines
-}; # sqlite-configure-finalize
-
-########################################################################
-# Runs some common initialization which must happen immediately after
-# autosetup's [options] function is called. This is also a convenient
-# place to put some generic pieces common to both the canonical
-# top-level build and the "autoconf" build, but it's not intended to
-# be a catch-all dumping ground for such.
-proc sqlite-post-options-init {} {
- define PACKAGE_NAME "sqlite"
+# Runs "phase 1" of the configure process: after initial --flags
+# handling but before the build-specific parts are run. $buildMode
+# must be the mode which was passed to [sqlite-configure].
+proc sqlite-configure-phase1 {buildMode} {
+ define PACKAGE_NAME sqlite
define PACKAGE_URL {https://sqlite.org}
define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum
define PACKAGE_STRING "[get-define PACKAGE_NAME] [get-define PACKAGE_VERSION]"
@@ -457,6 +397,8 @@ proc sqlite-post-options-init {} {
with-readline-lib => with-readline-ldflags
with-debug => debug
}
+ set ::sqliteConfig(msg-debug-enabled) [proj-val-truthy [get-env msg-debug 0]]
+ proc-debug "msg-debug is enabled"
sqlite-autoreconfig
proj-file-extensions
if {".exe" eq [get-define TARGET_EXEEXT]} {
@@ -466,8 +408,49 @@ proc sqlite-post-options-init {} {
define SQLITE_OS_UNIX 1
define SQLITE_OS_WIN 0
}
- set ::sqliteConfig(msg-debug-enabled) [proj-val-truthy [get-env msg-debug 0]]
sqlite-setup-default-cflags
+ sqlite-handle-debug
+ define HAVE_LFS 0
+ if {[opt-bool largefile]} {
+ #
+ # Insofar as we can determine HAVE_LFS has no effect on the
+ # library. Perhaps it did back in the early 2000's. The
+ # --enable/disable-largefile flag is retained because it's
+ # harmless, but it doesn't do anything useful. It does have
+ # visible side-effects, though: the generated sqlite_cfg.h may (or
+ # may not) define HAVE_LFS.
+ cc-check-lfs
+ }
+}; # sqlite-configure-phase1
+
+########################################################################
+# Performs late-stage config steps common to all supported
+# $::sqliteConfig(build-mode) values.
+proc sqlite-configure-finalize {} {
+ sqlite-handle-rpath
+ sqlite-handle-soname
+ sqlite-handle-threadsafe
+ sqlite-handle-tempstore
+ sqlite-handle-load-extension
+ sqlite-handle-math
+ sqlite-handle-icu
+ sqlite-handle-line-editing
+
+ proj-define-for-opt shared ENABLE_LIB_SHARED "Build shared library?"
+ if {![proj-define-for-opt static ENABLE_LIB_STATIC "Build static library?"]} {
+ # This notice really only applies to the canonical build...
+ proj-indented-notice {
+ NOTICE: static lib build may be implicitly re-activated by
+ other components, e.g. some test apps.
+ }
+ }
+
+ sqlite-handle-env-quirks
+ sqlite-handle-common-feature-flags
+ sqlite-finalize-feature-flags
+ sqlite-process-dot-in-files; # do not [define] anything after this
+ sqlite-post-config-validation
+ sqlite-dump-defines
}
########################################################################
@@ -478,6 +461,13 @@ proc msg-debug {msg} {
puts stderr [proj-bold "** DEBUG: $msg"]
}
}
+########################################################################
+# A [msg-debug] proxy which prepends the name of the current proc to
+# the debug message. It is not legal to call this from the global
+# scope.
+proc proc-debug {msg} {
+ msg-debug "\[[proj-current-proc-name 1]\]: $msg"
+}
########################################################################
# Sets up the SQLITE_AUTORECONFIG define.
@@ -558,6 +548,10 @@ proc sqlite-check-common-bins {} {
########################################################################
# Run checks for system-level includes and libs which are common to
# both the canonical build and the "autoconf" bundle.
+#
+# For the canonical build this must come after
+# [sqlite-handle-wasi-sdk], as that function may change the
+# environment in ways which affect this.
proc sqlite-check-common-system-deps {} {
# Check for needed/wanted data types
cc-with {-includes stdint.h} \
@@ -668,7 +662,7 @@ proc sqlite-setup-default-cflags {} {
}
########################################################################
-# Handle various SQLITE_ENABLE_... feature flags.
+# Handle various SQLITE_ENABLE/OMIT_... feature flags.
proc sqlite-handle-common-feature-flags {} {
msg-result "Feature flags..."
foreach {boolFlag featureFlag ifSetEvalThis} {
@@ -728,7 +722,6 @@ proc sqlite-handle-common-feature-flags {} {
msg-result " - $boolFlag"
}
}
-
}
#########################################################################
@@ -752,13 +745,12 @@ proc sqlite-finalize-feature-flags {} {
}
########################################################################
-# Checks for the --debug flag, defining SQLITE_DEBUG to 1 if it is
-# true. TARGET_DEBUG gets defined either way, with content depending
-# on whether --debug is true or false.
+# Checks for the --debug flag and [define]s TARGET_DEBUG based on
+# that. TARGET_DEBUG is unused in the autoconf build but that is
+# arguably a bug.
proc sqlite-handle-debug {} {
msg-checking "SQLITE_DEBUG build? "
proj-if-opt-truthy debug {
- define SQLITE_DEBUG 1
define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall}
proj-opt-set memsys5
msg-result yes
@@ -794,7 +786,7 @@ proc sqlite-handle-soname {} {
}
}
}
- msg-debug "soname=$soname"
+ proc-debug "soname=$soname"
if {[proj-check-soname $soname]} {
define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname
msg-result "Setting SONAME using: [get-define LDFLAGS_LIBSQLITE3_SONAME]"
@@ -925,6 +917,11 @@ proc sqlite-handle-emsdk {} {
########################################################################
# Internal helper for [sqlite-check-line-editing]. Returns a list of
# potential locations under which readline.h might be found.
+#
+# On some environments this function may perform extra work to help
+# sqlite-check-line-editing figure out how to find libreadline and
+# friends. It will communicate those results via means other than the
+# result value, e.g. by modifying configure --flags.
proc sqlite-get-readline-dir-list {} {
# Historical note: the dirs list, except for the inclusion of
# $prefix and some platform-specific dirs, originates from the
@@ -941,13 +938,24 @@ proc sqlite-get-readline-dir-list {} {
*-mingw64 {
lappend dirs /mingw64 /mingw
}
+ *-haiku {
+ lappend dirs /boot/system/develop/headers
+ if {[opt-val with-readline-ldflags] in {auto ""}} {
+ # If the user did not supply their own --with-readline-ldflags
+ # value, hijack that flag to inject options which are known to
+ # work on a default Haiku installation.
+ if {"" ne [glob -nocomplain /boot/system/lib/libreadline*]} {
+ proj-opt-set with-readline-ldflags {-L/boot/system/lib -lreadline}
+ }
+ }
+ }
}
lappend dirs /usr /usr/local /usr/local/readline /usr/contrib
set rv {}
foreach d $dirs {
if {[file isdir $d]} {lappend rv $d}
}
- #msg-debug "sqlite-get-readline-dir-list dirs=$rv"
+ #proc-debug "dirs=$rv"
return $rv
}
@@ -1088,7 +1096,9 @@ proc sqlite-check-line-editing {} {
proj-warn "Skipping check for readline.h because we're cross-compiling."
} else {
set dirs [sqlite-get-readline-dir-list]
- set subdirs "include/$editLibName"
+ set subdirs [list \
+ include/$editLibName \
+ readline]
if {"editline" eq $editLibName} {
lappend subdirs include/readline
# ^^^ editline, on some systems, does not have its own header,
@@ -1096,7 +1106,8 @@ proc sqlite-check-line-editing {} {
}
lappend subdirs include
set rlInc [proj-search-for-header-dir readline.h \
- -dirs $dirs -subdirs $subdirs]
+ -dirs $dirs -subdirs $subdirs]
+ #proc-debug "rlInc=$rlInc"
if {"" ne $rlInc} {
if {[string match */readline $rlInc]} {
set rlInc [file dirname $rlInc]; # CLI shell: #include
@@ -1121,7 +1132,8 @@ proc sqlite-check-line-editing {} {
set rlLib ""
if {"" ne $rlInc} {
set rlLib [opt-val with-readline-ldflags]
- if {$rlLib eq "auto" || $rlLib eq ""} {
+ #proc-debug "rlLib=$rlLib"
+ if {$rlLib in {auto ""}} {
set rlLib ""
set libTerm ""
if {[proj-check-function-in-lib tgetent "$editLibName ncurses curses termcap"]} {
@@ -1231,7 +1243,7 @@ proc sqlite-handle-icu {} {
msg-result "Checking for ICU support..."
set icuConfigBin [opt-val with-icu-config]
set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
- if {"auto" eq $icuConfigBin || "pkg-config" eq $icuConfigBin} {
+ if {$icuConfigBin in {auto pkg-config}} {
if {[pkg-config-init 0] && [pkg-config icu-io]} {
# Maintenance reminder: historical docs say to use both of
# (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
@@ -1285,7 +1297,9 @@ proc sqlite-handle-icu {} {
if {[opt-bool icu-collations]} {
msg-result "Enabling ICU collations."
sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS
- # Recall that shell.c builds with sqlite3.c
+ # Recall that shell.c builds with sqlite3.c except in the case
+ # of --disable-static-shell, a combination we do not
+ # specifically attempt to account for.
}
} elseif {[opt-bool icu-collations]} {
proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
@@ -1355,7 +1369,7 @@ proc sqlite-handle-math {} {
define LDFLAGS_MATH [get-define lib_ceil]
undefine lib_ceil
sqlite-add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS}
- msg-result "Enabling math SQL functions [get-define LDFLAGS_MATH]"
+ msg-result "Enabling math SQL functions"
} {
define LDFLAGS_MATH ""
msg-result "Disabling math SQL functions"
@@ -1428,7 +1442,7 @@ proc sqlite-handle-dll-basename {} {
# The name of the import library is [define]d in SQLITE_OUT_IMPLIB.
#
# If the configure flag --out-implib is not used (or programmatically
-# set) then this is a no-op (but see [sqliet-handle-env-quirks]). If
+# set) then this is a no-op (but see [sqlite-handle-env-quirks]). If
# that flag is used but the capability is not available, a fatal error
# is triggered.
#
@@ -1507,7 +1521,7 @@ proc sqlite-env-is-unix-on-windows {{envTuple ""}} {
#
# [define]s SQLITE_DLL_INSTALL_RULES to a symbolic name suffix for a
# set of "make install" rules to use for installation of the DLL
-# deliverable. The makefile is tasked with with providing rules named
+# deliverable. The makefile is tasked with providing rules named
# install-dll-NAME which runs the installation for that set, as well
# as providing a rule named install-dll which resolves to
# install-dll-NAME (perhaps indirectly, depending on whether the DLL
@@ -1519,13 +1533,13 @@ proc sqlite-env-is-unix-on-windows {{envTuple ""}} {
#
# On platforms where an "import library" is conventionally used but
# --out-implib was not explicitly used, automatically add that flag.
-# This conventionally applies to the "Unix on Windows" environments
-# like msys and cygwin.
+# This conventionally applies only to the "Unix on Windows"
+# environments like msys and cygwin.
#
# 3) --dll-basename:
#
# On the same platforms addressed by --out-implib, if --dll-basename
-# is not specified, --dll-basename=auto is implied.
+# is not explicitly specified, --dll-basename=auto is implied.
proc sqlite-handle-env-quirks {} {
set instName unix-generic; # name of installation rules set
set autoDll 0; # true if --out-implib/--dll-basename should be implied
@@ -1651,7 +1665,8 @@ proc sqlite-handle-wasi-sdk {} {
tcl
threadsafe
} {
- if {[opt-bool $opt]} {
+ if {[proj-opt-exists $opt] && [opt-bool $opt]} {
+ # -^^^^ distinguish between canonical and autoconf builds
msg-result " --disable-$opt"
proj-opt-set $opt 0
}
@@ -1754,14 +1769,14 @@ proc sqlite-check-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"
+ proc-debug "use_tcl ${use_tcl}"
+ proc-debug "with_tclsh=${with_tclsh}"
+ proc-debug "with_tcl=$with_tcl"
if {"" eq $with_tclsh && "" eq $with_tcl} {
# If neither --with-tclsh nor --with-tcl are provided, try to find
# a workable tclsh.
set with_tclsh [proj-first-bin-of tclsh9.0 tclsh8.6 tclsh]
- msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}"
+ proc-debug "with_tclsh=${with_tclsh}"
}
set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases
diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c
index d7574aec52..0a9b08ed15 100644
--- a/ext/fts5/fts5_expr.c
+++ b/ext/fts5/fts5_expr.c
@@ -2015,7 +2015,8 @@ void sqlite3Fts5ParseSetDistance(
);
return;
}
- nNear = nNear * 10 + (p->p[i] - '0');
+ if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0');
+ /* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
}
}else{
nNear = FTS5_DEFAULT_NEARDIST;
diff --git a/ext/misc/series.c b/ext/misc/series.c
index 04644dd603..e8188f1c97 100644
--- a/ext/misc/series.c
+++ b/ext/misc/series.c
@@ -60,8 +60,7 @@
** step HIDDEN
** );
**
-** The virtual table also has a rowid, logically equivalent to n+1 where
-** "n" is the ascending integer in the aforesaid production definition.
+** The virtual table also has a rowid which is an alias for the value.
**
** Function arguments in queries against this virtual table are translated
** into equality constraints against successive hidden columns. In other
@@ -276,6 +275,7 @@ static int seriesConnect(
int rc;
/* Column numbers */
+#define SERIES_COLUMN_ROWID (-1)
#define SERIES_COLUMN_VALUE 0
#define SERIES_COLUMN_START 1
#define SERIES_COLUMN_STOP 2
@@ -363,13 +363,11 @@ static int seriesColumn(
#endif
/*
-** Return the rowid for the current row, logically equivalent to n+1 where
-** "n" is the ascending integer in the aforesaid production definition.
+** The rowid is the same as the value.
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
series_cursor *pCur = (series_cursor*)cur;
- sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
- *pRowid = (sqlite3_int64)((nss.iValueNow;
return SQLITE_OK;
}
@@ -657,7 +655,10 @@ static int seriesBestIndex(
continue;
}
if( pConstraint->iColumniColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){
+ if( (pConstraint->iColumn==SERIES_COLUMN_VALUE ||
+ pConstraint->iColumn==SERIES_COLUMN_ROWID)
+ && pConstraint->usable
+ ){
switch( op ){
case SQLITE_INDEX_CONSTRAINT_EQ:
case SQLITE_INDEX_CONSTRAINT_IS: {
diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js
index 95843a35dc..73426f2039 100644
--- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js
+++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js
@@ -79,6 +79,48 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
capi.SQLITE_OPEN_MAIN_JOURNAL |
capi.SQLITE_OPEN_SUPER_JOURNAL |
capi.SQLITE_OPEN_WAL;
+ const FLAG_COMPUTE_DIGEST_V2 = capi.SQLITE_OPEN_MEMORY
+ /* Part of the fix for
+ https://github.com/sqlite/sqlite-wasm/issues/97
+
+ Summary: prior to version 3.50.0 computeDigest() always computes
+ a value of [0,0] due to overflows, so it does not do anything
+ useful. Fixing it invalidates old persistent files, so we
+ instead only fix it for files created or updated since the bug
+ was discovered and fixed.
+
+ This flag determines whether we use the broken legacy
+ computeDigest() or the v2 variant. We only use this flag for
+ newly-created/overwritten files. Pre-existing files have the
+ broken digest stored in them so need to continue to use that.
+
+ What this means, in terms of db file compatibility between
+ versions:
+
+ - DBs created with versions older than this fix (<3.50.0)
+ can be read by post-fix versions. Such DBs which are written
+ to in-place (not replaced) by newer versions can still be read
+ by older versions, as the affected digest is only modified
+ when the SAH slot is assigned to a given filename.
+
+ - DBs created with post-fix versions will, when read by a pre-fix
+ version, be seen as having a "bad digest" and will be
+ unceremoniously replaced by that pre-fix version. When swapping
+ back to a post-fix version, that version will see that the file
+ entry is missing the FLAG_COMPUTE_DIGEST_V2 bit so will treat it
+ as a legacy file.
+
+ This flag is stored in the same memory as the various
+ SQLITE_OPEN_... flags and we must be careful here to not use a
+ flag bit which is otherwise relevant for the VFS.
+ SQLITE_OPEN_MEMORY is handled by sqlite3_open_v2() and friends,
+ not the VFS, so we'll repurpose that one. If we take a
+ currently-unused bit and it ends up, at some later point, being
+ used, we would have to invalidate existing VFS files in order to
+ move to another bit. Similarly, if the SQLITE_OPEN_MEMORY bit
+ were ever reassigned (which it won't be!), we'd invalidate all
+ VFS-side files.
+ */;
/** Subdirectory of the VFS's space where "opaque" (randomly-named)
files are stored. Changing this effectively invalidates the data
@@ -329,6 +371,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
const pool = getPoolForVfs(pVfs);
try{
+ flags &= ~FLAG_COMPUTE_DIGEST_V2;
pool.log(`xOpen ${wasm.cstrToJs(zName)} ${flags}`);
// First try to open a path that already exists in the file system.
const path = (zName && wasm.peek8(zName))
@@ -624,7 +667,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const fileDigest = new Uint32Array(HEADER_DIGEST_SIZE / 4);
sah.read(fileDigest, {at: HEADER_OFFSET_DIGEST});
- const compDigest = this.computeDigest(this.#apBody);
+ const compDigest = this.computeDigest(this.#apBody, flags);
+ //warn("getAssociatedPath() flags",'0x'+flags.toString(16), "compDigest", compDigest);
if(fileDigest.every((v,i) => v===compDigest[i])){
// Valid digest
const pathBytes = this.#apBody.findIndex((v)=>0===v);
@@ -633,6 +677,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
// leaving stale db data laying around.
sah.truncate(HEADER_OFFSET_DATA);
}
+ //warn("getAssociatedPath() flags",'0x'+flags.toString(16), "compDigest", compDigest,"pathBytes",pathBytes);
return pathBytes
? textDecoder.decode(this.#apBody.subarray(0,pathBytes))
: '';
@@ -655,10 +700,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
if(HEADER_MAX_PATH_SIZE <= enc.written + 1/*NUL byte*/){
toss("Path too long:",path);
}
+ if(path && flags){
+ /* When creating or re-writing files, update their digest, if
+ needed, to v2. We continue to use v1 for the (!path) case
+ (empty files) because there's little reason not to use a
+ digest of 0 for empty entries. */
+ flags |= FLAG_COMPUTE_DIGEST_V2;
+ }
this.#apBody.fill(0, enc.written, HEADER_MAX_PATH_SIZE);
this.#dvBody.setUint32(HEADER_OFFSET_FLAGS, flags);
-
- const digest = this.computeDigest(this.#apBody);
+ const digest = this.computeDigest(this.#apBody, flags);
+ //console.warn("setAssociatedPath(",path,") digest",digest);
sah.write(this.#apBody, {at: 0});
sah.write(digest, {at: HEADER_OFFSET_DIGEST});
sah.flush();
@@ -679,15 +731,22 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
metadata for each file as a validation check. Changing this
algorithm invalidates all existing databases for this VFS, so
don't do that.
+
+ See the docs for FLAG_COMPUTE_DIGEST_V2 for more details.
*/
- computeDigest(byteArray){
- let h1 = 0xdeadbeef;
- let h2 = 0x41c6ce57;
- for(const v of byteArray){
- h1 = 31 * h1 + (v * 307);
- h2 = 31 * h2 + (v * 307);
+ computeDigest(byteArray, fileFlags){
+ if( fileFlags & FLAG_COMPUTE_DIGEST_V2 ){
+ let h1 = 0xdeadbeef;
+ let h2 = 0x41c6ce57;
+ for(const v of byteArray){
+ h1 = Math.imul(h1 ^ v, 2654435761);
+ h2 = Math.imul(h2 ^ v, 104729);
+ }
+ return new Uint32Array([h1>>>0, h2>>>0]);
+ }else{
+ /* this is what the buggy legacy computation worked out to */
+ return new Uint32Array([0,0]);
}
- return new Uint32Array([h1>>>0, h2>>>0]);
}
/**
diff --git a/ext/wasm/mkwasmbuilds.c b/ext/wasm/mkwasmbuilds.c
index e3cd34b00d..d13302769e 100644
--- a/ext/wasm/mkwasmbuilds.c
+++ b/ext/wasm/mkwasmbuilds.c
@@ -45,6 +45,7 @@
** "sqlite3-wasmfs" build, only "esm" (ES6 Module) is legal.
*/
#define JS_BUILD_MODES vanilla esm bundler-friendly node
+/* Separator to help eyeballs find the different sections */
static const char * zBanner =
"\n########################################################################\n";
@@ -140,8 +141,8 @@ static void mk_prologue(void){
** mk_lib_mode().
**
** Maintenance reminder: do not combine flags within this enum,
-** e.g. LIBMODE_BUNDLER_FRIEND=0x02|LIBMODE_ESM, as that will lead to
-** breakage in some of the flag checks.
+** e.g. LIBMODE_BUNDLER_FRIENDLY=0x02|LIBMODE_ESM, as that will lead
+** to breakage in some of the flag checks.
*/
enum LibModeFlags {
/* Indicates an ESM module build. */
@@ -208,7 +209,7 @@ static void mk_pre_post(const char *zName /* build name */,
pf("$(eval $(call SQLITE.CALL.C-PP.FILTER,$(extern-post-js.js.in),$(extern-post-js.js.%s-%s),"
"$(c-pp.D.%s-%s)))\n", zNM, zNM);
- /* Combine flags for use with emcc... */
+ /* Combined flags for use with emcc... */
pf("pre-post-common.flags.%s-%s := "
"$(pre-post-common.flags) "
"--post-js=$(post-js.js.%s-%s) "
diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js
index 8638845a76..d30e59e38c 100644
--- a/ext/wasm/tester1.c-pp.js
+++ b/ext/wasm/tester1.c-pp.js
@@ -3506,7 +3506,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
});
db.exec([
"create table t(a);",
- "insert into t(a) values(1),(2),(3);",
+ "insert into t(a) values(1),(2),(1);",
"select auxtest(1,a), auxtest(1,a) from t order by a"
]);
}finally{
diff --git a/ext/wasm/tests/opfs/sahpool/digest-worker.js b/ext/wasm/tests/opfs/sahpool/digest-worker.js
new file mode 100644
index 0000000000..28b3c1673f
--- /dev/null
+++ b/ext/wasm/tests/opfs/sahpool/digest-worker.js
@@ -0,0 +1,94 @@
+/*
+ 2025-01-31
+
+ The author disclaims copyright to this source code. In place of a
+ legal notice, here is a blessing:
+
+ * May you do good and not evil.
+ * May you find forgiveness for yourself and forgive others.
+ * May you share freely, never taking more than you give.
+
+ ***********************************************************************
+
+ This file is part of testing the OPFS SAHPool VFS's computeDigest()
+ fix. See ./digest.html for the details.
+*/
+const clog = console.log.bind(console);
+const wPost = (type,...args)=>postMessage({type, payload:args});
+const log = (...args)=>{
+ clog("Worker:",...args);
+ wPost('log',...args);
+}
+
+const hasOpfs = ()=>{
+ return globalThis.FileSystemHandle
+ && globalThis.FileSystemDirectoryHandle
+ && globalThis.FileSystemFileHandle
+ && globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle
+ && navigator?.storage?.getDirectory;
+};
+if( !hasOpfs() ){
+ wPost('error',"OPFS not detected");
+ throw new Error("OPFS not detected");
+}
+
+clog("Importing sqlite3...");
+const searchParams = new URL(self.location.href).searchParams;
+importScripts(searchParams.get('sqlite3.dir') + '/sqlite3.js');
+
+const runTests = function(sqlite3, poolUtil){
+ const fname = '/my.db';
+ let db = new poolUtil.OpfsSAHPoolDb(fname);
+ let n = (new Date()).valueOf();
+ try {
+ db.exec([
+ "create table if not exists t(a);"
+ ]);
+ db.exec({
+ sql: "insert into t(a) values(?)",
+ bind: n++
+ });
+ log(fname,"record count: ",db.selectValue("select count(*) from t"));
+ }finally{
+ db.close();
+ }
+
+ db = new poolUtil.OpfsSAHPoolDb(fname);
+ try {
+ db.exec({
+ sql: "insert into t(a) values(?)",
+ bind: n++
+ });
+ log(fname,"record count: ",db.selectValue("select count(*) from t"));
+ }finally{
+ db.close();
+ }
+
+ const fname2 = '/my2.db';
+ db = new poolUtil.OpfsSAHPoolDb(fname2);
+ try {
+ db.exec([
+ "create table if not exists t(a);"
+ ]);
+ db.exec({
+ sql: "insert into t(a) values(?)",
+ bind: n++
+ });
+ log(fname2,"record count: ",db.selectValue("select count(*) from t"));
+ }finally{
+ db.close();
+ }
+};
+
+globalThis.sqlite3InitModule().then(async function(sqlite3){
+ log("sqlite3 version:",sqlite3.version);
+ const sahPoolConfig = {
+ name: 'opfs-sahpool-digest',
+ clearOnInit: false,
+ initialCapacity: 6
+ };
+ return sqlite3.installOpfsSAHPoolVfs(sahPoolConfig).then(poolUtil=>{
+ log('vfs acquired');
+ runTests(sqlite3, poolUtil);
+ });
+});
diff --git a/ext/wasm/tests/opfs/sahpool/digest.html b/ext/wasm/tests/opfs/sahpool/digest.html
new file mode 100644
index 0000000000..daa1f77287
--- /dev/null
+++ b/ext/wasm/tests/opfs/sahpool/digest.html
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+ sqlite3 tester: OpfsSAHPool Digest
+
+
+
+
+
+ This is a test app for the digest calculation of the OPFS
+ SAHPool VFS. It requires running it with a new database created using
+ v3.49.0 or older, then running it again with a newer version, then
+ again with 3.49.0 or older.
+
+
+
+
+
+
+
+
+
diff --git a/main.mk b/main.mk
index 0b42a41113..d153267792 100644
--- a/main.mk
+++ b/main.mk
@@ -187,6 +187,9 @@ CFLAGS.readline ?= -I$(prefix)/include
# during installation, which may break the build of targets which are
# built after others are installed.
#
+# Maintenance reminder: we specifically do not strip binaries, as
+# discussed in https://sqlite.org/forum/forumpost/9a67df63eda9925c.
+#
INSTALL ?= install
#
# $(ENABLE_LIB_SHARED) =
@@ -2170,10 +2173,10 @@ fuzzy: fuzzcheck$(T.exe)
xbin: fuzzcheck$(T.exe)
# -fsanitize=... flags for fuzzcheck-asan.
-CFLAGS.fuzzcheck.fsanitize ?= -fsanitize=address
+CFLAGS.fuzzcheck-asan.fsanitize ?= -fsanitize=address
fuzzcheck-asan$(T.exe): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP)
- $(T.link) -o $@ $(CFLAGS.fuzzcheck.fsanitize) $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \
+ $(T.link) -o $@ $(CFLAGS.fuzzcheck-asan.fsanitize) $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \
sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: fuzzcheck-asan$(T.exe)
xbin: fuzzcheck-asan$(T.exe)
@@ -2193,11 +2196,110 @@ xbin: fuzzcheck-ubsan$(T.exe)
#
# FUZZDB=test/fuzzdata*.db make run-fuzzcheck
#
-run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe)
+# The original rules for this target were like this:
+#
+# run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe)
+# @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi
+# ./fuzzcheck$(T.exe) --spinner $(FUZZDB)
+# ./fuzzcheck-asan$(T.exe) --spinner $(FUZZDB)
+# ./fuzzcheck-ubsan$(T.exe) --spinner $(FUZZDB)
+#
+# What follows is a decomposition of these rules in a way that allows make
+# to run things in parallel when using the -jN option.
+#
+FUZZDB-check:
@if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi
- ./fuzzcheck$(T.exe) --spinner $(FUZZDB)
- ./fuzzcheck-asan$(T.exe) --spinner $(FUZZDB)
- ./fuzzcheck-ubsan$(T.exe) --spinner $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n0
+run-fuzzcheck-n0: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 0 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n1
+run-fuzzcheck-n1: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 1 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n2
+run-fuzzcheck-n2: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 2 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n3
+run-fuzzcheck-n3: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 3 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n4
+run-fuzzcheck-n4: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 4 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n5
+run-fuzzcheck-n5: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 5 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n6
+run-fuzzcheck-n6: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 6 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n7
+run-fuzzcheck-n7: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 7 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n8
+run-fuzzcheck-n8: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 8 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-n9
+run-fuzzcheck-n9: FUZZDB-check fuzzcheck$(T.exe)
+ ./fuzzcheck$(T.exe) --slice 9 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a0
+run-fuzzcheck-a0: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 0 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a1
+run-fuzzcheck-a1: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 1 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a2
+run-fuzzcheck-a2: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 2 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a3
+run-fuzzcheck-a3: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 3 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a4
+run-fuzzcheck-a4: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 4 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a5
+run-fuzzcheck-a5: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 5 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a6
+run-fuzzcheck-a6: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 6 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a7
+run-fuzzcheck-a7: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 7 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a8
+run-fuzzcheck-a8: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 8 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-a9
+run-fuzzcheck-a9: FUZZDB-check fuzzcheck-asan$(T.exe)
+ ./fuzzcheck-asan$(T.exe) --slice 9 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u0
+run-fuzzcheck-u0: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 0 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u1
+run-fuzzcheck-u1: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 1 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u2
+run-fuzzcheck-u2: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 2 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u3
+run-fuzzcheck-u3: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 3 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u4
+run-fuzzcheck-u4: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 4 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u5
+run-fuzzcheck-u5: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 5 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u6
+run-fuzzcheck-u6: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 6 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u7
+run-fuzzcheck-u7: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 7 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u8
+run-fuzzcheck-u8: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 8 10 $(FUZZDB)
+run-fuzzcheck: run-fuzzcheck-u9
+run-fuzzcheck-u9: FUZZDB-check fuzzcheck-ubsan$(T.exe)
+ ./fuzzcheck-ubsan$(T.exe) --slice 9 10 $(FUZZDB)
+
ossshell$(T.exe): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
diff --git a/manifest b/manifest
index ad8cf6691c..1f26fd4554 100644
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\swal2\sbranch.
-D 2025-03-15T20:28:42.705
+D 2025-03-22T14:19:11.153
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
-F Makefile.in 2788f5a3c36e26817707003170871936d44f46c5b45f8cbefe07c9f1a51a8988
+F Makefile.in 86cc5297495fd5ce632cd7ec298c562900f874eef42c44d5890bd22397bb3820
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc e21d24292743154ff41a1fa7d8b7d5fb5005581af89231d3197395bb7654953e
F README.md a953c0cffd6e4f2501a306c00ee2b6e1e6630c25031e094629307fe99dd003d1
@@ -14,13 +14,13 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531
-F auto.def 619383263dfd0ee31df6a9d3e9828f65943d9fbcd274084046680641e5de53cb
+F auto.def f769bf3111089ee9471a2a872c47651c4e29e81d104a52867ab544fde5ef6bad
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
-F autoconf/Makefile.in 6c98c82f52aa27a5c586080cf7c61c811174c2b6d8b8de33fd657d78d541dd7d
+F autoconf/Makefile.in 1fe497c0df20102f7824ec8a3423cc13c26505655456ecd06a7a8ab02f606586
F autoconf/Makefile.msc 5bc67d3912444c40c6f96d003e5c90663e51abb83d204a520110b1b2038dcd8b
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
F autoconf/README.txt 1a32296d8bbdd67110c79d224c92c05545a0b5bd0c272950025fe3c7c7b49580
-F autoconf/auto.def 8d81c1d728d8462a9b6c1ca0714013bbb097aee0ae5e79309d7939cead98e295
+F autoconf/auto.def 4cb3c39042039bb852034dc1a9d42717d42eef759a687a664ad283db8e6b816e
F autoconf/tea/Makefile.in ba0556fee8da09c066bad85a4457904e46ee2c2eabaa309c0e83a78f2f151a8e
F autoconf/tea/README.txt 6c396709b45eb2b3be0ae6dc7e40a140d231962e3a2354da6c4dd48b1d9999bc
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
@@ -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 b306314e8a87ccf873cb5b2a360c4a27bbf841df5b76f3acbd65322cff165476
+F autosetup/README.md f98cc827a162a1da4877e9656d749d414ba3f408d457d30e029afc66590c00c3
F autosetup/autosetup 74a9782b68d07934510190fbd03fc6ad92e63f0ea3b5cbffa5f0bd271ad60f01 x
F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x
F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x
@@ -49,8 +49,8 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d
F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f
F autosetup/jimsh0.c a57c16e65dcffc9c76e496757cb3f7fb47e01ecbd1631a0a5e01751fc856f049
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
-F autosetup/proj.tcl bacaf1ed827067942a6d33f2a5c95bd649ceacae2a8ddc584d0f74456fb9167e
-F autosetup/sqlite-config.tcl a7f4d093d63bc1da9ec3d44f392f377ce4c86aa7e48532ae51619e55558f5fbe
+F autosetup/proj.tcl 49faf960df88a374686234105def663dbfc297ab79c87686df0a0b973dd77018
+F autosetup/sqlite-config.tcl 6e1dce27dfb69910bc28c3d3d4e33470fffc3c68f1d6a87799d34a2cc27f79dd
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
F contrib/sqlitecon.tcl eb4c6578e08dd353263958da0dc620f8400b869a50d06e271ab0be85a51a08d3
@@ -111,7 +111,7 @@ F ext/fts5/fts5Int.h bffbd0acdcdf509899681f4e1cfeef1c955030acd9fe15ff9082410f80c
F ext/fts5/fts5_aux.c da4a7a9a11ec15c6df0699d908915a209bcde48f0b04101461316b59f71abffb
F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d7c53066c7
F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8
-F ext/fts5/fts5_expr.c 887a611b34094c828ff5fb19bbc50a6b1bbfd28791db01b0c8bf722e3c9f437a
+F ext/fts5/fts5_expr.c be9e5f7f11d87e7bd3680832c93c13050fe351994b5052b0215c2ef40312c23a
F ext/fts5/fts5_hash.c a6266cedd801ab7964fa9e74ebcdda6d30ec6a96107fa24148ec6b7b5b80f6e0
F ext/fts5/fts5_index.c d171f2a507abccb3d524bf461b01f0d3971a9bf221be622ac7c671a991cb62ee
F ext/fts5/fts5_main.c 57933c18efe1058d8871199875c7a59744dabc3904f3aefbf9ff4a4e11fc79e2
@@ -438,7 +438,7 @@ F ext/misc/regexp.c 388e7f237307c7dfbfb8dde44e097946f6c437801d63f0d7ad63f3320d4e
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
-F ext/misc/series.c 69e0d2b5d193c67bdfee5baf79c10ec24a61a40212c7ca9c219edf7afa24305f
+F ext/misc/series.c 076a4c85dde2ae543d040f1080cdab74ebf3da7f3febfe38e0cd45a2217498bf
F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9
F ext/misc/shathree.c fd22d70620f86a0467acfdd3acd8435d5cb54eb1e2d9ff36ae44e389826993df
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
@@ -647,7 +647,7 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js f646a65257973b8c4481f8a6a216370b85644
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
-F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 16d80af915bfd2529824b999b304425503094eedf34fb113d0791e002b13e5cf
+F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 0f68a64e508598910e7c01214ae27d603dfc8baec6a184506fafac603a901931
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4ab0704ee198de7d1059eccedc7703c931510b588d10af0ee36ea5b3ebbac284
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616
F ext/wasm/api/sqlite3-wasm.c 6a4cd40267eaf08400895c5b9de39c56976c3b97b3c1bbe53fc2e80fa074e9c7
@@ -682,7 +682,7 @@ F ext/wasm/index-dist.html 56132399702b15d70c474c3f1952541e25cb0922942868f70daf1
F ext/wasm/index.html bcaa00eca521b372a6a62c7e7b17a870b0fcdf3e418a5921df1fd61e5344080d
F ext/wasm/jaccwabyt/jaccwabyt.js 6e4f26d0edb5c2e7d381b7eff1924832a040a12274afab2d1e1789027e9f6c5c
F ext/wasm/jaccwabyt/jaccwabyt.md 1128e3563e7eff90b5a373395251fc76cb32386fad1fea6075b0f34a8f1b9bdf
-F ext/wasm/mkwasmbuilds.c 082b7372db68c2d4cd9f55e7cde8eb1b83e9569e520984e6b08cb62606f3bf38
+F ext/wasm/mkwasmbuilds.c 6e0b22002bc520b7af053681571a96d30049a51f7f1389e81c524e8d420f5d40
F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
@@ -698,16 +698,18 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
-F ext/wasm/tester1.c-pp.js f3a3cbf0207287c4caa9f84b4e2934804e4b5720c71eaf143f33c8122bd3c9f2
+F ext/wasm/tester1.c-pp.js 419717b16e12703487a7ccf3ea4e63d693bdfbf7657e55a7e6c559bbccf027d3
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
+F ext/wasm/tests/opfs/sahpool/digest-worker.js b0ab6218588f1f0a6d15a363b493ceaf29bfb87804d9e0165915a9996377cf79
+F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b516a598dd096dcf3cf8cd81df8
F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
F ext/wasm/wasmfs.make 68999f5bd8c489239592d59a420f8c627c99169bbd6fa16a404751f757b9f702
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
-F main.mk e422aadc477bf446b13f92472f10c609567449796d551ed85237df8586a76dc8
+F main.mk be9db24c49ab5a9790388012bedd66b91e38bb5cc9e0778da9b548fe56109171
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -731,7 +733,7 @@ F src/build.c 3fe9b9d0f411cc2139a2d5ffa1c9b555417f89332f4dbf7f8e311c2e69e40c81
F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9
-F src/dbpage.c 2e677acb658a29965e55398bbc61161cb7819da538057c8032adac7ab8e4a8c0
+F src/dbpage.c fcb1aafe00872a8aff9a7aa0ef7ff1b01e5817ec7bbd521f8f3e1e674ac8d609
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
F src/expr.c 61c3baab38f1b50eb4696e1f37c8f7ae1d1ecbfc1a35d446cfd1886624784131
@@ -783,8 +785,8 @@ F src/printf.c 33fc0d7643c848a098afdcb6e1db6de12379d47084b1cd0912cfce1d09345e44
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 20e1fbe8f840ffc0cd835e33f68a802a22e34faa918d7a269f3de242fda02f99
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 8c273248e38a8a7286abe3f41c1931cc65eff602fef128acc0cc0484e1b7abb3
-F src/shell.c.in 248050551cad788f8bb4b4728e00d8e36a10130d2d101e55cd51cfee03df91ff
+F src/select.c bfe14cdfceba54744b1c6c29099313f5173a0793dfaff0cd484774e9d05dbeab
+F src/shell.c.in 9d1b46e09c1b933b0c7afaf4ae27030dc356ee19ae4f95ce8bf3647035b9635b
F src/sqlite.h.in fd70afd92948cf7cc93f687ac960bad1b0b6fbc436752419eff2fd65a1809380
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
@@ -975,7 +977,7 @@ F test/bind2.test 918bc35135f4141809ead7585909cde57d44db90a7a62aef540127148f91aa
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
-F test/bloom1.test cf613a27054bbaf61c5bfc440a5cfd3ff76798d0695f3fc5e5d1bbc819b8dab1
+F test/bloom1.test 04f3a17df8912bfdc292c41b59d79f93893fe69799f3089a64451f9112f9658f
F test/boundary1.tcl 6421b2d920d8b09539503a8673339d32f7609eb1
F test/boundary1.test 66d7f4706ccdb42d58eafdb081de07b0eb42d77b
F test/boundary2.tcl e34ef4e930cf1083150d4d2c603e146bd3b76bcb
@@ -1280,7 +1282,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
-F test/fuzzcheck.c e94511f5f5b8c134c83535b4799004b85ead69ed8375d74e9af90e41549a82ad
+F test/fuzzcheck.c 19f8af47a5c4ee2c3943fdee270f1f14e3d83fe968a9737a7557fb4e3c06efc1
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1288,7 +1290,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db b8725a5f5cf7a3b7241a9038e57ca7e7cc8c3f4d86b44bd770617bda245ab2b0
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
-F test/fuzzdata8.db c6f9cb7d2b808fb10894afe53ef00f51e73e43baa7aabdba7e9af4713fc5b186
+F test/fuzzdata8.db 8f34ae00d8d5d4747dd80983cf46161065e4f78324dcff3c893506ff8db3a4a6
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
@@ -1640,16 +1642,16 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test 573942b8d0e444956445993d5a5275c6912bc49b654441eec0b5e1e735f2e5b7
-F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
+F test/shell1.test a00910c3d811420c15c1411106871c65678516435e352cbb013a09839bf327c6
+F test/shell2.test ac102ebc0a9ec166257600c4ee8bdefec242163afced295f10b004f4af3fc9dd
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
-F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
-F test/shell5.test 0e5f8ce08206b9998a778cfe1989e20e47839153c05af2da29198150172e22fc
+F test/shell4.test ad7eee983b5e7f1dd92d8c87bc0f39474086bc32c980c00f3934c54aabc636a2
+F test/shell5.test d17e7927ab8b7f720efbdd9b5d05fceb6c3c56c25917901b315400214bf24ef4
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd
F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209
-F test/shellA.test 079c05c11947ade4ea8d51053d3abb687ec96a3dce6680d01838519b705190c5
+F test/shellA.test 4ecff8b7b2c0122ba8174abfbcc4b0f59e44d80f2a911068f8cd4cfc6661032d
F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
@@ -1719,7 +1721,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
-F test/tabfunc01.test 66d1ea27289c19317bf111744a4d5fda901759945d22ddb5bc964641fc38c185
+F test/tabfunc01.test 76da0509b01b9d12f4e71f8af28ee702d38166a5306bd77a955fb1a370dcd8b5
F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0
F test/tableapi.test e37c33e6be2276e3a96bb54b00eea7f321277115d10e5b30fdb52a112b432750
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
@@ -1731,7 +1733,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
-F test/tester.tcl c0f60f9da4ddaf845d16c2bebefd165f38ae88f6b7acd86459d3052f9d409404
+F test/tester.tcl 32d67bc83aef038404b458ca2c9c0c51f09c8d31eb9a28d6796b702fd89a2b60
F test/testrunner.tcl 0ffa67806e75aa2c186c63d7d00b16bb45adb91ed6560461fda6dbe3e18c885e x
F test/testrunner_data.tcl 6d7e7824bb36278ea65c33f7da6dd3ca101fc7d6f7a765b807dce0aa68c52521
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
@@ -1972,6 +1974,7 @@ F test/view.test 3c23d7a068e9e4a0c4e6907498042772adea725f0630c3d9638ffd4e5a08b92
F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679
F test/view3.test ad8a8290ee2b55ff6ce66c9ef1ce3f1e47926273a3814e1c425293e128a95456
F test/vt02.c 5b44ac67b1a283fedecf2d6e2ceda61e7a157f01d44dcb4490dcb1e87d057060
+F test/vt100-a.sql 631eeab18c5adb531bab79aecf64eee3934b42c75a309ee395c814717a6a7651
F test/vtab1.test 09a72330d0f31eda2ffaa828b06a6b917fb86250ee72de0301570af725774c07
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -2163,7 +2166,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a
F tool/mkautoconfamal.sh c5e65fa1c922f2e3b3e4f6cd0331ec7d84bdef085f32cb1c46673cdf95ec8090
-F tool/mkccode.tcl 210159febe0ef0ecbc53c79833500663ceaba0115b2b374405818dc835b5f84b x
+F tool/mkccode.tcl c42a8f8cf78f92e83795d5447460dbce7aaf78a3bbf9082f1507dc71a3665f3c x
F tool/mkctimec.tcl a384e7613db2a46e346cb4593731239a9239e942ff00aabd0c2b5d9e7afae840 x
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
@@ -2227,8 +2230,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 6baea938f0230f8b81b33373f948857fc44c2b3788bf8d4ee6e863b045632b82 d4307a0d43f42e96ec06ad2c1d8d0f5c8ecae759bae8231b1998633089809f49
-R 4a0c7dd88b1cecaa7e38a98abab95534
+P c8d8f613ed0d7639a8b859e8c7fa7da21bd1221a605c5da6a8fe041f7c9a3f5e f619e40fb05d3e09dca2ad9d9bbf38c66b4b93dd3d4e7c2071db28e671ee6a9c
+R 6fd5e7ca77fd0da216103b16a8dd29c5
U drh
-Z 66a02fd85f85dabea41fe0f85e5b0331
+Z b695b06c0719b4d59a901b5cc7a8d73c
# Remove this line to create a well-formed Fossil manifest.
diff --git a/manifest.uuid b/manifest.uuid
index da00cecb83..c31a432c05 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-c8d8f613ed0d7639a8b859e8c7fa7da21bd1221a605c5da6a8fe041f7c9a3f5e
+80e6ddd560b3041fe9164b940d684eeb6f28560a6c48b23ff49095da52e85df8
diff --git a/src/dbpage.c b/src/dbpage.c
index eb5ab33fe1..f9fdcc5a37 100644
--- a/src/dbpage.c
+++ b/src/dbpage.c
@@ -395,8 +395,8 @@ static int dbpageUpdate(
/* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and
** all subsequent pages to be deleted. */
pTab->iDbTrunc = iDb;
- pgno--;
- pTab->pgnoTrunc = pgno;
+ pTab->pgnoTrunc = pgno-1;
+ pgno = 1;
}else{
zErr = "bad page value";
goto update_fail;
diff --git a/src/select.c b/src/select.c
index eedbd82818..b2f2cc7fb8 100644
--- a/src/select.c
+++ b/src/select.c
@@ -3247,6 +3247,7 @@ static int multiSelect(
multi_select_end:
pDest->iSdst = dest.iSdst;
pDest->nSdst = dest.nSdst;
+ pDest->iSDParm2 = dest.iSDParm2;
if( pDelete ){
sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete);
}
diff --git a/src/shell.c.in b/src/shell.c.in
index 93d73e6ac7..8272956ebd 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -784,6 +784,23 @@ int cli_wcswidth(const char *z){
}
#endif
+/*
+** Check to see if z[] is a valid VT100 escape. If it is, then
+** return the number of bytes in the escape sequence. Return 0 if
+** z[] is not a VT100 escape.
+**
+** This routine assumes that z[0] is \033 (ESC).
+*/
+static int isVt100(const unsigned char *z){
+ int i;
+ if( z[1]!='[' ) return 0;
+ i = 2;
+ while( z[i]>=0x30 && z[i]<=0x3f ){ i++; }
+ while( z[i]>=0x20 && z[i]<=0x2f ){ i++; }
+ if( z[i]<0x40 || z[i]>0x7e ) return 0;
+ return i+1;
+}
+
/*
** Output string zUtf to stdout as w characters. If w is negative,
** then right-justify the text. W is the width in UTF-8 characters, not
@@ -799,6 +816,7 @@ static void utf8_width_print(FILE *out, int w, const char *zUtf){
unsigned char c;
int i = 0;
int n = 0;
+ int k;
int aw = w<0 ? -w : w;
if( zUtf==0 ) zUtf = "";
while( (c = a[i])!=0 ){
@@ -811,6 +829,8 @@ static void utf8_width_print(FILE *out, int w, const char *zUtf){
}
i += len;
n += x;
+ }else if( c==0x1b && (k = isVt100(&a[i]))>0 ){
+ i += k;
}else if( n>=aw ){
break;
}else{
@@ -3998,9 +4018,14 @@ static char *translateForDisplayAndDup(
i++;
continue;
}
- n++;
- j += 3;
- i++;
+ if( c==0x1b && p->eEscMode==SHELL_ESC_OFF && (k = isVt100(&z[i]))>0 ){
+ i += k;
+ j += k;
+ }else{
+ n++;
+ j += 3;
+ i++;
+ }
}
if( n>=mxWidth && bWordWrap ){
/* Perhaps try to back up to a better place to break the line */
@@ -4066,9 +4091,17 @@ static char *translateForDisplayAndDup(
zOut[j++] = '^';
zOut[j++] = 0x40 + c;
break;
- case SHELL_ESC_OFF:
- zOut[j++] = c;
+ case SHELL_ESC_OFF: {
+ int nn;
+ if( c==0x1b && (nn = isVt100(&z[i]))>0 ){
+ memcpy(&zOut[j], &z[i], nn);
+ j += nn;
+ i += nn - 1;
+ }else{
+ zOut[j++] = c;
+ }
break;
+ }
}
i++;
}
diff --git a/test/bloom1.test b/test/bloom1.test
index 151f364ae0..f8efcc1846 100644
--- a/test/bloom1.test
+++ b/test/bloom1.test
@@ -183,6 +183,47 @@ do_execsql_test 4.3 {
do_execsql_test 4.4 {
SELECT * FROM t0 LEFT JOIN t1 LEFT JOIN t2 ON (b NOTNULL)==(c IN ()) WHERE c;
} {xyz {} 7.0}
+
+reset_db
+do_execsql_test 5.0 {
+ CREATE TABLE t1 (c1);
+ INSERT INTO t1 VALUES (101);
+ CREATE TABLE t2 ( x );
+ INSERT INTO t2 VALUES(404);
+}
+
+do_execsql_test 5.1 {
+ SELECT 'val' in (
+ select 'val' from ( select 'valueB' from t1 order by 1 )
+ union all
+ select 'val'
+ );
+} {1}
+
+do_execsql_test 5.2 {
+ select * from t2
+ where 'val' in (
+ select 'val' from ( select 'valueB' from t1 order by 1 )
+ union all
+ select 'val'
+ );
+} {404}
+
+do_execsql_test 5.3 {
+ SELECT subq_1.c_0 as c_0
+ FROM ( SELECT 0 as c_0) as subq_1
+ WHERE (subq_1.c_0) IN (
+ SELECT subq_2.c_0 as c_0
+ FROM (
+ SELECT 0 as c_0
+ FROM t1 as ref_1
+ WHERE (ref_1.c1) = (2)
+ ORDER BY c_0 desc
+ ) as subq_2
+ UNION ALL
+ SELECT 0 as c_0
+ );
+} {0}
finish_test
diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c
index 7d5da2ce27..09898d7b35 100644
--- a/test/fuzzcheck.c
+++ b/test/fuzzcheck.c
@@ -391,6 +391,21 @@ static void renderDbSqlForCLI(
if( nSql>0 && zSql[nSql-1]!='\n' ) fprintf(out, "\n");
}
+/*
+** Find the tail (the last component) of a pathname.
+*/
+static const char *pathTail(const char *zPath){
+ const char *zTail = zPath;
+ while( zPath[0] ){
+ if( zPath[0]=='/' && zPath[1]!=0 ) zTail = &zPath[1];
+#ifndef __unix__
+ if( zPath[0]=='\\' && zPath[1]!=0 ) zTail = &zPath[1];
+#endif
+ zPath++;
+ }
+ return zTail;
+}
+
/*
** Read the complete content of a file into memory. Add a 0x00 terminator
** and return a pointer to the result.
@@ -1847,6 +1862,7 @@ static void showHelp(void){
"Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
"each database, checking for crashes and memory leaks.\n"
"Options:\n"
+" --brief Output only a summary of results at the end\n"
" --cell-size-check Set the PRAGMA cell_size_check=ON\n"
" --dbid M..N Use only the databases where dbid between M and N\n"
" \"M..\" for M and afterwards. Just \"M\" for M only\n"
@@ -1873,6 +1889,7 @@ static void showHelp(void){
" --result-trace Show the results of each SQL command\n"
" --script Output CLI script instead of running tests\n"
" --skip N Skip the first N test cases\n"
+" --slice M N Run only the M-th out of each group of N tests\n"
" --spinner Use a spinner to show progress\n"
" --sqlid M..N Use only SQL where sqlid between M..N\n"
" \"M..\" for M and afterwards. Just \"M\" for M only\n"
@@ -1887,6 +1904,7 @@ static void showHelp(void){
int main(int argc, char **argv){
sqlite3_int64 iBegin; /* Start time of this program */
int quietFlag = 0; /* True if --quiet or -q */
+ int briefFlag = 0; /* Output summary report at the end */
int verboseFlag = 0; /* True if --verbose or -v */
char *zInsSql = 0; /* SQL statement for --load-db or --load-sql */
int iFirstInsArg = 0; /* First argv[] for --load-db or --load-sql */
@@ -1934,6 +1952,8 @@ int main(int argc, char **argv){
int nV; /* How much to increase verbosity with -vvvv */
sqlite3_int64 tmStart; /* Start of each test */
int iEstTime = 0; /* LPF for the time-to-go */
+ int iSliceSz = 0; /* Divide the test space into this many pieces */
+ int iSliceIdx = 0; /* Only run the piece with this index */
sqlite3_config(SQLITE_CONFIG_URI,1);
registerOomSimulator();
@@ -1954,6 +1974,12 @@ int main(int argc, char **argv){
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
+ if( strcmp(z,"brief")==0 ){
+ briefFlag = 1;
+ quietFlag = 1;
+ verboseFlag = 1;
+ eVerbosity = 0;
+ }else
if( strcmp(z,"cell-size-check")==0 ){
cellSzCkFlag = 1;
}else
@@ -2044,6 +2070,7 @@ int main(int argc, char **argv){
g.uRandom = atoi(argv[++i]);
}else
if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
+ briefFlag = 0;
quietFlag = 1;
verboseFlag = 0;
eVerbosity = 0;
@@ -2062,12 +2089,19 @@ int main(int argc, char **argv){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
nSkip = atoi(argv[++i]);
}else
+ if( strcmp(z,"slice")==0 ){
+ if( i>=argc-2 ) fatalError("missing arguments on %s", argv[i]);
+ iSliceIdx = integerValue(argv[++i]);
+ iSliceSz = integerValue(argv[++i]);
+ /* --slice implices --brief */
+ briefFlag = 1;
+ quietFlag = 1;
+ verboseFlag = 1;
+ eVerbosity = 0;
+ }else
if( strcmp(z,"spinner")==0 ){
bSpinner = 1;
}else
- if( strcmp(z,"timer")==0 ){
- bTimer = 1;
- }else
if( strcmp(z,"sqlid")==0 ){
const char *zDotDot;
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
@@ -2093,10 +2127,14 @@ int main(int argc, char **argv){
fatalError("timeout is not available on non-unix systems");
#endif
}else
+ if( strcmp(z,"timer")==0 ){
+ bTimer = 1;
+ }else
if( strcmp(z,"vdbe-debug")==0 ){
bVdbeDebug = 1;
}else
if( strcmp(z,"verbose")==0 ){
+ briefFlag = 0;
quietFlag = 0;
verboseFlag++;
eVerbosity++;
@@ -2163,6 +2201,12 @@ int main(int argc, char **argv){
fatalError("cannot import into more than one database");
}
}
+ if( iSliceSz<=iSliceIdx
+ || iSliceSz<=0
+ || iSliceIdx<0
+ ){
+ iSliceSz = iSliceIdx = 0;
+ }
/* Process each source database separately */
for(iSrcDb=0; iSrcDbpNext){
tmStart = timeOfDay();
if( isDbSql(pSql->a, pSql->sz) ){
+ if( iSliceSz>0 && (nTest%iSliceSz)!=iSliceIdx ){
+ nTest++;
+ continue;
+ }
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
if( bScript ){
/* No progress output */
@@ -2510,6 +2558,10 @@ int main(int argc, char **argv){
for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
int openFlags;
const char *zVfs = "inmem";
+ if( iSliceSz>0 && (nTest%iSliceSz)!=iSliceIdx ){
+ nTest++;
+ continue;
+ }
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
pSql->id, pDb->id);
if( bScript ){
@@ -2616,7 +2668,20 @@ int main(int argc, char **argv){
}
}
}
- if( bScript ){
+ if( briefFlag ){
+ sqlite3_int64 iElapse = timeOfDay() - iBegin;
+ if( iSliceSz>0 ){
+ printf("%s %s: slice %d/%d of %d tests, %d.%03d seconds\n",
+ pathTail(argv[0]), pathTail(g.zDbFile),
+ iSliceIdx, iSliceSz, nTest,
+ (int)(iElapse/1000), (int)(iElapse%1000));
+ }else{
+ printf("%s %s: 0 errors, %d tests, %d.%03d seconds\n",
+ pathTail(argv[0]), pathTail(g.zDbFile), nTest,
+ (int)(iElapse/1000), (int)(iElapse%1000));
+ }
+ iBegin = timeOfDay();
+ }else if( bScript ){
/* No progress output */
}else if( bSpinner ){
int nTotal = g.nDb*g.nSql;
@@ -2634,6 +2699,7 @@ int main(int argc, char **argv){
} /* End loop over all source databases */
+
if( !quietFlag && !bScript ){
sqlite3_int64 iElapse = timeOfDay() - iBegin;
if( g.nInvariant ){
diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db
index 469df2c681..bfa3e3ecd0 100644
Binary files a/test/fuzzdata8.db and b/test/fuzzdata8.db differ
diff --git a/test/shell1.test b/test/shell1.test
index 598005a900..f89d34d536 100644
--- a/test/shell1.test
+++ b/test/shell1.test
@@ -1228,7 +1228,7 @@ do_test shell1-8.1 {
FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
}
} {0 47.49000000000000198951966012828052043914794921875}
-do_test shell1-8.2 {
+do_test_with_ansi_output shell1-8.2 {
catchcmd :memory: {
.mode box
SELECT ieee754(47.49) AS x;
@@ -1238,7 +1238,7 @@ SELECT ieee754(47.49) AS x;
├───────────────────────────────┤
│ ieee754(6683623321994527,-47) │
└───────────────────────────────┘}}
-do_test shell1-8.3 {
+do_test_with_ansi_output shell1-8.3 {
catchcmd ":memory: --box" {
select ieee754(6683623321994527,-47) as x;
}
@@ -1254,7 +1254,7 @@ do_test shell1-8.4 {
+------------------+-----+
| 6683623321994527 | -47 |
+------------------+-----+}}
-do_test shell1-8.5 {
+do_test_with_ansi_output shell1-8.5 {
catchcmd ":memory: --box" {
create table t(a text, b int);
insert into t values ('too long for one line', 1), ('shorter', NULL);
diff --git a/test/shell2.test b/test/shell2.test
index ee5ae4bdd9..3f9fec9efa 100644
--- a/test/shell2.test
+++ b/test/shell2.test
@@ -224,24 +224,24 @@ do_test shell2-1.4.10 {
set res [catchcmd :memory: [string trim {
SELECT * FROM generate_series(9223372036854775807,9223372036854775807,1);
SELECT * FROM generate_series(9223372036854775807,9223372036854775807,-1);
- SELECT avg(rowid),min(value),max(value) FROM generate_series(
+ SELECT avg(value),min(value),max(value) FROM generate_series(
-9223372036854775808,9223372036854775807,1085102592571150095);
SELECT * FROM generate_series(-9223372036854775808,9223372036854775807,
9223372036854775807);
- SELECT value,rowid FROM generate_series(-4611686018427387904,
+ SELECT value FROM generate_series(-4611686018427387904,
4611686018427387904, 4611686018427387904) ORDER BY value DESC;
SELECT * FROM generate_series(0,-2,-1);
SELECT * FROM generate_series(0,-2);
SELECT * FROM generate_series(0,2) LIMIT 3;}]]
} {0 {9223372036854775807
9223372036854775807
-9.5|-9223372036854775808|9223372036854775807
+-0.5|-9223372036854775808|9223372036854775807
-9223372036854775808
-1
9223372036854775806
-4611686018427387904|3
-0|2
--4611686018427387904|1
+4611686018427387904
+0
+-4611686018427387904
0
-1
-2
diff --git a/test/shell4.test b/test/shell4.test
index 4b7e9b8eec..4275911ef0 100644
--- a/test/shell4.test
+++ b/test/shell4.test
@@ -140,7 +140,7 @@ do_test shell4-3.1 {
close $fd
exec $::CLI_ONLY :memory: --interactive ".read t1.txt"
} {squirrel}
-do_test shell4-3.2 {
+do_test_with_ansi_output shell4-3.2 {
set fd [open t1.txt wb]
puts $fd "SELECT 'pound: \302\243';"
close $fd
diff --git a/test/shell5.test b/test/shell5.test
index 8eb905974b..70a2298bcb 100644
--- a/test/shell5.test
+++ b/test/shell5.test
@@ -553,7 +553,7 @@ Columns renamed during .import shell5.csv due to duplicates:
# Tests for preserving utf-8 that is not also ASCII.
#
-do_test shell5-6.1 {
+do_test_with_ansi_output shell5-6.1 {
set out [open shell5.csv w]
fconfigure $out -translation lf
puts $out {あい,うえお}
@@ -566,7 +566,7 @@ SELECT * FROM t1;}
} {0 { あい = 1
うえお = 2}}
-do_test shell5-6.2 {
+do_test_with_ansi_output shell5-6.2 {
set out [open shell5.csv w]
fconfigure $out -translation lf
puts $out {1,2}
diff --git a/test/shellA.test b/test/shellA.test
index 1a8161bf38..f3959d4283 100644
--- a/test/shellA.test
+++ b/test/shellA.test
@@ -35,7 +35,7 @@ do_execsql_test shellA-1.0 {
# Initial verification that the database created correctly
# and that our calls to the CLI are working.
#
-do_test shellA-1.2 {
+do_test_with_ansi_output shellA-1.2 {
exec {*}$CLI test.db {.mode box --escape symbol} {SELECT * FROM t1;}
} {
┌───┬──────────────────────────┐
@@ -67,7 +67,7 @@ do_test shellA-1.3 {
} {
^[[31mVT-100 codes^[[0m
}
-do_test shellA-1.4 {
+do_test_with_ansi_output shellA-1.4 {
exec {*}$CLI test.db --escape symbol {SELECT x FROM t1 WHERE a=2;}
} {
␛[31mVT-100 codes␛[0m
@@ -77,7 +77,7 @@ do_test shellA-1.5 {
} {
^[[31mVT-100 codes^[[0m
}
-do_test shellA-1.6 {
+do_test_with_ansi_output shellA-1.6 {
exec {*}$CLI test.db {.mode list --escape symbol} {SELECT x FROM t1 WHERE a=2;}
} {
␛[31mVT-100 codes␛[0m
@@ -134,7 +134,7 @@ do_test shellA-2.4 {
# ".mode line"
#
-do_test shellA-3.1 {
+do_test_with_ansi_output shellA-3.1 {
exec {*}$CLI test.db --line --escape symbol \
{SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
} {
@@ -177,7 +177,7 @@ line
# ".mode box"
#
-do_test shellA-4.1 {
+do_test_with_ansi_output shellA-4.1 {
exec {*}$CLI test.db --box --escape ascii \
{SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
} {
@@ -196,7 +196,7 @@ do_test shellA-4.1 {
│ 8 │ last line │
└───┴──────────────────────────┘
}
-do_test shellA-4.2 {
+do_test_with_ansi_output shellA-4.2 {
exec {*}$CLI test.db {.mode qbox} {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
} {
┌───┬───────────────────────────────────────────┐
diff --git a/test/tabfunc01.test b/test/tabfunc01.test
index cbf9865eda..c16fb9bec2 100644
--- a/test/tabfunc01.test
+++ b/test/tabfunc01.test
@@ -61,10 +61,10 @@ do_execsql_test tabfunc01-1.8 {
} {30 25 20 15 10 5 0}
do_execsql_test tabfunc01-1.9 {
SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC;
-} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
+} {30 30 25 25 20 20 15 15 10 10 5 5 0 0}
do_execsql_test tabfunc01-1.10 {
SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC;
-} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
+} {30 30 25 25 20 20 15 15 10 10 5 5 0 0}
do_execsql_test tabfunc01-1.20 {
CREATE VIEW v1(a,b) AS VALUES(1,2),(3,4);
@@ -383,7 +383,18 @@ do_execsql_test 1100 {
where (ref_3.value) in (select 1);
} {1}
-
+# 2025-03-18 /forumpost/1e17219c88
+# The generate_series() table-valued function is modified so that its
+# rowid is always its value. That way it can be used on the RHS of a
+# RIGHT JOIN.
+#
+do_execsql_test 1200 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(value INT);
+ INSERT INTO t1 VALUES (1),(2),(3);
+ SELECT t1.value, t2.value
+ FROM t1 RIGHT JOIN generate_series(1,3,1) AS t2 USING(value);
+} {1 1 2 2 3 3}
# Free up memory allocations
intarray_addr
diff --git a/test/tester.tcl b/test/tester.tcl
index cf42b2d125..8f1f83e65b 100644
--- a/test/tester.tcl
+++ b/test/tester.tcl
@@ -810,6 +810,15 @@ proc do_test {name cmd expected} {
flush stdout
}
+# Like do_test except the test is not run in a slave interpreter
+# on Windows because of issues with ANSI and UTF8 I/O on Win11.
+#
+proc do_test_with_ansi_output {name cmd expected} {
+ if {![info exists ::SLAVE] || $::tcl_platform(platform)!="windows"} {
+ uplevel 1 [list do_test $name $cmd $expected]
+ }
+}
+
proc dumpbytes {s} {
set r ""
for {set i 0} {$i < [string length $s]} {incr i} {
diff --git a/test/vt100-a.sql b/test/vt100-a.sql
new file mode 100644
index 0000000000..a0d3f46be7
--- /dev/null
+++ b/test/vt100-a.sql
@@ -0,0 +1,19 @@
+/*
+** Run this script using the "sqlite3" command-line shell
+** test test formatting of output text that contains
+** vt100 escape sequences.
+*/
+.mode box -escape off
+CREATE TEMP TABLE t1(a,b,c);
+INSERT INTO t1 VALUES
+ ('one','twotwotwo','thirty-three'),
+ (unistr('\u001b[91mRED\u001b[0m'),'fourfour','fifty-five'),
+ ('six','seven','eighty-eight');
+.print With -escape off
+SELECT * FROM t1;
+.mode box -escape ascii
+.print With -escape ascii
+SELECT * FROM t1;
+.mode box -escape symbol
+.print With -escape symbol
+SELECT * FROM t1;
diff --git a/tool/mkccode.tcl b/tool/mkccode.tcl
index ecafbdadb9..8b4fae82c9 100755
--- a/tool/mkccode.tcl
+++ b/tool/mkccode.tcl
@@ -1,17 +1,16 @@
-#!/usr/bin/tclsh
+#!/bin/env tclsh
#
-# Use this script to build C-language source code for a program that uses
-# tclsqlite.c together with custom TCL scripts and/or C extensions for
-# either SQLite or TCL.
+# This script is used to amalgamate C source code files into a single
+# unit.
#
# Usage example:
#
# tclsh mkccode.tcl -DENABLE_FEATURE_XYZ demoapp.c.in >demoapp.c
#
# The demoapp.c.in file contains a mixture of C code, TCL script, and
-# processing directives used by mktclsqliteprog.tcl to build the final C-code
-# output file. Most lines of demoapp.c.in are copied straight through into
-# the output. The following control directives are recognized:
+# processing directives used by mkccode.tcl to build the final C-code
+# output file. Most lines of demoapp.c.in are copied straight through
+# into the output. The following control directives are recognized:
#
# BEGIN_STRING
#