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 #