1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge the latest trunk enhancements into the wal2 branch.

FossilOrigin-Name: a78208b597ee34b1121dd8014b3c1376b46baddff41448c96a37723cc9ede921
This commit is contained in:
drh
2024-08-16 18:58:50 +00:00
51 changed files with 1766 additions and 870 deletions

View File

@@ -121,10 +121,6 @@ TCLSH_CMD = @TCLSH_CMD@
# #
TCLLIBDIR = @TCLLIBDIR@ TCLLIBDIR = @TCLLIBDIR@
# The suffix used on shared libraries. Ex: ".dll", ".so", ".dylib"
#
SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
# If gcov support was enabled by the configure script, add the appropriate # If gcov support was enabled by the configure script, add the appropriate
# flags here. It's not always as easy as just having the user add the right # flags here. It's not always as easy as just having the user add the right
# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which # CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
@@ -1559,12 +1555,37 @@ install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal
pkgIndex.tcl: pkgIndex.tcl:
echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@
tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR) $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
# Build the SQLite TCL extension in a way that make it compatible
# with whatever version of TCL is running as $TCLSH_CMD, possibly defined
# by --with-tclsh=
#
tclextension: tclsqlite3.c
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS)
# Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD
# to find it.
#
tclextension-install: tclsqlite3.c
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS)
# Install the SQLite TCL extension that is used by $TCLSH_CMD
#
tclextension-uninstall:
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall
# List all installed the SQLite TCL extension that is are accessible
# by $TCLSH_CMD, included prior versions.
#
tclextension-list:
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info
clean: clean:
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
rm -f sqlite3.h opcodes.* rm -f sqlite3.h opcodes.*

View File

@@ -1821,6 +1821,19 @@ pkgIndex.tcl: $(TOP)\VERSION
$(SQLITE3TCLDLL): libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl $(SQLITE3TCLDLL): libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
tclextension: $(SQLITE3TCLDLL)
tclextension-install: $(SQLITE3TCLDLL)
$(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --install-only
tclextension-uninstall:
$(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --uninstall
tclextension-list:
$(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --info
# <</mark>> # <</mark>>
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)

393
configure vendored
View File

@@ -781,18 +781,6 @@ TARGET_HAVE_EDITLINE
TARGET_HAVE_READLINE TARGET_HAVE_READLINE
TARGET_READLINE_INC TARGET_READLINE_INC
TARGET_READLINE_LIBS TARGET_READLINE_LIBS
HAVE_TCL
TCL_SHLIB_SUFFIX
TCL_STUB_LIB_SPEC
TCL_STUB_LIB_FLAG
TCL_STUB_LIB_FILE
TCL_LIB_SPEC
TCL_LIB_FLAG
TCL_LIB_FILE
TCL_INCLUDE_SPEC
TCL_SRC_DIR
TCL_BIN_DIR
TCL_VERSION
TARGET_EXEEXT TARGET_EXEEXT
SQLITE_OS_WIN SQLITE_OS_WIN
SQLITE_OS_UNIX SQLITE_OS_UNIX
@@ -806,6 +794,10 @@ RELEASE
VERSION VERSION
program_prefix program_prefix
TCLLIBDIR TCLLIBDIR
HAVE_TCL
TCL_STUB_LIB_SPEC
TCL_LIB_SPEC
TCL_INCLUDE_SPEC
TCLSH_CMD TCLSH_CMD
INSTALL_DATA INSTALL_DATA
INSTALL_SCRIPT INSTALL_SCRIPT
@@ -894,12 +886,13 @@ enable_fast_install
with_gnu_ld with_gnu_ld
enable_libtool_lock enable_libtool_lock
enable_largefile enable_largefile
with_tclsh
with_tcl
enable_tcl
with_wasi_sdk with_wasi_sdk
enable_threadsafe enable_threadsafe
enable_releasemode enable_releasemode
enable_tempstore enable_tempstore
enable_tcl
with_tcl
enable_editline enable_editline
enable_readline enable_readline
with_readline_lib with_readline_lib
@@ -1551,11 +1544,12 @@ Optional Features:
optimize for fast installation [default=yes] optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds) --disable-libtool-lock avoid locking (might break parallel builds)
--disable-largefile omit support for large files --disable-largefile omit support for large files
--disable-tcl omit building accessory programs that require
TCL-dev
--disable-threadsafe Disable mutexing --disable-threadsafe Disable mutexing
--enable-releasemode Support libtool link to release mode --enable-releasemode Support libtool link to release mode
--enable-tempstore Use an in-ram database for temporary tables --enable-tempstore Use an in-ram database for temporary tables
(never,no,yes,always) (never,no,yes,always)
--disable-tcl do not build TCL extension
--enable-editline enable BSD editline support --enable-editline enable BSD editline support
--disable-readline disable readline support --disable-readline disable readline support
--enable-debug enable debugging & verbose explain --enable-debug enable debugging & verbose explain
@@ -1583,10 +1577,10 @@ Optional Packages:
--with-pic try to use only PIC/non-PIC objects [default=use --with-pic try to use only PIC/non-PIC objects [default=use
both] both]
--with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-tclsh=PATHNAME full pathname of a tclsh to use
--with-tcl=DIR directory containing (tclConfig.sh)
--with-wasi-sdk=DIR directory containing the WASI SDK. Triggers --with-wasi-sdk=DIR directory containing the WASI SDK. Triggers
cross-compile to WASM. cross-compile to WASM.
--with-tcl=DIR directory containing tcl configuration
(tclConfig.sh)
--with-readline-lib specify readline library --with-readline-lib specify readline library
--with-readline-inc specify readline include paths --with-readline-inc specify readline include paths
--with-linenoise=DIR source directory for linenoise library --with-linenoise=DIR source directory for linenoise library
@@ -3945,13 +3939,13 @@ if ${lt_cv_nm_interface+:} false; then :
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3948: $ac_compile\"" >&5) (eval echo "\"\$as_me:3942: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:3951: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval echo "\"\$as_me:3945: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:3954: output\"" >&5) (eval echo "\"\$as_me:3948: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
@@ -5157,7 +5151,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 5160 "configure"' > conftest.$ac_ext echo '#line 5154 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@@ -6682,11 +6676,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6685: $lt_compile\"" >&5) (eval echo "\"\$as_me:6679: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:6689: \$? = $ac_status" >&5 echo "$as_me:6683: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -7021,11 +7015,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7024: $lt_compile\"" >&5) (eval echo "\"\$as_me:7018: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7028: \$? = $ac_status" >&5 echo "$as_me:7022: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -7126,11 +7120,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7129: $lt_compile\"" >&5) (eval echo "\"\$as_me:7123: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7133: \$? = $ac_status" >&5 echo "$as_me:7127: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -7181,11 +7175,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7184: $lt_compile\"" >&5) (eval echo "\"\$as_me:7178: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7188: \$? = $ac_status" >&5 echo "$as_me:7182: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -9561,7 +9555,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 9564 "configure" #line 9558 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -9657,7 +9651,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 9660 "configure" #line 9654 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -10314,24 +10308,30 @@ done
USE_AMALGAMATION=1 USE_AMALGAMATION=1
######### #########
# See whether we can run specific tclsh versions known to work well; # Figure out all the name of a working tclsh and parameters needed to compile against Tcl.
# if not, then we fall back to plain tclsh. # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this.
# TODO: try other versions before falling back?
# #
if test x"${with_tcl}" != x; then
if test ! -r ${with_tcl}/tclConfig.sh; then # Check whether --with-tclsh was given.
as_fn_error $? "no tclConfig.sh file found in --with-tcl: ${with_tcl}" "$LINENO" 5 if test "${with_tclsh+set}" = set; then :
else withval=$with_tclsh;
. ${with_tcl}/tclConfig.sh fi
TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION}
if test ! -x ${TCLSH_CMD}; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot use tclsh at: ${TCLSH_CMD}" >&5 # Check whether --with-tcl was given.
$as_echo "$as_me: WARNING: cannot use tclsh at: ${TCLSH_CMD}" >&2;} if test "${with_tcl+set}" = set; then :
TCLSH_CMD=none withval=$with_tcl;
fi fi
fi
# Check whether --enable-tcl was given.
if test "${enable_tcl+set}" = set; then :
enableval=$enable_tcl; use_tcl=$enableval
else else
for ac_prog in tclsh8.6 tclsh8.5 tclsh use_tcl=yes
fi
if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then
for ac_prog in tclsh8.6 tclsh tclsh9.0
do do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
@@ -10374,25 +10374,101 @@ fi
done done
test -n "$TCLSH_CMD" || TCLSH_CMD="none" test -n "$TCLSH_CMD" || TCLSH_CMD="none"
with_tclsh=${TCLSH_CMD}
fi
if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then
TCLSH_CMD=${with_tclsh}
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using tclsh at \"$TCLSH_CMD\"" >&5
$as_echo "using tclsh at \"$TCLSH_CMD\"" >&6; }
if test x"${use_tcl}" = "xyes"; then
with_tcl=`${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl`
if test x"${with_tcl}" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" >&5
$as_echo "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $TCLSH_CMD is unable to recommend a tclConfig.sh" >&5
$as_echo "$as_me: WARNING: $TCLSH_CMD is unable to recommend a tclConfig.sh" >&2;}
fi
fi
fi
if test x"${use_tcl}" = "xyes"; then
if test x"${with_tcl}" != x; then
if test -r ${with_tcl}/tclConfig.sh; then
tclconfig="${with_tcl}/tclConfig.sh"
else
for i in tcl8.6 tcl9.0 lib; do
if test -r ${with_tcl}/$i/tclConfig.sh; then
tclconfig=${with_tcl}/$i/tclConfig.sh
break
fi
done
fi
if test ! -r "${tclconfig}"; then
as_fn_error $? "no tclConfig.sh file found under ${with_tcl}" "$LINENO" 5
fi
else
# If we have not yet found a tclConfig.sh file, look in $libdir whic is
# set automatically by autoconf or by the --prefix command-line option.
# See https://sqlite.org/forum/forumpost/e04e693439a22457
libdir=${prefix}/lib
if test -r ${libdir}/tclConfig.sh; then
tclconfig=${libdir}/tclConfig.sh
else
for i in tcl8.6 tcl9.0 lib; do
if test -r ${libdir}/$i/tclConfig.sh; then
tclconfig=${libdir}/$i/tclConfig.sh
break
fi
done
fi
if test ! -r "${tclconfig}"; then
as_fn_error $? "cannot find a usable tclConfig.sh file.
Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found.
SQLite does not use TCL internally, but TCL is required to build SQLite
from canonical sources and TCL is required for testing." "$LINENO" 5
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: loading TCL configuration from ${tclconfig}" >&5
$as_echo "loading TCL configuration from ${tclconfig}" >&6; }
. ${tclconfig}
# There are lots of other configuration variables that are provided by the
# tclConfig.sh file and that could be included here. But as of right now,
# TCL_LIB_SPEC is the only what that the Makefile uses.
HAVE_TCL=1
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to run tests because of --disable-tcl" >&5
$as_echo "unable to run tests because of --disable-tcl" >&6; }
HAVE_TCL=0
fi
if test x"$TCLSH_CMD" == x; then
TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION}
if test ! -x ${TCLSH_CMD}; then
TCLSH_CMD_2=${TCL_EXEC_PREFIX}/bin/tclsh
if test ! -x ${TCLSH_CMD_2}; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" >&5
$as_echo "$as_me: WARNING: cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" >&2;}
TCLSH_CMD=none
else
TCLSH_CMD=${TCLSH_CMD_2}
fi
fi
fi fi
if test "$TCLSH_CMD" = "none"; then if test "$TCLSH_CMD" = "none"; then
# If we can't find a local tclsh, then building the amalgamation will fail. # If we can't find a local tclsh, then building the amalgamation will fail.
# We act as though --disable-amalgamation has been used. # We act as though --disable-amalgamation has been used.
echo "Warning: can't find tclsh - defaulting to non-amalgamation build." { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Warning: can't find tclsh - defaulting to non-amalgamation build." >&5
$as_echo "$as_me: WARNING: Warning: can't find tclsh - defaulting to non-amalgamation build." >&2;}
USE_AMALGAMATION=0 USE_AMALGAMATION=0
TCLSH_CMD="tclsh" TCLSH_CMD="tclsh"
fi fi
if test x"$TCLSH_CMD" = x; then
as_fn_error $? "cannot find a usable tclsh" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $TCLSH_CMD" >&5
$as_echo "using $TCLSH_CMD" >&6; }
fi
if test "x${TCLLIBDIR+set}" != "xset" ; then if test "x${TCLLIBDIR+set}" != "xset" ; then
TCLLIBDIR='$(libdir)'
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
if test -d $i ; then if test -d $i ; then
TCLLIBDIR=$i TCLLIBDIR=$i
@@ -10789,213 +10865,6 @@ fi
##########
# Figure out all the parameters needed to compile against Tcl.
#
# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG
# macros in the in the tcl.m4 file of the standard TCL distribution.
# Those macros could not be used directly since we have to make some
# minor changes to accomodate systems that do not have TCL installed.
#
# Check whether --enable-tcl was given.
if test "${enable_tcl+set}" = set; then :
enableval=$enable_tcl; use_tcl=$enableval
else
use_tcl=yes
fi
if test "${use_tcl}" = "yes" ; then
# Check whether --with-tcl was given.
if test "${with_tcl+set}" = set; then :
withval=$with_tcl; with_tclconfig=${withval}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
$as_echo_n "checking for Tcl configuration... " >&6; }
if ${ac_cv_c_tclconfig+:} false; then :
$as_echo_n "(cached) " >&6
else
# First check to see if --with-tcl was specified.
if test x"${with_tclconfig}" != x ; then
if test -f "${with_tclconfig}/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
else
as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
fi
fi
# Start autosearch by asking tclsh
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# On ubuntu 14.10, $auto_path on tclsh is not quite correct.
# So try again after applying corrections.
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD} | sed 's,/tcltk/tcl,/tcl,g'`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# Recent versions of Xcode on Macs hid the tclConfig.sh file
# in a strange place.
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk/usr/lib
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# then check for a private Tcl installation
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
../tcl \
`ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
`ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
`ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
../../tcl \
`ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
`ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
`ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
../../../tcl \
`ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
`ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
`ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null`
do
if test -f "$i/unix/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
break
fi
done
fi
# check in a few common install locations
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
`ls -d ${libdir} 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
`ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i; pwd)`
break
fi
done
fi
# check in a few other private locations
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
${srcdir}/../tcl \
`ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
`ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null`
do
if test -f "$i/unix/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
break
fi
done
fi
fi
if test x"${ac_cv_c_tclconfig}" = x ; then
use_tcl=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5
$as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5
$as_echo "$as_me: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5
$as_echo "$as_me: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&2;}
else
TCL_BIN_DIR=${ac_cv_c_tclconfig}
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found $TCL_BIN_DIR/tclConfig.sh" >&5
$as_echo "found $TCL_BIN_DIR/tclConfig.sh" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5
$as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; }
if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
. $TCL_BIN_DIR/tclConfig.sh
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
$as_echo "file not found" >&6; }
fi
#
# If the TCL_BIN_DIR is the build directory (not the install directory),
# then set the common variable name to the value of the build variables.
# For example, the variable TCL_LIB_SPEC will be set to the value
# of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
# instead of TCL_BUILD_LIB_SPEC since it will work with both an
# installed and uninstalled version of Tcl.
#
if test -f $TCL_BIN_DIR/Makefile ; then
TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
fi
#
# eval is required to do the TCL_DBGX substitution
#
eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
fi
fi
if test "${use_tcl}" = "no" ; then
HAVE_TCL=""
else
HAVE_TCL=1
fi
########## ##########
# Figure out what C libraries are required to compile programs # Figure out what C libraries are required to compile programs
# that use "readline()" library. # that use "readline()" library.

View File

@@ -116,41 +116,103 @@ AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_s
USE_AMALGAMATION=1 USE_AMALGAMATION=1
######### #########
# See whether we can run specific tclsh versions known to work well; # Figure out all the name of a working tclsh and parameters needed to compile against Tcl.
# if not, then we fall back to plain tclsh. # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this.
# TODO: try other versions before falling back?
# #
if test x"${with_tcl}" != x; then AC_ARG_WITH(tclsh, AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use]))
if test ! -r ${with_tcl}/tclConfig.sh; then AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)]))
AC_MSG_ERROR([no tclConfig.sh file found in --with-tcl: ${with_tcl}]) AC_ARG_ENABLE(tcl, AS_HELP_STRING([--disable-tcl],[omit building accessory programs that require TCL-dev]),
else [use_tcl=$enableval],[use_tcl=yes])
. ${with_tcl}/tclConfig.sh if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then
TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh tclsh9.0],none)
if test ! -x ${TCLSH_CMD}; then with_tclsh=${TCLSH_CMD}
AC_MSG_WARN([cannot use tclsh at: ${TCLSH_CMD}]) fi
TCLSH_CMD=none if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then
TCLSH_CMD=${with_tclsh}
AC_MSG_RESULT([using tclsh at "$TCLSH_CMD"])
if test x"${use_tcl}" = "xyes"; then
with_tcl=`${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl`
if test x"${with_tcl}" != x; then
AC_MSG_RESULT([$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}])
else
AC_MSG_WARN([$TCLSH_CMD is unable to recommend a tclConfig.sh])
fi fi
fi fi
fi
if test x"${use_tcl}" = "xyes"; then
if test x"${with_tcl}" != x; then
if test -r ${with_tcl}/tclConfig.sh; then
tclconfig="${with_tcl}/tclConfig.sh"
else
for i in tcl8.6 tcl9.0 lib; do
if test -r ${with_tcl}/$i/tclConfig.sh; then
tclconfig=${with_tcl}/$i/tclConfig.sh
break
fi
done
fi
if test ! -r "${tclconfig}"; then
AC_MSG_ERROR([no tclConfig.sh file found under ${with_tcl}])
fi
else
# If we have not yet found a tclConfig.sh file, look in $libdir whic is
# set automatically by autoconf or by the --prefix command-line option.
# See https://sqlite.org/forum/forumpost/e04e693439a22457
libdir=${prefix}/lib
if test -r ${libdir}/tclConfig.sh; then
tclconfig=${libdir}/tclConfig.sh
else
for i in tcl8.6 tcl9.0 lib; do
if test -r ${libdir}/$i/tclConfig.sh; then
tclconfig=${libdir}/$i/tclConfig.sh
break
fi
done
fi
if test ! -r "${tclconfig}"; then
AC_MSG_ERROR([cannot find a usable tclConfig.sh file.
Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found.
SQLite does not use TCL internally, but TCL is required to build SQLite
from canonical sources and TCL is required for testing.])
fi
fi
AC_MSG_RESULT([loading TCL configuration from ${tclconfig}])
. ${tclconfig}
AC_SUBST(TCL_INCLUDE_SPEC)
AC_SUBST(TCL_LIB_SPEC)
AC_SUBST(TCL_STUB_LIB_SPEC)
# There are lots of other configuration variables that are provided by the
# tclConfig.sh file and that could be included here. But as of right now,
# TCL_LIB_SPEC is the only what that the Makefile uses.
HAVE_TCL=1
else else
AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none) AC_MSG_RESULT([unable to run tests because of --disable-tcl])
HAVE_TCL=0
fi
AC_SUBST(HAVE_TCL)
if test x"$TCLSH_CMD" == x; then
TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION}
if test ! -x ${TCLSH_CMD}; then
TCLSH_CMD_2=${TCL_EXEC_PREFIX}/bin/tclsh
if test ! -x ${TCLSH_CMD_2}; then
AC_MSG_WARN([cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}])
TCLSH_CMD=none
else
TCLSH_CMD=${TCLSH_CMD_2}
fi
fi
fi fi
if test "$TCLSH_CMD" = "none"; then if test "$TCLSH_CMD" = "none"; then
# If we can't find a local tclsh, then building the amalgamation will fail. # If we can't find a local tclsh, then building the amalgamation will fail.
# We act as though --disable-amalgamation has been used. # We act as though --disable-amalgamation has been used.
echo "Warning: can't find tclsh - defaulting to non-amalgamation build." AC_MSG_WARN([Warning: can't find tclsh - defaulting to non-amalgamation build.])
USE_AMALGAMATION=0 USE_AMALGAMATION=0
TCLSH_CMD="tclsh" TCLSH_CMD="tclsh"
fi fi
if test x"$TCLSH_CMD" = x; then
AC_MSG_ERROR([cannot find a usable tclsh])
else
AC_MSG_RESULT([using $TCLSH_CMD])
fi
AC_SUBST(TCLSH_CMD) AC_SUBST(TCLSH_CMD)
AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin])
if test "x${TCLLIBDIR+set}" != "xset" ; then if test "x${TCLLIBDIR+set}" != "xset" ; then
TCLLIBDIR='$(libdir)'
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do
if test -d $i ; then if test -d $i ; then
TCLLIBDIR=$i TCLLIBDIR=$i
@@ -357,190 +419,6 @@ AC_SUBST(SQLITE_OS_UNIX)
AC_SUBST(SQLITE_OS_WIN) AC_SUBST(SQLITE_OS_WIN)
AC_SUBST(TARGET_EXEEXT) AC_SUBST(TARGET_EXEEXT)
##########
# Figure out all the parameters needed to compile against Tcl.
#
# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG
# macros in the in the tcl.m4 file of the standard TCL distribution.
# Those macros could not be used directly since we have to make some
# minor changes to accomodate systems that do not have TCL installed.
#
AC_ARG_ENABLE(tcl, AS_HELP_STRING([--disable-tcl],[do not build TCL extension]),
[use_tcl=$enableval],[use_tcl=yes])
if test "${use_tcl}" = "yes" ; then
AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl=DIR],[directory containing tcl configuration (tclConfig.sh)]), with_tclconfig=${withval})
AC_MSG_CHECKING([for Tcl configuration])
AC_CACHE_VAL(ac_cv_c_tclconfig,[
# First check to see if --with-tcl was specified.
if test x"${with_tclconfig}" != x ; then
if test -f "${with_tclconfig}/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
else
AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
fi
fi
# Start autosearch by asking tclsh
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# On ubuntu 14.10, $auto_path on tclsh is not quite correct.
# So try again after applying corrections.
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD} | sed 's,/tcltk/tcl,/tcl,g'`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# Recent versions of Xcode on Macs hid the tclConfig.sh file
# in a strange place.
if test x"${ac_cv_c_tclconfig}" = x ; then
if test x"$cross_compiling" = xno; then
for i in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk/usr/lib
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="$i"
break
fi
done
fi
fi
# then check for a private Tcl installation
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
../tcl \
`ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
`ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
`ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
../../tcl \
`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
../../../tcl \
`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null`
do
if test -f "$i/unix/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
break
fi
done
fi
# check in a few common install locations
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
`ls -d ${libdir} 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
`ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null`
do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i; pwd)`
break
fi
done
fi
# check in a few other private locations
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in \
${srcdir}/../tcl \
`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null`
do
if test -f "$i/unix/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
break
fi
done
fi
])
if test x"${ac_cv_c_tclconfig}" = x ; then
use_tcl=no
AC_MSG_WARN(Can't find Tcl configuration definitions)
AC_MSG_WARN(*** Without Tcl the regression tests cannot be executed ***)
AC_MSG_WARN(*** Consider using --with-tcl=... to define location of Tcl ***)
else
TCL_BIN_DIR=${ac_cv_c_tclconfig}
AC_MSG_RESULT(found $TCL_BIN_DIR/tclConfig.sh)
AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh])
if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
AC_MSG_RESULT([loading])
. $TCL_BIN_DIR/tclConfig.sh
else
AC_MSG_RESULT([file not found])
fi
#
# If the TCL_BIN_DIR is the build directory (not the install directory),
# then set the common variable name to the value of the build variables.
# For example, the variable TCL_LIB_SPEC will be set to the value
# of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
# instead of TCL_BUILD_LIB_SPEC since it will work with both an
# installed and uninstalled version of Tcl.
#
if test -f $TCL_BIN_DIR/Makefile ; then
TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
fi
#
# eval is required to do the TCL_DBGX substitution
#
eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_INCLUDE_SPEC)
AC_SUBST(TCL_LIB_FILE)
AC_SUBST(TCL_LIB_FLAG)
AC_SUBST(TCL_LIB_SPEC)
AC_SUBST(TCL_STUB_LIB_FILE)
AC_SUBST(TCL_STUB_LIB_FLAG)
AC_SUBST(TCL_STUB_LIB_SPEC)
AC_SUBST(TCL_SHLIB_SUFFIX)
fi
fi
if test "${use_tcl}" = "no" ; then
HAVE_TCL=""
else
HAVE_TCL=1
fi
AC_SUBST(HAVE_TCL)
########## ##########
# Figure out what C libraries are required to compile programs # Figure out what C libraries are required to compile programs
# that use "readline()" library. # that use "readline()" library.

View File

@@ -53,11 +53,6 @@
# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ # define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */
#endif #endif
#if CIO_WIN_WC_XLATE
/* Character used to represent a known-incomplete UTF-8 char group (<28>) */
static WCHAR cBadGroup = 0xfffd;
#endif
#if CIO_WIN_WC_XLATE #if CIO_WIN_WC_XLATE
static HANDLE handleOfFile(FILE *pf){ static HANDLE handleOfFile(FILE *pf){
int fileDesc = _fileno(pf); int fileDesc = _fileno(pf);

View File

@@ -465,6 +465,13 @@ do_execsql_test 5.3 {
t2 t2_idx_0001295b {100 20 5} t2 t2_idx_0001295b {100 20 5}
} }
do_catchsql_test 5.4 {
SELECT sqlite_expert_rem(123, 123);
} {1 {no such function: sqlite_expert_rem}}
do_catchsql_test 5.5 {
SELECT sqlite_expert_sample();
} {1 {no such function: sqlite_expert_sample}}
if 0 { if 0 {
do_test expert1-6.0 { do_test expert1-6.0 {
catchcmd :memory: { catchcmd :memory: {

View File

@@ -626,7 +626,7 @@ static int expertFilter(
pCsr->pData = 0; pCsr->pData = 0;
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
"SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName "SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName
); );
} }
@@ -1500,7 +1500,7 @@ struct IdxRemCtx {
}; };
/* /*
** Implementation of scalar function rem(). ** Implementation of scalar function sqlite_expert_rem().
*/ */
static void idxRemFunc( static void idxRemFunc(
sqlite3_context *pCtx, sqlite3_context *pCtx,
@@ -1513,7 +1513,7 @@ static void idxRemFunc(
assert( argc==2 ); assert( argc==2 );
iSlot = sqlite3_value_int(argv[0]); iSlot = sqlite3_value_int(argv[0]);
assert( iSlot<=p->nSlot ); assert( iSlot<p->nSlot );
pSlot = &p->aSlot[iSlot]; pSlot = &p->aSlot[iSlot];
switch( pSlot->eType ){ switch( pSlot->eType ){
@@ -1624,7 +1624,8 @@ static int idxPopulateOneStat1(
const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
zCols = idxAppendText(&rc, zCols, zCols = idxAppendText(&rc, zCols,
"%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s",
zComma, zName, nCol, zName, zColl
); );
zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
} }
@@ -1757,13 +1758,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
rc = sqlite3_create_function( rc = sqlite3_create_function(dbrem, "sqlite_expert_rem",
dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
); );
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3_create_function( rc = sqlite3_create_function(p->db, "sqlite_expert_sample",
p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
); );
} }
@@ -1815,6 +1816,9 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
} }
sqlite3_create_function(p->db, "sqlite_expert_rem", 2, SQLITE_UTF8, 0,0,0,0);
sqlite3_create_function(p->db, "sqlite_expert_sample", 0,SQLITE_UTF8,0,0,0,0);
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
return rc; return rc;
} }

View File

@@ -398,6 +398,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){
return 1; return 1;
} }
assert( pIter->nSnippet>=0 );
pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1;
for(i=0; i<pIter->nPhrase; i++){ for(i=0; i<pIter->nPhrase; i++){
SnippetPhrase *pPhrase = &pIter->aPhrase[i]; SnippetPhrase *pPhrase = &pIter->aPhrase[i];

View File

@@ -54,7 +54,7 @@ struct Fts5Expr {
/* /*
** eType: ** eType:
** Expression node type. Always one of: ** Expression node type. Usually one of:
** **
** FTS5_AND (nChild, apChild valid) ** FTS5_AND (nChild, apChild valid)
** FTS5_OR (nChild, apChild valid) ** FTS5_OR (nChild, apChild valid)
@@ -62,6 +62,10 @@ struct Fts5Expr {
** FTS5_STRING (pNear valid) ** FTS5_STRING (pNear valid)
** FTS5_TERM (pNear valid) ** FTS5_TERM (pNear valid)
** **
** An expression node with eType==0 may also exist. It always matches zero
** rows. This is created when a phrase containing no tokens is parsed.
** e.g. "".
**
** iHeight: ** iHeight:
** Distance from this node to furthest leaf. This is always 0 for nodes ** Distance from this node to furthest leaf. This is always 0 for nodes
** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one
@@ -2263,6 +2267,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
} }
} }
/*
** Add pSub as a child of p.
*/
static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
int ii = p->nChild; int ii = p->nChild;
if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
@@ -2407,19 +2414,23 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
"fts5: %s queries are not supported (detail!=full)", "fts5: %s queries are not supported (detail!=full)",
pNear->nPhrase==1 ? "phrase": "NEAR" pNear->nPhrase==1 ? "phrase": "NEAR"
); );
sqlite3_free(pRet); sqlite3Fts5ParseNodeFree(pRet);
pRet = 0; pRet = 0;
pNear = 0;
assert( pLeft==0 && pRight==0 );
} }
} }
}else{ }else{
assert( pNear==0 );
fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight); fts5ExprAddChildren(pRet, pRight);
pLeft = pRight = 0;
if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){
sqlite3Fts5ParseError(pParse, sqlite3Fts5ParseError(pParse,
"fts5 expression tree is too large (maximum depth %d)", "fts5 expression tree is too large (maximum depth %d)",
SQLITE_FTS5_MAX_EXPR_DEPTH SQLITE_FTS5_MAX_EXPR_DEPTH
); );
sqlite3_free(pRet); sqlite3Fts5ParseNodeFree(pRet);
pRet = 0; pRet = 0;
} }
} }
@@ -2457,6 +2468,7 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
assert( pRight->eType==FTS5_STRING assert( pRight->eType==FTS5_STRING
|| pRight->eType==FTS5_TERM || pRight->eType==FTS5_TERM
|| pRight->eType==FTS5_EOF || pRight->eType==FTS5_EOF
|| (pRight->eType==FTS5_AND && pParse->bPhraseToAnd)
); );
if( pLeft->eType==FTS5_AND ){ if( pLeft->eType==FTS5_AND ){
@@ -3104,6 +3116,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
pNode->iRowid = iRowid; pNode->iRowid = iRowid;
pNode->bEof = 0; pNode->bEof = 0;
switch( pNode->eType ){ switch( pNode->eType ){
case 0:
case FTS5_TERM: case FTS5_TERM:
case FTS5_STRING: case FTS5_STRING:
return (pNode->pNear->apPhrase[0]->poslist.n>0); return (pNode->pNear->apPhrase[0]->poslist.n>0);

View File

@@ -2235,11 +2235,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
} }
static void fts5ApiPhraseNext( static void fts5ApiPhraseNext(
Fts5Context *pUnused, Fts5Context *pCtx,
Fts5PhraseIter *pIter, Fts5PhraseIter *pIter,
int *piCol, int *piOff int *piCol, int *piOff
){ ){
UNUSED_PARAM(pUnused);
if( pIter->a>=pIter->b ){ if( pIter->a>=pIter->b ){
*piCol = -1; *piCol = -1;
*piOff = -1; *piOff = -1;
@@ -2247,8 +2246,12 @@ static void fts5ApiPhraseNext(
int iVal; int iVal;
pIter->a += fts5GetVarint32(pIter->a, iVal); pIter->a += fts5GetVarint32(pIter->a, iVal);
if( iVal==1 ){ if( iVal==1 ){
/* Avoid returning a (*piCol) value that is too large for the table,
** even if the position-list is corrupt. The caller might not be
** expecting it. */
int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol;
pIter->a += fts5GetVarint32(pIter->a, iVal); pIter->a += fts5GetVarint32(pIter->a, iVal);
*piCol = iVal; *piCol = (iVal>=nCol ? nCol-1 : iVal);
*piOff = 0; *piOff = 0;
pIter->a += fts5GetVarint32(pIter->a, iVal); pIter->a += fts5GetVarint32(pIter->a, iVal);
} }

View File

@@ -79,7 +79,7 @@ static int fts5AsciiCreate(
int i; int i;
memset(p, 0, sizeof(AsciiTokenizer)); memset(p, 0, sizeof(AsciiTokenizer));
memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
const char *zArg = azArg[i+1]; const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
fts5AsciiAddExceptions(p, zArg, 1); fts5AsciiAddExceptions(p, zArg, 1);
@@ -90,6 +90,7 @@ static int fts5AsciiCreate(
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
} }
} }
if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR;
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
fts5AsciiDelete((Fts5Tokenizer*)p); fts5AsciiDelete((Fts5Tokenizer*)p);
p = 0; p = 0;
@@ -381,17 +382,16 @@ static int fts5UnicodeCreate(
} }
/* Search for a "categories" argument */ /* Search for a "categories" argument */
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
if( 0==sqlite3_stricmp(azArg[i], "categories") ){ if( 0==sqlite3_stricmp(azArg[i], "categories") ){
zCat = azArg[i+1]; zCat = azArg[i+1];
} }
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = unicodeSetCategories(p, zCat); rc = unicodeSetCategories(p, zCat);
} }
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
const char *zArg = azArg[i+1]; const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
@@ -416,6 +416,7 @@ static int fts5UnicodeCreate(
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
} }
} }
if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
}else{ }else{
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
@@ -1298,7 +1299,7 @@ static int fts5TriCreate(
int i; int i;
pNew->bFold = 1; pNew->bFold = 1;
pNew->iFoldParam = 0; pNew->iFoldParam = 0;
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
const char *zArg = azArg[i+1]; const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
@@ -1316,6 +1317,7 @@ static int fts5TriCreate(
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
} }
} }
if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;
if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
rc = SQLITE_ERROR; rc = SQLITE_ERROR;

View File

@@ -8958,7 +8958,6 @@ do_catchsql_test 61.2 {
SELECT * FROM t3 ORDER BY rowid; SELECT * FROM t3 ORDER BY rowid;
} {/*malformed database schema*/} } {/*malformed database schema*/}
breakpoint
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
do_test 62.0 { do_test 62.0 {
sqlite3 db {} sqlite3 db {}
@@ -10768,6 +10767,7 @@ do_catchsql_test 73.1 {
reset_db reset_db
do_test 74.0 { do_test 74.0 {
sqlite3 db {} sqlite3 db {}
sqlite3_fts5_register_matchinfo db
db deserialize [decode_hexdb { db deserialize [decode_hexdb {
| size 106496 pagesize 4096 filename x.db | size 106496 pagesize 4096 filename x.db
| page 1 offset 0 | page 1 offset 0
@@ -14587,14 +14587,19 @@ do_test 74.0 {
| end x.db | end x.db
}]} {} }]} {}
do_catchsql_test 74.1 { do_catchsql_test 74.0.5 {
SELECT rowid, quote(matchinfo(t1,'p<>xyb<s')) FROM t1 WHERE t1 MATCH 'e*'; SELECT matchinfo(1,2);
} {1 {unable to use function matchinfo in the requested context}} } {1 {unable to use function matchinfo in the requested context}}
do_catchsql_test 74.1 {
SELECT rowid, quote(matchinfo(t1,'pxyb<s')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {unrecognized matchinfo flag: <}}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
reset_db reset_db
do_test 75.0 { do_test 75.0 {
sqlite3 db {} sqlite3 db {}
sqlite3_fts5_register_matchinfo db
db deserialize [decode_hexdb { db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-033d665d5caa8d.db | size 32768 pagesize 4096 filename crash-033d665d5caa8d.db
| page 1 offset 0 | page 1 offset 0
@@ -14791,7 +14796,7 @@ do_test 75.0 {
do_catchsql_test 75.1 { do_catchsql_test 75.1 {
SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*'; SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {unable to use function matchinfo in the requested context}} } {1 {database disk image is malformed}}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
reset_db reset_db

View File

@@ -0,0 +1,48 @@
# 2024 August 8
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5expr
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE x1 USING fts5(a);
INSERT INTO x1(rowid, a) VALUES (113, 'fts5 expr test');
}
do_execsql_test 1.1 {
SELECT rowid FROM x1('expr');
} {113}
for {set ii 0} {$ii < 300} {incr ii} {
set expr "expr "
append expr [string repeat "NOT abcd " $ii]
if {$ii<257} {
set res {0 113}
} else {
set res {1 {fts5 expression tree is too large (maximum depth 256)}}
}
do_catchsql_test 1.1.$ii {
SELECT rowid FROM x1($expr)
} $res
}
finish_test

View File

@@ -21,6 +21,8 @@ ifcapable !fts5 {
return return
} }
if 0 {
do_execsql_test 1.0 { do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a); CREATE VIRTUAL TABLE t1 USING fts5(a);
} }
@@ -566,5 +568,25 @@ do_execsql_test 20.5 {
SELECT rowid FROM x1 WHERE x1 MATCH 'z' OR (x1 MATCH 'a' AND x1 MATCH 'd'); SELECT rowid FROM x1 WHERE x1 MATCH 'z' OR (x1 MATCH 'a' AND x1 MATCH 'd');
} {3 1} } {3 1}
#-------------------------------------------------------------------------
}
reset_db
do_execsql_test 21.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail='none');
INSERT INTO t1(a) VALUES('a');
}
do_execsql_test 21.2 {
SELECT rank FROM ( SELECT rank FROM t1('a NOT "" NOT def') ) ORDER BY 1;
} {-1e-06}
do_execsql_test 21.3 {
SELECT rank FROM ( SELECT rank FROM t1('a NOT <20> NOT def') ) ORDER BY 1;
} {-1e-06}
do_execsql_test 21.4 {
SELECT rank FROM ( SELECT rank FROM t1('a NOT "" NOT def') );
} {-1e-06}
finish_test finish_test

View File

@@ -85,5 +85,25 @@ do_execsql_test 1.7 {
SELECT highlight(t1, 0, '>', '<') FROM t1('BB mess'); SELECT highlight(t1, 0, '>', '<') FROM t1('BB mess');
} {AAdont>BBmess<} } {AAdont>BBmess<}
# 2024-08-06 https://sqlite.org/forum/forumpost/171bcc2bcd
# Error handling of tokenize= arguments.
#
foreach {n tkz} {
1 {ascii none}
2 {unicode61 none}
3 {porter none}
4 {trigram none}
5 {ascii none 0}
6 {unicode61 none 0}
7 {porter none 0}
8 {trigram none 0}
} {
db eval {DROP TABLE IF EXISTS t2;}
do_catchsql_test 2.$n "
DROP TABLE IF EXISTS t2;
CREATE VIRTUAL TABLE t2 USING fts5(a,b,c,tokenize='$tkz');
" {1 {error in tokenizer constructor}}
}
finish_test finish_test

View File

@@ -69,6 +69,9 @@ do_execsql_test 2.0 {
INSERT INTO t1 VALUES('abcdefghijklm'); INSERT INTO t1 VALUES('abcdefghijklm');
INSERT INTO t1 VALUES('กรุงเทพมหานคร'); INSERT INTO t1 VALUES('กรุงเทพมหานคร');
} }
do_catchsql_test 2.0.1 {
CREATE VIRTUAL TABLE t2 USING fts5(z, tokenize='trigram case_sensitive');
} {1 {error in tokenizer constructor}}
foreach {tn s res} { foreach {tn s res} {
1 abc "(abc)defghijklm" 1 abc "(abc)defghijklm"
@@ -206,7 +209,7 @@ do_execsql_test 7.0 {
(20, "жираф.png"), (20, "жираф.png"),
(30, "cat.png"), (30, "cat.png"),
(40, "кот.png"), (40, "кот.png"),
(50, "misic-🎵-.mp3"); (50, "misic-🎵-.mp3");
} }
do_execsql_test 7.1 { do_execsql_test 7.1 {
SELECT rowid FROM f WHERE +filename GLOB '*ир*'; SELECT rowid FROM f WHERE +filename GLOB '*ир*';

View File

@@ -21,6 +21,9 @@ do_execsql_test 1.0 "
INSERT INTO t1 VALUES('abc\u0303defghijklm'); INSERT INTO t1 VALUES('abc\u0303defghijklm');
INSERT INTO t1 VALUES('a\u0303b\u0303c\u0303defghijklm'); INSERT INTO t1 VALUES('a\u0303b\u0303c\u0303defghijklm');
" "
do_catchsql_test 1.0.1 {
CREATE VIRTUAL TABLE t2 USING fts5(z, tokenize='trigram remove_diacritics');
} {1 {error in tokenizer constructor}}
do_execsql_test 1.1 { do_execsql_test 1.1 {
SELECT highlight(t1, 0, '(', ')') FROM t1('abc'); SELECT highlight(t1, 0, '(', ')') FROM t1('abc');
@@ -117,4 +120,18 @@ do_execsql_test 4.2 {
SELECT rowid FROM t4 WHERE z LIKE '%abc%' SELECT rowid FROM t4 WHERE z LIKE '%abc%'
} {1} } {1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE t5 USING fts5(
c1, tokenize='trigram', detail='none'
);
INSERT INTO t5(rowid, c1) VALUES(1, 'abc_____xyx_yxz');
INSERT INTO t5(rowid, c1) VALUES(2, 'abc_____xyxz');
INSERT INTO t5(rowid, c1) VALUES(3, 'ac_____xyxz');
} {}
do_execsql_test 5.1 {
SELECT rowid FROM t5 WHERE c1 LIKE 'abc%xyxz'
} {2}
finish_test finish_test

View File

@@ -470,120 +470,4 @@ do_execsql_test 8.2.3 {
SELECT rowid FROM t4 WHERE t4 MATCH 'a' ORDER BY rowid ASC; SELECT rowid FROM t4 WHERE t4 MATCH 'a' ORDER BY rowid ASC;
} {2 4} } {2 4}
#-------------------------------------------------------------------------
#
if 0 {
foreach {tn sql} {
1 {
CREATE VIRTUAL TABLE t5 USING fts4(tokenize=unicode61 [tokenchars= .]);
CREATE VIRTUAL TABLE t6 USING fts4(
tokenize=unicode61 [tokenchars=="] "tokenchars=[]");
CREATE VIRTUAL TABLE t7 USING fts4(tokenize=unicode61 [separators=x\xC4]);
}
2 {
CREATE VIRTUAL TABLE t5 USING fts4(tokenize=unicode61 "tokenchars= .");
CREATE VIRTUAL TABLE t6 USING fts4(tokenize=unicode61 "tokenchars=[=""]");
CREATE VIRTUAL TABLE t7 USING fts4(tokenize=unicode61 "separators=x\xC4");
}
3 {
CREATE VIRTUAL TABLE t5 USING fts4(tokenize=unicode61 'tokenchars= .');
CREATE VIRTUAL TABLE t6 USING fts4(tokenize=unicode61 'tokenchars=="[]');
CREATE VIRTUAL TABLE t7 USING fts4(tokenize=unicode61 'separators=x\xC4');
}
4 {
CREATE VIRTUAL TABLE t5 USING fts4(tokenize=unicode61 `tokenchars= .`);
CREATE VIRTUAL TABLE t6 USING fts4(tokenize=unicode61 `tokenchars=[="]`);
CREATE VIRTUAL TABLE t7 USING fts4(tokenize=unicode61 `separators=x\xC4`);
}
} {
do_execsql_test 9.$tn.0 {
DROP TABLE IF EXISTS t5;
DROP TABLE IF EXISTS t5aux;
DROP TABLE IF EXISTS t6;
DROP TABLE IF EXISTS t6aux;
DROP TABLE IF EXISTS t7;
DROP TABLE IF EXISTS t7aux;
}
do_execsql_test 9.$tn.1 $sql
do_execsql_test 9.$tn.2 {
CREATE VIRTUAL TABLE t5aux USING fts4aux(t5);
INSERT INTO t5 VALUES('one two three/four.five.six');
SELECT * FROM t5aux;
} {
four.five.six * 1 1 four.five.six 0 1 1
{one two three} * 1 1 {one two three} 0 1 1
}
do_execsql_test 9.$tn.3 {
CREATE VIRTUAL TABLE t6aux USING fts4aux(t6);
INSERT INTO t6 VALUES('alpha=beta"gamma/delta[epsilon]zeta');
SELECT * FROM t6aux;
} {
{alpha=beta"gamma} * 1 1 {alpha=beta"gamma} 0 1 1
{delta[epsilon]zeta} * 1 1 {delta[epsilon]zeta} 0 1 1
}
do_execsql_test 9.$tn.4 {
CREATE VIRTUAL TABLE t7aux USING fts4aux(t7);
INSERT INTO t7 VALUES('alephxbeth\xC4gimel');
SELECT * FROM t7aux;
} {
aleph * 1 1 aleph 0 1 1
beth * 1 1 beth 0 1 1
gimel * 1 1 gimel 0 1 1
}
}
# Check that multiple options are handled correctly.
#
do_execsql_test 10.1 {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts4(tokenize=unicode61
"tokenchars=xyz" "tokenchars=.=" "separators=.=" "separators=xy"
"separators=a" "separators=a" "tokenchars=a" "tokenchars=a"
);
INSERT INTO t1 VALUES('oneatwoxthreeyfour');
INSERT INTO t1 VALUES('a.single=word');
CREATE VIRTUAL TABLE t1aux USING fts4aux(t1);
SELECT * FROM t1aux;
} {
.single=word * 1 1 .single=word 0 1 1
four * 1 1 four 0 1 1
one * 1 1 one 0 1 1
three * 1 1 three 0 1 1
two * 1 1 two 0 1 1
}
# Test that case folding happens after tokenization, not before.
#
do_execsql_test 10.2 {
DROP TABLE IF EXISTS t2;
CREATE VIRTUAL TABLE t2 USING fts4(tokenize=unicode61 "separators=aB");
INSERT INTO t2 VALUES('oneatwoBthree');
INSERT INTO t2 VALUES('onebtwoAthree');
CREATE VIRTUAL TABLE t2aux USING fts4aux(t2);
SELECT * FROM t2aux;
} {
one * 1 1 one 0 1 1
onebtwoathree * 1 1 onebtwoathree 0 1 1
three * 1 1 three 0 1 1
two * 1 1 two 0 1 1
}
# Test that the tokenchars and separators options work with the
# fts3tokenize table.
#
do_execsql_test 11.1 {
CREATE VIRTUAL TABLE ft1 USING fts3tokenize(
"unicode61", "tokenchars=@.", "separators=1234567890"
);
SELECT token FROM ft1 WHERE input = 'berlin@street123sydney.road';
} {
berlin@street sydney.road
}
}
finish_test finish_test

View File

@@ -15,10 +15,20 @@
** Two SQL functions are implemented: ** Two SQL functions are implemented:
** **
** sha3(X,SIZE) ** sha3(X,SIZE)
** sha3_query(Y,SIZE) ** sha3_agg(Y,SIZE)
** sha3_query(Z,SIZE)
** **
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
** X is NULL. ** X is NULL. If inputs X is text, the UTF-8 rendering of that text is
** used to compute the hash. If X is a BLOB, then the binary data of the
** blob is used to compute the hash. If X is an integer or real number,
** then that number if converted into UTF-8 text and the hash is computed
** over the text.
**
** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since
** order is important for the hash, it is recommended that the Y expression
** by followed by an ORDER BY clause to guarantee that the inputs occur
** in the desired order.
** **
** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
** and returns a hash of their results. ** and returns a hash of their results.
@@ -26,6 +36,68 @@
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
** is used. If SIZE is included it must be one of the integers 224, 256, ** is used. If SIZE is included it must be one of the integers 224, 256,
** 384, or 512, to determine SHA3 hash variant that is computed. ** 384, or 512, to determine SHA3 hash variant that is computed.
**
** Because the sha3_agg() and sha3_query() functions compute a hash over
** multiple values, the values are encode to use include type information.
**
** In sha3_agg(), the sequence of bytes that gets hashed for each input
** Y depends on the datatype of Y:
**
** typeof(Y)='null' A single "N" is hashed. (One byte)
**
** typeof(Y)='integer' The data hash is the character "I" followed
** by an 8-byte big-endian binary of the
** 64-bit signed integer. (Nine bytes total.)
**
** typeof(Y)='real' The character "F" followed by an 8-byte
** big-ending binary of the double. (Nine
** bytes total.)
**
** typeof(Y)='text' The hash is over prefix "Tnnn:" followed
** by the UTF8 encoding of the text. The "nnn"
** in the prefix is the minimum-length decimal
** representation of the octet_length of the text.
** Notice the ":" at the end of the prefix, which
** is needed to separate the prefix from the
** content in cases where the content starts
** with a digit.
**
** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed
** by the binary content of the blob. The "nnn"
** in the prefix is the mimimum-length decimal
** representation of the byte-length of the blob.
**
** According to the rules above, all of the following SELECT statements
** should return TRUE:
**
** SELECT sha3(1) = sha3('1');
**
** SELECT sha3('hello') = sha3(x'68656c6c6f');
**
** WITH a(x) AS (VALUES('xyzzy'))
** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a;
**
** WITH a(x) AS (VALUES(x'010203'))
** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a;
**
** WITH a(x) AS (VALUES(0x123456))
** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a;
**
** WITH a(x) AS (VALUES(100.015625))
** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a;
**
** WITH a(x) AS (VALUES(NULL))
** SELECT sha3_agg(x) = sha3('N') FROM a;
**
**
** In sha3_query(), individual column values are encoded as with
** sha3_agg(), but with the addition that a single "R" character is
** inserted at the start of each row.
**
** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER
** clause if NULL rows should be excluded:
**
** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1;
*/ */
#include "sqlite3ext.h" #include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1 SQLITE_EXTENSION_INIT1
@@ -75,6 +147,7 @@ struct SHA3Context {
unsigned nRate; /* Bytes of input accepted per Keccak iteration */ unsigned nRate; /* Bytes of input accepted per Keccak iteration */
unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
unsigned iSize; /* 224, 256, 358, or 512 */
}; };
/* /*
@@ -404,6 +477,7 @@ static void KeccakF1600Step(SHA3Context *p){
*/ */
static void SHA3Init(SHA3Context *p, int iSize){ static void SHA3Init(SHA3Context *p, int iSize){
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
p->iSize = iSize;
if( iSize>=128 && iSize<=512 ){ if( iSize>=128 && iSize<=512 ){
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
}else{ }else{
@@ -547,6 +621,60 @@ static void sha3_step_vformat(
SHA3Update(p, (unsigned char*)zBuf, n); SHA3Update(p, (unsigned char*)zBuf, n);
} }
/*
** Update a SHA3Context using a single sqlite3_value.
*/
static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){
switch( sqlite3_value_type(pVal) ){
case SQLITE_NULL: {
SHA3Update(p, (const unsigned char*)"N",1);
break;
}
case SQLITE_INTEGER: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
sqlite3_int64 v = sqlite3_value_int64(pVal);
memcpy(&u, &v, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'I';
SHA3Update(p, x, 9);
break;
}
case SQLITE_FLOAT: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
double r = sqlite3_value_double(pVal);
memcpy(&u, &r, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'F';
SHA3Update(p,x,9);
break;
}
case SQLITE_TEXT: {
int n2 = sqlite3_value_bytes(pVal);
const unsigned char *z2 = sqlite3_value_text(pVal);
sha3_step_vformat(p,"T%d:",n2);
SHA3Update(p, z2, n2);
break;
}
case SQLITE_BLOB: {
int n2 = sqlite3_value_bytes(pVal);
const unsigned char *z2 = sqlite3_value_blob(pVal);
sha3_step_vformat(p,"B%d:",n2);
SHA3Update(p, z2, n2);
break;
}
}
}
/* /*
** Implementation of the sha3_query(SQL,SIZE) function. ** Implementation of the sha3_query(SQL,SIZE) function.
** **
@@ -636,54 +764,7 @@ static void sha3QueryFunc(
while( SQLITE_ROW==sqlite3_step(pStmt) ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){
SHA3Update(&cx,(const unsigned char*)"R",1); SHA3Update(&cx,(const unsigned char*)"R",1);
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
switch( sqlite3_column_type(pStmt,i) ){ sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i));
case SQLITE_NULL: {
SHA3Update(&cx, (const unsigned char*)"N",1);
break;
}
case SQLITE_INTEGER: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
memcpy(&u, &v, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'I';
SHA3Update(&cx, x, 9);
break;
}
case SQLITE_FLOAT: {
sqlite3_uint64 u;
int j;
unsigned char x[9];
double r = sqlite3_column_double(pStmt,i);
memcpy(&u, &r, 8);
for(j=8; j>=1; j--){
x[j] = u & 0xff;
u >>= 8;
}
x[0] = 'F';
SHA3Update(&cx,x,9);
break;
}
case SQLITE_TEXT: {
int n2 = sqlite3_column_bytes(pStmt, i);
const unsigned char *z2 = sqlite3_column_text(pStmt, i);
sha3_step_vformat(&cx,"T%d:",n2);
SHA3Update(&cx, z2, n2);
break;
}
case SQLITE_BLOB: {
int n2 = sqlite3_column_bytes(pStmt, i);
const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
sha3_step_vformat(&cx,"B%d:",n2);
SHA3Update(&cx, z2, n2);
break;
}
}
} }
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
@@ -691,6 +772,44 @@ static void sha3QueryFunc(
sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
} }
/*
** xStep function for sha3_agg().
*/
static void sha3AggStep(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
SHA3Context *p;
p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p));
if( p==0 ) return;
if( p->nRate==0 ){
int sz = 256;
if( argc==2 ){
sz = sqlite3_value_int(argv[1]);
if( sz!=224 && sz!=384 && sz!=512 ){
sz = 256;
}
}
SHA3Init(p, sz);
}
sha3UpdateFromValue(p, argv[0]);
}
/*
** xFinal function for sha3_agg().
*/
static void sha3AggFinal(sqlite3_context *context){
SHA3Context *p;
p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p));
if( p==0 ) return;
if( p->iSize ){
sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT);
}
}
#ifdef _WIN32 #ifdef _WIN32
__declspec(dllexport) __declspec(dllexport)
@@ -711,6 +830,16 @@ int sqlite3_shathree_init(
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
0, sha3Func, 0, 0); 0, sha3Func, 0, 0);
} }
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3_agg", 1,
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
0, 0, sha3AggStep, sha3AggFinal);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3_agg", 2,
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
0, 0, sha3AggStep, sha3AggFinal);
}
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha3_query", 1, rc = sqlite3_create_function(db, "sha3_query", 1,
SQLITE_UTF8 | SQLITE_DIRECTONLY, SQLITE_UTF8 | SQLITE_DIRECTONLY,

View File

@@ -679,6 +679,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
** near the end of a corrupt record. */ ** near the end of a corrupt record. */
rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
assert( pCsr->rec.aBuf!=0 );
assert( nPayload!=0 ); assert( nPayload!=0 );
/* Load the nLocal bytes of payload */ /* Load the nLocal bytes of payload */

View File

@@ -363,8 +363,8 @@ static int recoverError(
va_start(ap, zFmt); va_start(ap, zFmt);
if( zFmt ){ if( zFmt ){
z = sqlite3_vmprintf(zFmt, ap); z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
} }
va_end(ap);
sqlite3_free(p->zErrMsg); sqlite3_free(p->zErrMsg);
p->zErrMsg = z; p->zErrMsg = z;
p->errCode = errCode; p->errCode = errCode;

106
manifest
View File

@@ -1,11 +1,11 @@
C Fix\ssome\ssigned/unsigned\scompiler\swarnings\son\sthis\sbranch. C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\swal2\sbranch.
D 2024-08-09T10:56:11.486 D 2024-08-16T18:58:50.275
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 4c8be28f7ad963012161999f22c029a9bdac19c78df36879c85e5d3502f856fd F Makefile.in baf73332b7f1eb44791fbfed4d944bea6d12a818d78d66addac97df36885c9e3
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc e0e79546f90e2a5e9c72b84eeb4ff4f1c84ce274fb5f65f04f4327e8f6091f31 F Makefile.msc f430e06739c5747ccf741f2307b673f9e22b6845e49ffac7bedbfb371f239bfd
F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3 F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -35,8 +35,8 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034
F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5 F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure e0efd210b151971f4158e3fdf93b34322882a668a96f88b6167a6f7a51edebec x F configure 2e5058c2ba2c6b50a01cf50c158180c4ec969b2068c2e361dfbfc875ec3f9d1c x
F configure.ac 7361a1dd862c0ba0d2daa3d978bc3b93fcccc1ef3efe204d0238722c19bbdcf5 F configure.ac b7e26a699a2ffc5eb7a25636f32755c27bbb665777b68ef35a90c1ee9bd9d469
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d
@@ -54,12 +54,12 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94 F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
F ext/consio/console_io.c f32b757c9ee7fdf68e7586bee306f8368759e7cd12febb2a6839199b1c1af395 x F ext/consio/console_io.c b4885dfea71ed583315de8f0792a29d5fc7c7460b4a26c0aebe5cda5da8b38f8 x
F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646 F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4 F ext/expert/sqlite3expert.c 8b09aeb2b95a9fca8b6628b522bf4d69aa746ff64c38eb1e99a9b5fad8cf03b9
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70 F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
@@ -75,7 +75,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8 F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8
F ext/fts3/fts3_snippet.c 610328fe128c047c6b0eba77768982ccf3933daae095d497949a75c9dfd47409 F ext/fts3/fts3_snippet.c c38117a2e4dcc9485a170a57a6134423955247b230fef7073c46fa9c51239540
F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69 F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69
F ext/fts3/fts3_test.c 7a9cb3d61774134211bf4bfdf1adcb581a1a0377f2d050a121ae7ab44baef0e3 F ext/fts3/fts3_test.c 7a9cb3d61774134211bf4bfdf1adcb581a1a0377f2d050a121ae7ab44baef0e3
F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962 F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962
@@ -98,15 +98,15 @@ F ext/fts5/fts5Int.h 41fb3a2dd40e818cc96c6f4176dbdf2aaa8f57043cfc9a8f2676e7e6a72
F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1 F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
F ext/fts5/fts5_config.c 68cb87a49215f8e7028000b681df4057c430a4a6afbd676463886da94c9e1c37 F ext/fts5/fts5_config.c 68cb87a49215f8e7028000b681df4057c430a4a6afbd676463886da94c9e1c37
F ext/fts5/fts5_expr.c c7336d5f9ecc0e2b014d700be2bec0ea383b0e82c494a7c5c4ac622327c2bfad F ext/fts5/fts5_expr.c 4b7734db98393d6f7fbc5c9c71ebcabe70110f7df08f6b136d096a1eaee0f56a
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
F ext/fts5/fts5_main.c 77fefb37e7931095a5ff271a28fbe4f73ec46d5492ef1f35d405d98e137ad8ed F ext/fts5/fts5_main.c 6ec7a7d005c632d86e510ddfaca56b197a5b20b61848415764b91bd27d1e4f84
F ext/fts5/fts5_storage.c 1d7e08d4331da2f3f7e78e70eef2ed6a013d91ba16175c651adbc5ad672235aa F ext/fts5/fts5_storage.c 1d7e08d4331da2f3f7e78e70eef2ed6a013d91ba16175c651adbc5ad672235aa
F ext/fts5/fts5_tcl.c 5ca3e3e35010d326f5b821a563e4fcde3913e052935f5c2c72c264122a26b48f F ext/fts5/fts5_tcl.c 5ca3e3e35010d326f5b821a563e4fcde3913e052935f5c2c72c264122a26b48f
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be F ext/fts5/fts5_tokenize.c 63ebe9057ed3f4dfc49944bc4aee3d3b745cc2faff73bc152ed3554ed3bf9cf4
F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0 F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0
@@ -148,7 +148,7 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b
F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a
F ext/fts5/test/fts5corrupt.test a9bda1ded5112ebf1ee85c5381bd1fe8974952e2523cede4d5072804d2011503 F ext/fts5/test/fts5corrupt.test a9bda1ded5112ebf1ee85c5381bd1fe8974952e2523cede4d5072804d2011503
F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4 F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4
F ext/fts5/test/fts5corrupt3.test 3cbb18b8970c66ed4d741eb3eecf42c986bd4c430572a5050350a72030de66cf F ext/fts5/test/fts5corrupt3.test b5f35d72af85b1d5a092b3d5e437f7944d142dd0b0c87b928fd0436a0aec6987
F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733
F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76 F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
@@ -160,6 +160,7 @@ F ext/fts5/test/fts5dlidx.test a7c42b0a74dc7c8aa1a46d586e0aadda4b6cc42c24450f8d3
F ext/fts5/test/fts5doclist.test b7cb84758504519746957802db9cd31187bb4e0028b89d9087ba06e26cc4155f F ext/fts5/test/fts5doclist.test b7cb84758504519746957802db9cd31187bb4e0028b89d9087ba06e26cc4155f
F ext/fts5/test/fts5ea.test cefdf66024550fa7920c03395c71ce5046235ed1a1a7a469d79b19e7aad5afb5 F ext/fts5/test/fts5ea.test cefdf66024550fa7920c03395c71ce5046235ed1a1a7a469d79b19e7aad5afb5
F ext/fts5/test/fts5eb.test 401f756fdb77083aeba8b696c1e0ad4d834c39dbd6f17e492bb55a2ad64b4296 F ext/fts5/test/fts5eb.test 401f756fdb77083aeba8b696c1e0ad4d834c39dbd6f17e492bb55a2ad64b4296
F ext/fts5/test/fts5expr.test 7e1b2d075b63b727a624a378c2c09f94296a93dc4ae968aad67f8d9f3810c266
F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd
F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344
F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522
@@ -188,7 +189,7 @@ F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fc
F ext/fts5/test/fts5matchinfo.test 877520582feb86bbfd95ab780099bcba4526f18ac75ee34979144cf86ba3a5a3 F ext/fts5/test/fts5matchinfo.test 877520582feb86bbfd95ab780099bcba4526f18ac75ee34979144cf86ba3a5a3
F ext/fts5/test/fts5merge.test 2654df0bcdb2d117c2d38b6aeb0168061be01c643f9e9194b36c43a2970e8082 F ext/fts5/test/fts5merge.test 2654df0bcdb2d117c2d38b6aeb0168061be01c643f9e9194b36c43a2970e8082
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
F ext/fts5/test/fts5misc.test b88aa28ff20238b394495b0795cddca1a62b98fa09b99e462a8abc572d04ee88 F ext/fts5/test/fts5misc.test b1682a40061bc58dcc62bbad48938fc5214d2ac6a868a8899c0c3d1930f1115d
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
F ext/fts5/test/fts5near.test 33d60867581066e5db7016deb5d651628125d7ff4e0233a88175aa5b65874c74 F ext/fts5/test/fts5near.test 33d60867581066e5db7016deb5d651628125d7ff4e0233a88175aa5b65874c74
@@ -230,13 +231,13 @@ F ext/fts5/test/fts5synonym2.test 58f357b997cf2fedeeb9d0de4db9f880fa96fa2fe27a74
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98 F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98
F ext/fts5/test/fts5tokenizer2.test 9c1ad8ef0465076cbc9ff5c764782594329b3bce3e0f6a931a026902d006f495 F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6
F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0 F ext/fts5/test/fts5trigram.test be914555deb8504dde682bd5aa343d00c4da37dfad20709a5bac30d5f97f2ef5
F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566 F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61
F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2 F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
F ext/fts5/test/fts5unicode.test 41898f7e476e6515cd4b737c02a442cda5a580a74509788aa9072a2074948e0e F ext/fts5/test/fts5unicode.test 41898f7e476e6515cd4b737c02a442cda5a580a74509788aa9072a2074948e0e
F ext/fts5/test/fts5unicode2.test 3ff7ea5d27310d65441779d9919055084cdbb570ed7743af1f8f4eeca1a3be26 F ext/fts5/test/fts5unicode2.test a5c38179b311a188b24376772309389b073c996f52b79bb9ca760a19e62043ea
F ext/fts5/test/fts5unicode3.test f4891a3dac3b49c3d7c0fdb29566e9eb0ecff35263370c89f9661b1952b20818 F ext/fts5/test/fts5unicode3.test f4891a3dac3b49c3d7c0fdb29566e9eb0ecff35263370c89f9661b1952b20818
F ext/fts5/test/fts5unicode4.test 728c8f0caafb05567f524ad313d9f8b780fa45987b8a8df04eff87923c74b4d0 F ext/fts5/test/fts5unicode4.test 728c8f0caafb05567f524ad313d9f8b780fa45987b8a8df04eff87923c74b4d0
F ext/fts5/test/fts5unindexed.test 168838d2c385e131120bbf5b516d2432a5fabc4caa2259c932e1d49ae209a4ae F ext/fts5/test/fts5unindexed.test 168838d2c385e131120bbf5b516d2432a5fabc4caa2259c932e1d49ae209a4ae
@@ -416,7 +417,7 @@ F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d385
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
F ext/misc/series.c d96e5aac21658c6b5d54f918ac140460ec7197734c1a4fba806950831a7b1e7a F ext/misc/series.c d96e5aac21658c6b5d54f918ac140460ec7197734c1a4fba806950831a7b1e7a
F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d
F ext/misc/shathree.c 543af7ce71d391cd3a9ab6924a6a1124efc63211fd0f2e240dc4b56077ba88ac F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea
F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634
@@ -482,7 +483,7 @@ F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69
F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8 F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8
F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0 F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0
F ext/recover/dbdata.c a22ecd689f00ff2ad33b5633c4ef84c8f088c65faeac18d4eb73c128395c7aec F ext/recover/dbdata.c 5295f4f922b60d7035b6b9fd5846b13071b9d97ed7fad8496837bb7640d24771
F ext/recover/recover1.test e16d78e94183562abff569967b18b7c77451d7044365516cd0fe14713a284851 F ext/recover/recover1.test e16d78e94183562abff569967b18b7c77451d7044365516cd0fe14713a284851
F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a
F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3
@@ -498,7 +499,7 @@ F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52
F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
F ext/recover/sqlite3recover.c 65ef0f56301a16c0536c9839fb7e23540c9c4f75da0afe3b7b4d163c8f624404 F ext/recover/sqlite3recover.c 2dcf6b56c5e0e2b43fc4c6115b689ab194c374ced7f7f8380ad9a24d8ef24ac9
F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -693,8 +694,8 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
F src/alter.c e1b6782b85dd758f89e5c588e4e3eb82638c2dafc0c857b79a43bb8ec1746fca F src/alter.c bb663fddf1fe0e2e6d8758b2b7fb6374e7c057a6ca3955f37a48986806029765
F src/analyze.c 5c4e2bfd0aa8e5157f7fb91a17d86905510a74397326dc5767ec4e0588a4eea5 F src/analyze.c 30bf40ec4208ead9e977bec017bccc8a9681820936e38ca5a4a7443100a6d5c5
F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39
F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
@@ -720,7 +721,7 @@ F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c F src/insert.c 8ff11e9e54c5fc1fe89707b3d41cf44ad2822f712bd3b5da68338ea42518847e
F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
@@ -750,7 +751,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c d2f77fe2133a3c33ee5552bde00efec2afae790a75e7903aeff3bdb193f30a8a F src/pager.c d2f77fe2133a3c33ee5552bde00efec2afae790a75e7903aeff3bdb193f30a8a
F src/pager.h fc0c95d27f2aefffcb39b4373b3557e89e1b4b9a36b183cc04d6f22002bf0ad2 F src/pager.h fc0c95d27f2aefffcb39b4373b3557e89e1b4b9a36b183cc04d6f22002bf0ad2
F src/parse.y 2bd540b3b1e79017eb41fca2396633a75e7dd430c05383c61fe52c6f4e97c6d8 F src/parse.y 318ef86fbe358b1a93262a42e152f37b97b3fddae8d319dffbd24ce2300f6c88
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
@@ -759,20 +760,20 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 7e8d23ce7cdbfedf351a47e759f2722e8182ca10fd7580be43f4ce1f1a228145 F src/resolve.c 0aee8a2e5340ba95a966917305dfaff5147fcad78d0839cd364b16e4746b8bcb
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 6a95a2bffa6c09584dea99db5a7ae10c813305c09c92920ffc54f6eae2ba399e F src/select.c 6a95a2bffa6c09584dea99db5a7ae10c813305c09c92920ffc54f6eae2ba399e
F src/shell.c.in 44c02fd1581d95e066b479241e081f37dc95c98452badd03627ef2a1c21bdc80 F src/shell.c.in 94571558b0fb28c37a5cf6dbd6ea27285341023a28a8cb5795cd2768fab67704
F src/sqlite.h.in 1ad9110150773c38ebababbad11b5cb361bcd3997676dec1c91ac5e0416a7b86 F src/sqlite.h.in 1ad9110150773c38ebababbad11b5cb361bcd3997676dec1c91ac5e0416a7b86
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h b77218c425891c7c90506c77fd2eb13bae03628d065b44fffeb37401cd955ac1 F src/sqliteInt.h 128b9004698cc79993d5369d7d1763deaf8bbf26e5e8931ec540707e5a7238df
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 8e86ab2595c2ff7bb155331fb173e560180235bceaacce7931a718b1c2e6dfb4 F src/tclsqlite.c c6888598f08dee3d9112a38ef42c8f5c89ca7f3190f4694744d0b84250f4bf8c
F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262 F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
F src/test1.c 51159784f29d3dfd4b50fd6ed9c43c8f7f36925c501a3ad3083528e5e5544bd7 F src/test1.c 3f18399557d954bc85f4564aec8ea1777d2161a81d98a3ff6c9e9046bf3554c1
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -792,7 +793,7 @@ F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c9
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5
F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851 F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851
F src/test_hexio.c 5ac8f07ac25f48651e7f25bcf95727840b901d5aa348c13dde51a6e603f3a934 F src/test_hexio.c 35704e7db83fe1a0e1a014bacb17de97d7d1e89af3356a9da04e37cdaa087c09
F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e
F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5
F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293
@@ -814,7 +815,7 @@ F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e
F src/test_superlock.c 18355ca274746aa6909e3744163e5deb1196a85d5bc64b9cd377273cef626da7 F src/test_superlock.c 18355ca274746aa6909e3744163e5deb1196a85d5bc64b9cd377273cef626da7
F src/test_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c F src/test_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c
F src/test_tclsh.c efa390787ecfbae22e0a0a05d9ee771a9db78ffd84e2eea092899c2d80d57b0e F src/test_tclsh.c efa390787ecfbae22e0a0a05d9ee771a9db78ffd84e2eea092899c2d80d57b0e
F src/test_tclvar.c 2c42fe9a74af0f3c8f87a339f66d9d3bd3a967fb5db1ed2500348055b954e391 F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424
F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb
F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3 F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3
F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2 F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2
@@ -839,7 +840,7 @@ F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
F src/vdbeaux.c cac65e6512c51f2a2419c53f41c8162b8344a99053bc77844d66536f5e4fd3fb F src/vdbeaux.c cac65e6512c51f2a2419c53f41c8162b8344a99053bc77844d66536f5e4fd3fb
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5 F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89 F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b
@@ -847,8 +848,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 7fe7aa272006e5070b31109757bb45d9e387d4df0c58a7ee56614764aaa39651 F src/wal.c 7fe7aa272006e5070b31109757bb45d9e387d4df0c58a7ee56614764aaa39651
F src/wal.h 97b8a9903387401377b59507e86b93a148ef1ad4e5ce0f23659a12dcdce56af2 F src/wal.h 97b8a9903387401377b59507e86b93a148ef1ad4e5ce0f23659a12dcdce56af2
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
F src/where.c d87a4160e26a7a96a2f7ca283b147b1b283b54ba545c46acb14cfcc6ec37ae9e F src/where.c f5be664f3379c9f930696e339ec4ef4c1187af860cca727411156101fae6b677
F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65 F src/whereInt.h 6444b888ce395cb80511284b8a73b63472d34247fcb1b125ee06a54fa6ae878e
F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290 F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290
F src/window.c 1e40ffc509bae21e466f6106382d238e91eb73edd4ba10e66ca4fd7af2b96896 F src/window.c 1e40ffc509bae21e466f6106382d238e91eb73edd4ba10e66ca4fd7af2b96896
@@ -948,6 +949,7 @@ F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede3967
F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f
F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce
F test/bestindexC.test 2df6ada16d8f00d9bb6a9664d9c323560aeed0e0ebc7a32b99d85d70037fd250 F test/bestindexC.test 2df6ada16d8f00d9bb6a9664d9c323560aeed0e0ebc7a32b99d85d70037fd250
F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3
F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
@@ -1113,7 +1115,7 @@ F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a
F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec
F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 815418b69f6be3a27037b1736c54699c72cc3e2e6b0bc878c01464d1dcec65fe F test/eqp.test 82f221e8cd588434d7f3bba9a0f4c78cbe7a541615a41632e12f50608bfb4a99
F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd
F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9
F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0 F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0
@@ -1213,7 +1215,7 @@ F test/fts3query.test 45806a302921b245a9dba5d85c9d51fb98b3f137eea6e6bf6eae4883e0
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
F test/fts3snippet.test 0887196d67cffbe365edde535b95ecc642a532ce8551ccd9a73aab5999c3ffae F test/fts3snippet.test 560c7f38c5fa591d88e367eac1313b64e503625616708ff61da9d5f52cbf75e5
F test/fts3snippet2.test 03f6738ab3897bea2ba6be424a0613872e167acbf37a66200d655d737b470f65 F test/fts3snippet2.test 03f6738ab3897bea2ba6be424a0613872e167acbf37a66200d655d737b470f65
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
@@ -1260,7 +1262,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzzcheck.c dc159967609d00b0cfe619e735cbbf8482570aca85711397034b0662b6c18fc7 F test/fuzzcheck.c 6e87c27df3d95c556870187987dff6efdc712b5cea60abedc8ab9215f471907a
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517 F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1272,7 +1274,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
F test/fuzzinvariants.c 0729b9d8ed77ad0f8c5c7601168a707d5803087d2da030ede9057c51c809cc6c F test/fuzzinvariants.c 81167c9a7e82c0539a1d704aeb3384046d01f4108cda160a2447cb2a149d6362
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -1493,6 +1495,7 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5 F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5
F test/orderbyB.test 32576c7b138105bc72f7fbf33bd320ca3a7d303641fc939e0e56af6cba884b3d
F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5 F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5
F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715 F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17 F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
@@ -1592,7 +1595,7 @@ F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f
F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select7.test b825420da8a0b5722fdb77f3369f6396a3d198c46e8787eb26ff9425d4ac9d27
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812 F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812
F test/selectA.test 1da8ce3884c326e11d2855baffb76436b0d7e044404af8a2a70d1399a4ff7e29 F test/selectA.test 1da8ce3884c326e11d2855baffb76436b0d7e044404af8a2a70d1399a4ff7e29
@@ -1632,7 +1635,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
F test/shrink.test 2668e607dcdfa19c52828c09b69685b38da793856582ae31debf79d90c7bbbdc F test/shrink.test 2668e607dcdfa19c52828c09b69685b38da793856582ae31debf79d90c7bbbdc
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test e03ba5b977da6fd71662a4b0a668f04053bda4b187ff3214db7533e28c732279 F test/skipscan1.test 9cbbb6575517b15292bd87ee85b853bbd3cd4b4735d69b0f083020cec16ff304
F test/skipscan2.test b032ed3e0ba5caa4df6c43ef22c31566aac67783bc031869155989a7ccdb5bd5 F test/skipscan2.test b032ed3e0ba5caa4df6c43ef22c31566aac67783bc031869155989a7ccdb5bd5
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test 0672103fd2c8f96bd114133f356192b35ece45c794fe3677e1d9e5e3104a608e F test/skipscan5.test 0672103fd2c8f96bd114133f356192b35ece45c794fe3677e1d9e5e3104a608e
@@ -1706,8 +1709,8 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16 F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl e216c7a6f61b20701076f2968ed00777c69a625df66d08275e2965770478070c F test/tester.tcl fa7006ff3843b9bf77a09ac474fa411ccaa89e33fb45ba30224e31fd15ab0937
F test/testrunner.tcl 2d100e73245e5f423942b6c198176c699137ee65192ed872bd8c9d4ac2c779b3 F test/testrunner.tcl 5d02deeba7a53baeadae6aa7641d90aac58fdfa3a7bcac85cfcfd752b1aab87c
F test/testrunner_data.tcl c5ae2b1f9a99210b0600d002fb3af1fee350997cee9416551e83b93501360ebf F test/testrunner_data.tcl c5ae2b1f9a99210b0600d002fb3af1fee350997cee9416551e83b93501360ebf
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
@@ -2079,13 +2082,13 @@ F test/windowE.test 6ba0c8048e4cc02b942e56640f8fcd50fd7ca72c876656c40f6baf42e316
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c
F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df F test/windowpushd.test c420e2265f0e09a0e798d0513a660d71b51602088d81b3dbd038918ee1339dcc
F test/with1.test b93833890e5d2a368e78747f124503a0159aa029b98e9ed4795ebf630b2efd3d F test/with1.test b93833890e5d2a368e78747f124503a0159aa029b98e9ed4795ebf630b2efd3d
F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28df F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28df
F test/with3.test e30369ea27aa27eb1bda4c5e510c8a9f782c8afd2ab99d1a02b8a7f25a5d3e65 F test/with3.test e30369ea27aa27eb1bda4c5e510c8a9f782c8afd2ab99d1a02b8a7f25a5d3e65
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
F test/with6.test e097a03e5c898a8cd8f3a2d6a994ec510ea4376b5d484c2b669a41001e7758c8 F test/with6.test 9ff3503c3ff7cd459dc4852a02aaefa998dccace53f4142a0eb726174ad5984a
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217 F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
@@ -2107,6 +2110,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x
F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5 F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5
F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b8421e1428a
F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca
@@ -2118,6 +2122,7 @@ F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651e
F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
F tool/fast_vacuum.c c129ae2924a48310c7b766810391da9e8fda532b9f6bd3f9a9e3a799a1b42af9 F tool/fast_vacuum.c c129ae2924a48310c7b766810391da9e8fda532b9f6bd3f9a9e3a799a1b42af9
F tool/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/fuzzershell.c 41480c8a1e4749351f381431ecfdfceba645396c5d836f8d26b51a33c4a21b33 F tool/fuzzershell.c 41480c8a1e4749351f381431ecfdfceba645396c5d836f8d26b51a33c4a21b33
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
@@ -2214,9 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P eac582056fcf6210bf90576cce30c087503b864dc8d558f2998f04b3d1bfb569 P 681d228023efb902b9039acf33600dd91f158e622d4dc0b434ed74f39ce0070a 41a41c173a9d15d94f23d73a5c04bfb1616cb9223bc81d41808f9b4d00817fbf 7a0cdc7edb704a88a77b748cd28f6e00c49849cc2c1af838b95b34232ecc21f9
Q +d615d5291871ba120d916c4722e6067e083f394c6a7f398059442b36c4500718 R e2d0f4bcac8e3e78ac9fc97bce4611d5
R b7562e9c3a0decaefc4ce79c3da81d61 U drh
U dan Z d38ddf7cbe3129369a9ec5b4eb3fffb1
Z 2f95d8eb17e333c43b562f53602b1258
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
681d228023efb902b9039acf33600dd91f158e622d4dc0b434ed74f39ce0070a a78208b597ee34b1121dd8014b3c1376b46baddff41448c96a37723cc9ede921

View File

@@ -1320,7 +1320,7 @@ static int renameResolveTrigger(Parse *pParse){
/* ALWAYS() because if the table of the trigger does not exist, the /* ALWAYS() because if the table of the trigger does not exist, the
** error would have been hit before this point */ ** error would have been hit before this point */
if( ALWAYS(pParse->pTriggerTab) ){ if( ALWAYS(pParse->pTriggerTab) ){
rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0;
} }
/* Resolve symbols in WHEN clause */ /* Resolve symbols in WHEN clause */

View File

@@ -1797,12 +1797,13 @@ static int loadStatTbl(
while( sqlite3_step(pStmt)==SQLITE_ROW ){ while( sqlite3_step(pStmt)==SQLITE_ROW ){
int nIdxCol = 1; /* Number of columns in stat4 records */ int nIdxCol = 1; /* Number of columns in stat4 records */
char *zIndex; /* Index name */ char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */ Index *pIdx; /* Pointer to the index object */
int nSample; /* Number of samples */ int nSample; /* Number of samples */
int nByte; /* Bytes of space required */ int nByte; /* Bytes of space required */
int i; /* Bytes of space required */ int i; /* Bytes of space required */
tRowcnt *pSpace; tRowcnt *pSpace; /* Available allocated memory space */
u8 *pPtr; /* Available memory as a u8 for easier manipulation */
zIndex = (char *)sqlite3_column_text(pStmt, 0); zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue; if( zIndex==0 ) continue;
@@ -1822,7 +1823,7 @@ static int loadStatTbl(
} }
pIdx->nSampleCol = nIdxCol; pIdx->nSampleCol = nIdxCol;
pIdx->mxSample = nSample; pIdx->mxSample = nSample;
nByte = sizeof(IndexSample) * nSample; nByte = ROUND8(sizeof(IndexSample) * nSample);
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
@@ -1831,7 +1832,9 @@ static int loadStatTbl(
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
return SQLITE_NOMEM_BKPT; return SQLITE_NOMEM_BKPT;
} }
pSpace = (tRowcnt*)&pIdx->aSample[nSample]; pPtr = (u8*)pIdx->aSample;
pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0]));
pSpace = (tRowcnt*)pPtr;
assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); assert( EIGHT_BYTE_ALIGNMENT( pSpace ) );
pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
pIdx->pTable->tabFlags |= TF_HasStat4; pIdx->pTable->tabFlags |= TF_HasStat4;

View File

@@ -717,6 +717,7 @@ Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
pRet->pSrc->nSrc = 1; pRet->pSrc->nSrc = 1;
pRet->pPrior = pLeft->pPrior; pRet->pPrior = pLeft->pPrior;
pRet->op = pLeft->op; pRet->op = pLeft->op;
if( pRet->pPrior ) pRet->selFlags |= SF_Values;
pLeft->pPrior = 0; pLeft->pPrior = 0;
pLeft->op = TK_SELECT; pLeft->op = TK_SELECT;
assert( pLeft->pNext==0 ); assert( pLeft->pNext==0 );

View File

@@ -532,9 +532,9 @@ cmd ::= select(X). {
break; break;
} }
} }
if( (p->selFlags & SF_MultiValue)==0 && if( (p->selFlags & (SF_MultiValue|SF_Values))==0
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
cnt>mxSelect && cnt>mxSelect
){ ){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
} }

View File

@@ -2154,6 +2154,9 @@ int sqlite3ResolveExprNames(
** Resolve all names for all expression in an expression list. This is ** Resolve all names for all expression in an expression list. This is
** just like sqlite3ResolveExprNames() except that it works for an expression ** just like sqlite3ResolveExprNames() except that it works for an expression
** list rather than a single expression. ** list rather than a single expression.
**
** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a
** failure.
*/ */
int sqlite3ResolveExprListNames( int sqlite3ResolveExprListNames(
NameContext *pNC, /* Namespace to resolve expressions in. */ NameContext *pNC, /* Namespace to resolve expressions in. */
@@ -2162,7 +2165,7 @@ int sqlite3ResolveExprListNames(
int i; int i;
int savedHasAgg = 0; int savedHasAgg = 0;
Walker w; Walker w;
if( pList==0 ) return WRC_Continue; if( pList==0 ) return SQLITE_OK;
w.pParse = pNC->pParse; w.pParse = pNC->pParse;
w.xExprCallback = resolveExprStep; w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep; w.xSelectCallback = resolveSelectStep;
@@ -2176,7 +2179,7 @@ int sqlite3ResolveExprListNames(
#if SQLITE_MAX_EXPR_DEPTH>0 #if SQLITE_MAX_EXPR_DEPTH>0
w.pParse->nHeight += pExpr->nHeight; w.pParse->nHeight += pExpr->nHeight;
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
return WRC_Abort; return SQLITE_ERROR;
} }
#endif #endif
sqlite3WalkExprNN(&w, pExpr); sqlite3WalkExprNN(&w, pExpr);
@@ -2193,10 +2196,10 @@ int sqlite3ResolveExprListNames(
(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
} }
if( w.pParse->nErr>0 ) return WRC_Abort; if( w.pParse->nErr>0 ) return SQLITE_ERROR;
} }
pNC->ncFlags |= savedHasAgg; pNC->ncFlags |= savedHasAgg;
return WRC_Continue; return SQLITE_OK;
} }
/* /*

View File

@@ -3545,6 +3545,14 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
}else if( sqlite3_strlike("_INF", zVar, 0)==0 ){ }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){
sqlite3_bind_double(pStmt, i, INFINITY); sqlite3_bind_double(pStmt, i, INFINITY);
#endif #endif
}else if( strncmp(zVar, "$int_", 5)==0 ){
sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
}else if( strncmp(zVar, "$text_", 6)==0 ){
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
if( zBuf ){
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
sqlite3_bind_text64(pStmt, i, zBuf, -1, sqlite3_free, SQLITE_UTF8);
}
}else{ }else{
sqlite3_bind_null(pStmt, i); sqlite3_bind_null(pStmt, i);
} }
@@ -11640,7 +11648,10 @@ static int doAutoDetectRestore(ShellState *p, const char *zSql){
case 0: { case 0: {
const char *zExpect = "PRAGMA foreign_keys=OFF;"; const char *zExpect = "PRAGMA foreign_keys=OFF;";
assert( strlen(zExpect)==24 ); assert( strlen(zExpect)==24 );
if( p->bSafeMode==0 && memcmp(zSql, zExpect, 25)==0 ){ if( p->bSafeMode==0
&& strlen(zSql)>=24
&& memcmp(zSql, zExpect, 25)==0
){
p->eRestoreState = 1; p->eRestoreState = 1;
}else{ }else{
p->eRestoreState = 7; p->eRestoreState = 7;

View File

@@ -1927,6 +1927,7 @@ struct sqlite3 {
#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */
#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */
/* /*
@@ -2914,9 +2915,15 @@ struct AggInfo {
** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg.
** The assert()s that are part of this macro verify that constraint. ** The assert()s that are part of this macro verify that constraint.
*/ */
#ifndef NDEBUG
#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I))
#define AggInfoFuncReg(A,I) \ #define AggInfoFuncReg(A,I) \
(assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I))
#else
#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I))
#define AggInfoFuncReg(A,I) \
((A)->iFirstReg+(A)->nColumn+(I))
#endif
/* /*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** The datatype ynVar is a signed integer, either 16-bit or 32-bit.

View File

@@ -369,12 +369,19 @@ static int SQLITE_TCLAPI incrblobOutput(
return nWrite; return nWrite;
} }
/* The datatype of Tcl_DriverWideSeekProc changes between tcl8.6 and tcl9.0 */
#if TCL_MAJOR_VERSION==9
# define WideSeekProcType long long
#else
# define WideSeekProcType Tcl_WideInt
#endif
/* /*
** Seek an incremental blob channel. ** Seek an incremental blob channel.
*/ */
static long long SQLITE_TCLAPI incrblobWideSeek( static WideSeekProcType SQLITE_TCLAPI incrblobWideSeek(
ClientData instanceData, ClientData instanceData,
long long offset, WideSeekProcType offset,
int seekMode, int seekMode,
int *errorCodePtr int *errorCodePtr
){ ){

View File

@@ -8100,6 +8100,7 @@ static int SQLITE_TCLAPI optimization_control(
{ "distinct-opt", SQLITE_DistinctOpt }, { "distinct-opt", SQLITE_DistinctOpt },
{ "cover-idx-scan", SQLITE_CoverIdxScan }, { "cover-idx-scan", SQLITE_CoverIdxScan },
{ "order-by-idx-join", SQLITE_OrderByIdxJoin }, { "order-by-idx-join", SQLITE_OrderByIdxJoin },
{ "order-by-subquery", SQLITE_OrderBySubq },
{ "transitive", SQLITE_Transitive }, { "transitive", SQLITE_Transitive },
{ "omit-noop-join", SQLITE_OmitNoopJoin }, { "omit-noop-join", SQLITE_OmitNoopJoin },
{ "stat4", SQLITE_Stat4 }, { "stat4", SQLITE_Stat4 },
@@ -8324,7 +8325,7 @@ static int SQLITE_TCLAPI sorter_test_sort4_helper(
for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){ for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
int a = sqlite3_column_int(pStmt, 0); int a = sqlite3_column_int(pStmt, 0);
if( a!=sqlite3_column_int(pStmt, iB) ){ if( a!=sqlite3_column_int(pStmt, iB) ){
Tcl_AppendResult(interp, "data error: (a!=b)", 0); Tcl_AppendResult(interp, "data error: (a!=b)", (void*)0);
return TCL_ERROR; return TCL_ERROR;
} }
@@ -8343,13 +8344,13 @@ static int SQLITE_TCLAPI sorter_test_sort4_helper(
if( rc!=SQLITE_OK ) goto sql_error; if( rc!=SQLITE_OK ) goto sql_error;
if( iCksum1!=iCksum2 ){ if( iCksum1!=iCksum2 ){
Tcl_AppendResult(interp, "checksum mismatch", 0); Tcl_AppendResult(interp, "checksum mismatch", (void*)0);
return TCL_ERROR; return TCL_ERROR;
} }
return TCL_OK; return TCL_OK;
sql_error: sql_error:
Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0); Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), (void*)0);
return TCL_ERROR; return TCL_ERROR;
} }
@@ -8398,7 +8399,7 @@ static int SQLITE_TCLAPI test_user_add(
){ ){
char *zUser = 0; char *zUser = 0;
char *zPasswd = 0; char *zPasswd = 0;
int nPasswd = 0; Tcl_Size nPasswd = 0;
int isAdmin = 0; int isAdmin = 0;
sqlite3 *db; sqlite3 *db;
int rc; int rc;
@@ -8413,7 +8414,7 @@ static int SQLITE_TCLAPI test_user_add(
zUser = Tcl_GetString(objv[2]); zUser = Tcl_GetString(objv[2]);
zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin); rc = sqlite3_user_add(db, zUser, zPasswd, (int)nPasswd, isAdmin);
Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
return TCL_OK; return TCL_OK;
} }
@@ -8431,7 +8432,7 @@ static int SQLITE_TCLAPI test_user_change(
){ ){
char *zUser = 0; char *zUser = 0;
char *zPasswd = 0; char *zPasswd = 0;
int nPasswd = 0; Tcl_Size nPasswd = 0;
int isAdmin = 0; int isAdmin = 0;
sqlite3 *db; sqlite3 *db;
int rc; int rc;
@@ -8446,7 +8447,7 @@ static int SQLITE_TCLAPI test_user_change(
zUser = Tcl_GetString(objv[2]); zUser = Tcl_GetString(objv[2]);
zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin); rc = sqlite3_user_change(db, zUser, zPasswd, (int)nPasswd, isAdmin);
Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
return TCL_OK; return TCL_OK;
} }

View File

@@ -413,7 +413,7 @@ static int SQLITE_TCLAPI make_fts3record(
} }
for(i=0; i<(int)nArg; i++){ for(i=0; i<(int)nArg; i++){
sqlite3_int64 iVal; Tcl_WideInt iVal;
if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){ if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){
if( nOut+10>nAlloc ){ if( nOut+10>nAlloc ){
int nNew = nAlloc?nAlloc*2:128; int nNew = nAlloc?nAlloc*2:128;

View File

@@ -68,8 +68,8 @@ struct tclvar_cursor {
Tcl_Obj *pList1; /* Result of [info vars ?pattern?] */ Tcl_Obj *pList1; /* Result of [info vars ?pattern?] */
Tcl_Obj *pList2; /* Result of [array names [lindex $pList1 $i1]] */ Tcl_Obj *pList2; /* Result of [array names [lindex $pList1 $i1]] */
int i1; /* Current item in pList1 */ Tcl_Size i1; /* Current item in pList1 */
int i2; /* Current item (if any) in pList2 */ Tcl_Size i2; /* Current item (if any) in pList2 */
}; };
/* Methods for the tclvar module */ /* Methods for the tclvar module */
@@ -149,7 +149,7 @@ static int next2(Tcl_Interp *interp, tclvar_cursor *pCur, Tcl_Obj *pObj){
Tcl_Size n = 0; Tcl_Size n = 0;
pCur->i2++; pCur->i2++;
Tcl_ListObjLength(0, pCur->pList2, &n); Tcl_ListObjLength(0, pCur->pList2, &n);
if( pCur->i2>=(int)n ){ if( pCur->i2>=n ){
Tcl_DecrRefCount(pCur->pList2); Tcl_DecrRefCount(pCur->pList2);
pCur->pList2 = 0; pCur->pList2 = 0;
pCur->i2 = 0; pCur->i2 = 0;
@@ -170,7 +170,7 @@ static int tclvarNext(sqlite3_vtab_cursor *cur){
Tcl_Interp *interp = ((tclvar_vtab *)(cur->pVtab))->interp; Tcl_Interp *interp = ((tclvar_vtab *)(cur->pVtab))->interp;
Tcl_ListObjLength(0, pCur->pList1, &n); Tcl_ListObjLength(0, pCur->pList1, &n);
while( !ok && pCur->i1<(int)n ){ while( !ok && pCur->i1<n ){
Tcl_ListObjIndex(0, pCur->pList1, pCur->i1, &pObj); Tcl_ListObjIndex(0, pCur->pList1, pCur->i1, &pObj);
ok = next2(interp, pCur, pObj); ok = next2(interp, pCur, pObj);
if( !ok ){ if( !ok ){

View File

@@ -556,13 +556,14 @@ static int vdbePmaReadBlob(
while( nRem>0 ){ while( nRem>0 ){
int rc; /* vdbePmaReadBlob() return code */ int rc; /* vdbePmaReadBlob() return code */
int nCopy; /* Number of bytes to copy */ int nCopy; /* Number of bytes to copy */
u8 *aNext; /* Pointer to buffer to copy data from */ u8 *aNext = 0; /* Pointer to buffer to copy data from */
nCopy = nRem; nCopy = nRem;
if( nRem>p->nBuffer ) nCopy = p->nBuffer; if( nRem>p->nBuffer ) nCopy = p->nBuffer;
rc = vdbePmaReadBlob(p, nCopy, &aNext); rc = vdbePmaReadBlob(p, nCopy, &aNext);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
assert( aNext!=p->aAlloc ); assert( aNext!=p->aAlloc );
assert( aNext!=0 );
memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
nRem -= nCopy; nRem -= nCopy;
} }

View File

@@ -1501,6 +1501,19 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aConstraint = pIdxCons;
pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aOrderBy = pIdxOrderBy;
pIdxInfo->aConstraintUsage = pUsage; pIdxInfo->aConstraintUsage = pUsage;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
if( HasRowid(pTab)==0 ){
/* Ensure that all bits associated with PK columns are set. This is to
** ensure they are available for cases like RIGHT joins or OR loops. */
Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab);
assert( pPk!=0 );
for(i=0; i<pPk->nKeyCol; i++){
int iCol = pPk->aiColumn[i];
assert( iCol>=0 );
if( iCol>=BMS-1 ) iCol = BMS-1;
pIdxInfo->colUsed |= MASKBIT(iCol);
}
}
pHidden->pWC = pWC; pHidden->pWC = pWC;
pHidden->pParse = pParse; pHidden->pParse = pParse;
pHidden->eDistinct = eDistinct; pHidden->eDistinct = eDistinct;
@@ -3997,6 +4010,10 @@ static int whereLoopAddBtree(
#endif #endif
ApplyCostMultiplier(pNew->rRun, pTab->costMult); ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew, rSize); whereLoopOutputAdjust(pWC, pNew, rSize);
if( pSrc->pSelect ){
if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE;
pNew->u.btree.pOrderBy = pSrc->pSelect->pOrderBy;
}
rc = whereLoopInsert(pBuilder, pNew); rc = whereLoopInsert(pBuilder, pNew);
pNew->nOut = rSize; pNew->nOut = rSize;
if( rc ) break; if( rc ) break;
@@ -4034,7 +4051,9 @@ static int whereLoopAddBtree(
" according to whereIsCoveringIndex()\n", pProbe->zName)); " according to whereIsCoveringIndex()\n", pProbe->zName));
} }
} }
}else if( m==0 ){ }else if( m==0
&& (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
){
WHERETRACE(0x200, WHERETRACE(0x200,
("-> %s a covering index according to bitmasks\n", ("-> %s a covering index according to bitmasks\n",
pProbe->zName, m==0 ? "is" : "is not")); pProbe->zName, m==0 ? "is" : "is not"));
@@ -4216,7 +4235,6 @@ static int whereLoopAddVirtualOne(
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25; pIdxInfo->estimatedRows = 25;
pIdxInfo->idxFlags = 0; pIdxInfo->idxFlags = 0;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
pHidden->mHandleIn = 0; pHidden->mHandleIn = 0;
/* Invoke the virtual table xBestIndex() method */ /* Invoke the virtual table xBestIndex() method */
@@ -4829,6 +4847,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
return rc; return rc;
} }
/* Implementation of the order-by-subquery optimization:
**
** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really
** a subquery or CTE that has an ORDER BY clause. See if any of the terms
** in the subquery ORDER BY clause will satisfy pOrderBy from the outer
** query. Mark off all satisfied terms (by setting bits in *pOBSat) and
** return TRUE if they do. If not, return false.
**
** Example:
**
** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b));
** CREATE TABLE t2(x,y);
** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y)
** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b;
**
** The CTE named "t3" comes out in the natural order of "p", so the first
** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3"
** and sorting only needs to occur on the second term "b".
**
** Limitations:
**
** (1) The optimization is not applied if the outer ORDER BY contains
** a COLLATE clause. The optimization might be applied if the
** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as
** long as the subquery ORDER BY does the same. But if the
** outer ORDER BY uses COLLATE, even a redundant COLLATE, the
** optimization is bypassed.
**
** (2) The subquery ORDER BY terms must exactly match subquery result
** columns, including any COLLATE annotations. This routine relies
** on iOrderByCol to do matching between order by terms and result
** columns, and iOrderByCol will not be set if the result column
** and ORDER BY collations differ.
**
** (3) The subquery and outer ORDER BY can be in opposite directions as
** long as the subquery is materialized. If the subquery is
** implemented as a co-routine, the sort orders must be in the same
** direction because there is no way to run a co-routine backwards.
*/
static SQLITE_NOINLINE int wherePathMatchSubqueryOB(
WhereInfo *pWInfo, /* The WHERE clause */
WhereLoop *pLoop, /* The nested loop term that is a subquery */
int iLoop, /* Which level of the nested loop. 0==outermost */
int iCur, /* Cursor used by the this loop */
ExprList *pOrderBy, /* The ORDER BY clause on the whole query */
Bitmask *pRevMask, /* When loops need to go in reverse order */
Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */
){
int iOB; /* Index into pOrderBy->a[] */
int jSub; /* Index into pSubOB->a[] */
u8 rev = 0; /* True if iOB and jSub sort in opposite directions */
u8 revIdx = 0; /* Sort direction for jSub */
Expr *pOBExpr; /* Current term of outer ORDER BY */
ExprList *pSubOB; /* Complete ORDER BY on the subquery */
pSubOB = pLoop->u.btree.pOrderBy;
assert( pSubOB!=0 );
for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){}
for(jSub=0; jSub<pSubOB->nExpr && iOB<pOrderBy->nExpr; jSub++, iOB++){
if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break;
pOBExpr = pOrderBy->a[iOB].pExpr;
if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break;
if( pOBExpr->iTable!=iCur ) break;
if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break;
if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */
u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */
if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){
break;
}
revIdx = sfSub & KEYINFO_ORDER_DESC;
if( jSub>0 ){
if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){
break;
}
}else{
rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC);
if( rev ){
if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){
/* Cannot run a co-routine in reverse order */
break;
}
*pRevMask |= MASKBIT(iLoop);
}
}
}
*pOBSat |= MASKBIT(iOB);
}
return jSub>0;
}
/* /*
** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
** parameters) to see if it outputs rows in the requested ORDER BY ** parameters) to see if it outputs rows in the requested ORDER BY
@@ -4974,9 +5083,18 @@ static i8 wherePathSatisfiesOrderBy(
if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
if( pLoop->wsFlags & WHERE_IPK ){ if( pLoop->wsFlags & WHERE_IPK ){
if( pLoop->u.btree.pOrderBy
&& OptimizationEnabled(db, SQLITE_OrderBySubq)
&& wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur,
pOrderBy,pRevMask, &obSat)
){
nColumn = 0;
isOrderDistinct = 0;
}else{
nColumn = 1;
}
pIndex = 0; pIndex = 0;
nKeyCol = 0; nKeyCol = 0;
nColumn = 1;
}else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
return 0; return 0;
}else{ }else{
@@ -5071,7 +5189,7 @@ static i8 wherePathSatisfiesOrderBy(
} }
/* Find the ORDER BY term that corresponds to the j-th column /* Find the ORDER BY term that corresponds to the j-th column
** of the index and mark that ORDER BY term off ** of the index and mark that ORDER BY term having been satisfied.
*/ */
isMatch = 0; isMatch = 0;
for(i=0; bOnce && i<nOrderBy; i++){ for(i=0; bOnce && i<nOrderBy; i++){
@@ -7066,26 +7184,6 @@ whereBeginError:
} }
#endif #endif
#ifdef SQLITE_DEBUG
/*
** Return true if cursor iCur is opened by instruction k of the
** bytecode. Used inside of assert() only.
*/
static int cursorIsOpen(Vdbe *v, int iCur, int k){
while( k>=0 ){
VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
if( pOp->p1!=iCur ) continue;
if( pOp->opcode==OP_Close ) return 0;
if( pOp->opcode==OP_OpenRead ) return 1;
if( pOp->opcode==OP_OpenWrite ) return 1;
if( pOp->opcode==OP_OpenDup ) return 1;
if( pOp->opcode==OP_OpenAutoindex ) return 1;
if( pOp->opcode==OP_OpenEphemeral ) return 1;
}
return 0;
}
#endif /* SQLITE_DEBUG */
/* /*
** Generate the end of the WHERE loop. See comments on ** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information. ** sqlite3WhereBegin() for additional information.
@@ -7385,16 +7483,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
** reference. Verify that this is harmless - that the ** reference. Verify that this is harmless - that the
** table being referenced really is open. ** table being referenced really is open.
*/ */
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC if( pLoop->wsFlags & WHERE_IDX_ONLY ){
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 sqlite3ErrorMsg(pParse, "internal query planner error");
|| cursorIsOpen(v,pOp->p1,k) pParse->rc = SQLITE_INTERNAL;
|| pOp->opcode==OP_Offset }
);
#else
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|| cursorIsOpen(v,pOp->p1,k)
);
#endif
} }
}else if( pOp->opcode==OP_Rowid ){ }else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur; pOp->p1 = pLevel->iIdxCur;

View File

@@ -143,6 +143,7 @@ struct WhereLoop {
u16 nTop; /* Size of TOP vector */ u16 nTop; /* Size of TOP vector */
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
Index *pIndex; /* Index used, or NULL */ Index *pIndex; /* Index used, or NULL */
ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */
} btree; } btree;
struct { /* Information for virtual tables */ struct { /* Information for virtual tables */
int idxNum; /* Index number */ int idxNum; /* Index number */
@@ -636,7 +637,8 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
/* 0x02000000 -- available for reuse */ #define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine.
** NB: False-negatives are possible */
#define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */
#endif /* !defined(SQLITE_WHEREINT_H) */ #endif /* !defined(SQLITE_WHEREINT_H) */

93
test/bestindexD.test Normal file
View File

@@ -0,0 +1,93 @@
# 2024-08-03
#
# 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.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindexD
ifcapable !vtab {
finish_test
return
}
register_tcl_module db
proc vtab_command {method args} {
switch -- $method {
xConnect {
return "CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID"
}
xBestIndex {
set hdl [lindex $args 0]
set ::colUsed [$hdl mask]
set cost 1000000
set used ""
set cons 0
foreach c [$hdl constraints] {
set cost [expr $cost/10]
append used " use $cons"
incr cons
}
return "cost $cost rows $cost $used"
}
}
return {}
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
CREATE TABLE t2(a, b);
} {}
# This proc assumes that there is only one use of a virtual table - x1 -
# in SQL statement $sql. It tests that the colUsed value passed to the
# xBestIndex method matches the actual columns used, which is ascertained
# by searching the compiled VM code for VColumn instructions.
#
proc do_colsused_test {tn sql} {
set ::colUsed ""
execsql $sql
set got $::colUsed
set expect 0
db eval "EXPLAIN $sql" x {
if {$x(opcode)=="VColumn"} {
set expect [expr $expect | (1<<$x(p2))]
}
}
uplevel [list do_test $tn.($expect/$got) [list expr ($expect & $got)] $expect]
}
do_colsused_test 1.1 { SELECT a FROM x1 }
do_colsused_test 1.2 { SELECT a,c FROM x1 }
do_colsused_test 1.3 { SELECT b FROM x1 }
do_colsused_test 1.4 { SELECT b FROM x1 WHERE c=? }
do_colsused_test 1.5 {
select 1 from t2 full join x1;
}
do_colsused_test 1.6 {
select 1 from x1 WHERE (b=? AND c=?) OR (b=? AND c=?)
}
finish_test

View File

@@ -288,6 +288,7 @@ det 3.2.1 {
|--SCAN (subquery-xxxxxx) |--SCAN (subquery-xxxxxx)
`--USE TEMP B-TREE FOR ORDER BY `--USE TEMP B-TREE FOR ORDER BY
} }
det 3.2.2 { det 3.2.2 {
SELECT * FROM SELECT * FROM
(SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1, (SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1,
@@ -305,6 +306,16 @@ det 3.2.2 {
`--USE TEMP B-TREE FOR ORDER BY `--USE TEMP B-TREE FOR ORDER BY
} }
det 3.2.3 {
SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY x LIMIT 5
} {
QUERY PLAN
|--CO-ROUTINE (subquery-xxxxxx)
| |--SCAN t1
| `--USE TEMP B-TREE FOR ORDER BY
`--SCAN (subquery-xxxxxx)
}
det 3.3.1 { det 3.3.1 {
SELECT * FROM t1 WHERE y IN (SELECT y FROM t2) SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
} { } {
@@ -807,6 +818,7 @@ do_execsql_test 9.0 {
CREATE INDEX event_i1 ON event(mtime); CREATE INDEX event_i1 ON event(mtime);
CREATE TABLE private(rid INTEGER PRIMARY KEY); CREATE TABLE private(rid INTEGER PRIMARY KEY);
} }
optimization_control db order-by-subquery off
do_eqp_test 9.1 { do_eqp_test 9.1 {
WITH thread(age,duration,cnt,root,last) AS ( WITH thread(age,duration,cnt,root,last) AS (
SELECT SELECT
@@ -847,5 +859,46 @@ do_eqp_test 9.1 {
|--SEARCH event USING INTEGER PRIMARY KEY (rowid=?) |--SEARCH event USING INTEGER PRIMARY KEY (rowid=?)
`--USE TEMP B-TREE FOR ORDER BY `--USE TEMP B-TREE FOR ORDER BY
} }
optimization_control db all on
db cache flush
do_eqp_test 9.2 {
WITH thread(age,duration,cnt,root,last) AS (
SELECT
julianday('now') - max(fmtime) AS age,
max(fmtime) - min(fmtime) AS duration,
sum(fprev IS NULL) AS msg_count,
froot,
(SELECT fpid FROM forumpost
WHERE froot=x.froot
AND fpid NOT IN private
ORDER BY fmtime DESC LIMIT 1)
FROM forumpost AS x
WHERE fpid NOT IN private --- Ensure this table mentioned in EQP output!
GROUP BY froot
ORDER BY 1 LIMIT 26 OFFSET 5
)
SELECT
thread.age,
thread.duration,
thread.cnt,
blob.uuid,
substr(event.comment,instr(event.comment,':')+1)
FROM thread, blob, event
WHERE blob.rid=thread.last
AND event.objid=thread.last
ORDER BY 1;
} {
QUERY PLAN
|--CO-ROUTINE thread
| |--SCAN x USING INDEX forumthread
| |--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
| |--CORRELATED SCALAR SUBQUERY xxxxxx
| | |--SEARCH forumpost USING COVERING INDEX forumthread (froot=?)
| | `--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
| `--USE TEMP B-TREE FOR ORDER BY
|--SCAN thread
|--SEARCH blob USING INTEGER PRIMARY KEY (rowid=?)
`--SEARCH event USING INTEGER PRIMARY KEY (rowid=?)
}
finish_test finish_test

View File

@@ -561,7 +561,6 @@ do_test 4.3 {
}] }]
} {64} } {64}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases. # Request a snippet from a query with more than 64 phrases.
# #
@@ -588,5 +587,9 @@ do_execsql_test 5.1 {
{[a70] [a71] [a72]} {[a70] [a71] [a72]}
} }
do_execsql_test 5.2 {
SELECT snippet(t5, '[', ']', -1, 0) FROM t5 WHERE t5 MATCH 'a5'
} {{a4 [a5] a6}}
set sqlite_fts3_enable_parentheses 0 set sqlite_fts3_enable_parentheses 0
finish_test finish_test

View File

@@ -1028,6 +1028,30 @@ static int recoverDatabase(sqlite3 *db){
} }
return rc; return rc;
} }
/*
** Special parameter binding, for testing and debugging purposes.
**
** $int_NNN -> integer value NNN
** $text_TTTT -> floating point value TTT with destructor
*/
static void bindDebugParameters(sqlite3_stmt *pStmt){
int nVar = sqlite3_bind_parameter_count(pStmt);
int i;
for(i=0; i<nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i+1);
if( zVar==0 ) continue;
if( strncmp(zVar, "$int_", 5)==0 ){
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
}else
if( strncmp(zVar, "$text_", 6)==0 ){
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
if( zBuf ){
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
}
}
}
}
/* /*
** Run the SQL text ** Run the SQL text
@@ -1051,6 +1075,7 @@ static int runDbSql(
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
int nRow = 0; int nRow = 0;
bindDebugParameters(pStmt);
while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){ while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ){
nRow++; nRow++;
if( eVerbosity>=4 ){ if( eVerbosity>=4 ){

View File

@@ -38,6 +38,31 @@ static void reportInvariantFailed(
int noOpt /* True if opt flags inverted for pTest */ int noOpt /* True if opt flags inverted for pTest */
); );
/*
** Special parameter binding, for testing and debugging purposes.
**
** $int_NNN -> integer value NNN
** $text_TTTT -> floating point value TTT with destructor
*/
static void bindDebugParameters(sqlite3_stmt *pStmt){
int nVar = sqlite3_bind_parameter_count(pStmt);
int i;
for(i=0; i<nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i+1);
if( zVar==0 ) continue;
if( strncmp(zVar, "$int_", 5)==0 ){
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
}else
if( strncmp(zVar, "$text_", 6)==0 ){
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
if( zBuf ){
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
}
}
}
}
/* /*
** Do an invariant check on pStmt. iCnt determines which invariant check to ** Do an invariant check on pStmt. iCnt determines which invariant check to
** perform. The first check is iCnt==0. ** perform. The first check is iCnt==0.
@@ -107,6 +132,7 @@ int fuzz_invariant(
return rc; return rc;
} }
sqlite3_free(zTest); sqlite3_free(zTest);
bindDebugParameters(pTestStmt);
nCol = sqlite3_column_count(pStmt); nCol = sqlite3_column_count(pStmt);
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
rc = sqlite3_bind_value(pTestStmt,i+1+nParam,sqlite3_column_value(pStmt,i)); rc = sqlite3_bind_value(pTestStmt,i+1+nParam,sqlite3_column_value(pStmt,i));
@@ -171,6 +197,7 @@ int fuzz_invariant(
printf("invariant-validity-check #2:\n%s\n", zSql); printf("invariant-validity-check #2:\n%s\n", zSql);
sqlite3_free(zSql); sqlite3_free(zSql);
} }
bindDebugParameters(pCk);
while( (rc = sqlite3_step(pCk))==SQLITE_ROW ){ while( (rc = sqlite3_step(pCk))==SQLITE_ROW ){
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
if( !sameValue(pStmt, i, pTestStmt, i, 0) ) break; if( !sameValue(pStmt, i, pTestStmt, i, 0) ) break;
@@ -199,6 +226,7 @@ int fuzz_invariant(
} }
sqlite3_reset(pTestStmt); sqlite3_reset(pTestStmt);
bindDebugParameters(pCk);
while( (rc = sqlite3_step(pTestStmt))==SQLITE_ROW ){ while( (rc = sqlite3_step(pTestStmt))==SQLITE_ROW ){
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
if( !sameValue(pStmt, i, pTestStmt, i, pCk) ) break; if( !sameValue(pStmt, i, pTestStmt, i, pCk) ) break;
@@ -298,6 +326,7 @@ static char *fuzz_invariant_sql(sqlite3_stmt *pStmt, int iCnt){
sqlite3_finalize(pBase); sqlite3_finalize(pBase);
pBase = pStmt; pBase = pStmt;
} }
bindDebugParameters(pBase);
for(i=0; i<sqlite3_column_count(pStmt); i++){ for(i=0; i<sqlite3_column_count(pStmt); i++){
const char *zColName = sqlite3_column_name(pBase,i); const char *zColName = sqlite3_column_name(pBase,i);
const char *zSuffix = zColName ? strrchr(zColName, ':') : 0; const char *zSuffix = zColName ? strrchr(zColName, ':') : 0;

94
test/orderbyB.test Normal file
View File

@@ -0,0 +1,94 @@
# 2024-08-15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# Specifically, it tests cases with order-by-subquery optimization in which
# an ORDER BY in a subquery is used to help resolve an ORDER BY in the
# outer query without having to do an extra sort.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderbyb
db null NULL
do_execsql_test 1.0 {
CREATE TABLE t1(a TEXT, b TEXT, c INT);
INSERT INTO t1 VALUES(NULL,NULL,NULL);
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<7)
INSERT INTO t1(a,b,c) SELECT char(p,p), char(q,q), n FROM
(SELECT ((n-1)%4)+0x61 AS p, abs(n*2-9+(n>=5))+0x60 AS q, n FROM c);
UPDATE t1 SET b=upper(b) WHERE c=1;
CREATE TABLE t2(k TEXT PRIMARY KEY, v INT) WITHOUT ROWID;
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<7)
INSERT INTO t2(k,v) SELECT char(0x60+n,0x60+n), n FROM c;
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<7)
INSERT INTO t2(k,v) SELECT char(0x40+n,0x40+n), n FROM c;
SELECT a,b,c,tx.v AS 'v-a', ty.v AS 'v-b'
FROM t1 LEFT JOIN t2 AS tx ON tx.k=a
LEFT JOIN t2 AS ty ON ty.k=b
ORDER BY c;
} {
NULL NULL NULL NULL NULL
aa GG 1 1 7
bb ee 2 2 5
cc cc 3 3 3
dd aa 4 4 1
aa bb 5 1 2
bb dd 6 2 4
cc ff 7 3 6
}
do_eqp_execsql_test 1.1 {
WITH t3(x,y) AS (SELECT a, b FROM t1 ORDER BY a, b LIMIT 8)
SELECT x, y, v FROM t3 LEFT JOIN t2 ON k=t3.y ORDER BY x, y COLLATE nocase;
} {
QUERY PLAN
|--CO-ROUTINE t3
| |--SCAN t1
| `--USE TEMP B-TREE FOR ORDER BY
|--SCAN t3
|--SEARCH t2 USING PRIMARY KEY (k=?) LEFT-JOIN
`--USE TEMP B-TREE FOR LAST TERM OF ORDER BY
} {
NULL NULL NULL
aa bb 2
aa GG 7
bb dd 4
bb ee 5
cc cc 3
cc ff 6
dd aa 1
}
do_eqp_execsql_test 1.2 {
WITH t3(x,y) AS MATERIALIZED (SELECT a, b COLLATE nocase FROM t1 ORDER BY 1,2)
SELECT x, y, v FROM t3 LEFT JOIN t2 ON k=t3.y ORDER BY x,y;
} {
QUERY PLAN
|--MATERIALIZE t3
| |--SCAN t1
| `--USE TEMP B-TREE FOR ORDER BY
|--SCAN t3
`--SEARCH t2 USING PRIMARY KEY (k=?) LEFT-JOIN
} {
NULL NULL NULL
aa bb 2
aa GG 7
bb dd 4
bb ee 5
cc cc 3
cc ff 6
dd aa 1
}
finish_test

View File

@@ -155,6 +155,38 @@ if {[clang_sanitize_address]==0} {
} }
} }
# https://issues.chromium.org/issues/358174302
# Need to support an unlimited number of terms in a VALUES clause, even
# if some of those terms contain double-quoted string literals.
#
do_execsql_test select7-6.5 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a,b,c);
}
sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 10
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 0
do_catchsql_test select7-6.6 {
INSERT INTO t1 VALUES
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
(0,NULL,0), (X'',X'',0.0);
} {1 {no such column: "" - should this be a string literal in single-quotes?}}
do_execsql_test select7-6.7 {
SELECT count(*) FROM t1;
} {0}
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
do_catchsql_test select7-6.8 {
INSERT INTO t1 VALUES
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
(0,NULL,0), (X'',X'',0.0);
} {0 {}}
do_execsql_test select7-6.9 {
SELECT count(*) FROM t1;
} {16}
# This block of tests verifies that bug aa92c76cd4 is fixed. # This block of tests verifies that bug aa92c76cd4 is fixed.
# #
do_test select7-7.1 { do_test select7-7.1 {

View File

@@ -337,12 +337,12 @@ do_execsql_test skipscan1-9.2 {
} {/USING INDEX t9a_ab .ANY.a. AND b=./} } {/USING INDEX t9a_ab .ANY.a. AND b=./}
optimization_control db skip-scan 0 optimization_control db skip-scan off
do_execsql_test skipscan1-9.3 { do_execsql_test skipscan1-9.3 {
EXPLAIN QUERY PLAN EXPLAIN QUERY PLAN
SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5); SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5);
} {/{SCAN t9a}/} } {/{SCAN t9a}/}
optimization_control db skip-scan 1 optimization_control db all on
do_execsql_test skipscan1-2.1 { do_execsql_test skipscan1-2.1 {
CREATE TABLE t6(a TEXT, b INT, c INT, d INT); CREATE TABLE t6(a TEXT, b INT, c INT, d INT);

View File

@@ -1057,6 +1057,29 @@ proc do_eqp_test {name sql res} {
} }
} }
# Do both an eqp_test and an execsql_test on the same SQL.
#
proc do_eqp_execsql_test {name sql res1 res2} {
if {[regexp {^\s+QUERY PLAN\n} $res1]} {
set query_plan [query_plan_graph $sql]
if {[list {*}$query_plan]==[list {*}$res1]} {
uplevel [list do_test ${name}a [list set {} ok] ok]
} else {
uplevel [list \
do_test ${name}a [list query_plan_graph $sql] $res1
]
}
} else {
if {[string index $res 0]!="/"} {
set res1 "/*$res1*/"
}
uplevel do_execsql_test ${name}a [list "EXPLAIN QUERY PLAN $sql"] [list $res1]
}
uplevel do_execsql_test ${name}b [list $sql] [list $res2]
}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Usage: do_select_tests PREFIX ?SWITCHES? TESTLIST # Usage: do_select_tests PREFIX ?SWITCHES? TESTLIST

View File

@@ -54,10 +54,11 @@ proc usage {} {
Usage: Usage:
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS? $a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
$a0 PERMUTATION FILE $a0 PERMUTATION FILE
$a0 errors ?-v|--verbose?
$a0 help $a0 help
$a0 njob ?NJOB? $a0 njob ?NJOB?
$a0 script ?-msvc? CONFIG $a0 script ?-msvc? CONFIG
$a0 status $a0 status ?-d SECS? ?--cls?
where SWITCHES are: where SWITCHES are:
--buildonly Build test exes but do not run tests --buildonly Build test exes but do not run tests
@@ -66,6 +67,7 @@ Usage:
--explain Write summary to stdout --explain Write summary to stdout
--jobs NUM Run tests using NUM separate processes --jobs NUM Run tests using NUM separate processes
--omit CONFIGS Omit configs on comma-separated list CONFIGS --omit CONFIGS Omit configs on comma-separated list CONFIGS
--status Show the full "status" report while running
--stop-on-coredump Stop running if any test segfaults --stop-on-coredump Stop running if any test segfaults
--stop-on-error Stop running after any reported error --stop-on-error Stop running after any reported error
--zipvfs ZIPVFSDIR ZIPVFS source directory --zipvfs ZIPVFSDIR ZIPVFS source directory
@@ -100,13 +102,19 @@ with the specified permutation.
The "status" and "njob" commands are designed to be run from the same The "status" and "njob" commands are designed to be run from the same
directory as a running testrunner.tcl script that is running tests. The directory as a running testrunner.tcl script that is running tests. The
"status" command prints a report describing the current state and progress "status" command prints a report describing the current state and progress
of the tests. The "njob" command may be used to query or modify the number of the tests. Use the "-d N" option to have the status display clear the
of sub-processes the test script uses to run tests. screen and repeat every N seconds. The "njob" command may be used to query
or modify the number of sub-processes the test script uses to run tests.
The "script" command outputs the script used to build a configuration. The "script" command outputs the script used to build a configuration.
Add the "-msvc" option for a Windows-compatible script. For a list of Add the "-msvc" option for a Windows-compatible script. For a list of
available configurations enter "$a0 script help". available configurations enter "$a0 script help".
The "errors" commands shows the output of all tests that failed in the
most recent run. Complete output is shown if the -v or --verbose options
are used. Otherwise, an attempt is made to minimize the output to show
only the parts that contain the error messages.
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
}]] }]]
@@ -180,6 +188,7 @@ set TRG(dryrun) 0 ;# True if --dryrun option
set TRG(explain) 0 ;# True for the --explain option set TRG(explain) 0 ;# True for the --explain option
set TRG(stopOnError) 0 ;# Stop running at first failure set TRG(stopOnError) 0 ;# Stop running at first failure
set TRG(stopOnCore) 0 ;# Stop on a core-dump set TRG(stopOnCore) 0 ;# Stop on a core-dump
set TRG(fullstatus) 0 ;# Full "status" report while running
switch -nocase -glob -- $tcl_platform(os) { switch -nocase -glob -- $tcl_platform(os) {
*darwin* { *darwin* {
@@ -380,33 +389,35 @@ if {[string compare -nocase script [lindex $argv 0]]==0} {
exit exit
} }
# Helper routine for show_status
#--------------------------------------------------------------------------
# Check if this is the "status" command:
# #
if {[llength $argv]==1 proc display_job {jobdict {tm ""}} {
&& [string compare -nocase status [lindex $argv 0]]==0 array set job $jobdict
} { set dfname [format %-60s $job(displayname)]
set dtm ""
proc display_job {jobdict {tm ""}} { if {$tm!=""} {
array set job $jobdict set dtm [format %-10s "\[[expr {$tm-$job(starttime)}]ms\]"]
set dfname [format %-60s $job(displayname)]
set dtm ""
if {$tm!=""} { set dtm "\[[expr {$tm-$job(starttime)}]ms\]" }
puts " $dfname $dtm"
} }
puts " $dfname $dtm"
}
sqlite3 mydb $TRG(dbname) # This procedure shows the "status" page. It uses the database
mydb timeout 2000 # connect passed in as the "db" parameter. If the "cls" parameter
mydb eval BEGIN # is true, then VT100 escape codes are used to format the display.
#
set cmdline [mydb one { SELECT value FROM config WHERE name='cmdline' }] proc show_status {db cls} {
set nJob [mydb one { SELECT value FROM config WHERE name='njob' }] global TRG
$db eval BEGIN
if {[catch {
set cmdline [$db one { SELECT value FROM config WHERE name='cmdline' }]
set nJob [$db one { SELECT value FROM config WHERE name='njob' }]
} msg]} {
if {$cls} {puts "\033\[H\033\[2J"}
puts "Cannot read database: $TRG(dbname)"
return
}
set now [clock_milliseconds] set now [clock_milliseconds]
set tm [mydb one { set tm [$db one {
SELECT SELECT
COALESCE((SELECT value FROM config WHERE name='end'), $now) - COALESCE((SELECT value FROM config WHERE name='end'), $now) -
(SELECT value FROM config WHERE name='start') (SELECT value FROM config WHERE name='start')
@@ -414,7 +425,7 @@ if {[llength $argv]==1
set total 0 set total 0
foreach s {"" ready running done failed} { set S($s) 0 } foreach s {"" ready running done failed} { set S($s) 0 }
mydb eval { $db eval {
SELECT state, count(*) AS cnt FROM jobs GROUP BY 1 SELECT state, count(*) AS cnt FROM jobs GROUP BY 1
} { } {
incr S($state) $cnt incr S($state) $cnt
@@ -423,18 +434,28 @@ if {[llength $argv]==1
set fin [expr $S(done)+$S(failed)] set fin [expr $S(done)+$S(failed)]
if {$cmdline!=""} {set cmdline " $cmdline"} if {$cmdline!=""} {set cmdline " $cmdline"}
if {$cls} {
# Move the cursor to the top-left corner. Each iteration will simply
# overwrite.
puts -nonewline "\033\[H"
flush stdout
set clreol "\033\[K"
} else {
set clreol ""
}
set f "" set f ""
if {$S(failed)>0} { if {$S(failed)>0} {
set f "$S(failed) FAILED, " set f "$S(failed) FAILED, "
} }
puts "Command line: \[testrunner.tcl$cmdline\]" puts "Command line: \[testrunner.tcl$cmdline\]$clreol"
puts "Jobs: $nJob" puts "Jobs: $nJob "
puts "Summary: ${tm}ms, ($fin/$total) finished, ${f}$S(running) running" puts "Summary: ${tm}ms, ($fin/$total) finished,\
${f}$S(running) running "
set srcdir [file dirname [file dirname $TRG(info_script)]] set srcdir [file dirname [file dirname $TRG(info_script)]]
if {$S(running)>0} { if {$S(running)>0} {
puts "Running: " puts "Running: "
mydb eval { $db eval {
SELECT * FROM jobs WHERE state='running' ORDER BY starttime SELECT * FROM jobs WHERE state='running' ORDER BY starttime
} job { } job {
display_job [array get job] $now display_job [array get job] $now
@@ -442,21 +463,137 @@ if {[llength $argv]==1
} }
if {$S(failed)>0} { if {$S(failed)>0} {
puts "Failures: " puts "Failures: "
mydb eval { $db eval {
SELECT * FROM jobs WHERE state='failed' ORDER BY starttime SELECT * FROM jobs WHERE state='failed' ORDER BY starttime
} job { } job {
display_job [array get job] display_job [array get job]
} }
set nOmit [mydb one {SELECT count(*) FROM jobs WHERE state='omit'}] set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
if {$nOmit} { if {$nOmit} {
puts "$nOmit jobs omitted due to failures" puts "$nOmit jobs omitted due to failures$clreol"
}
}
if {$cls} {
# Clear everything else to the bottom of the screen
puts -nonewline "\033\[0J"
flush stdout
}
$db eval COMMIT
}
#--------------------------------------------------------------------------
# Check if this is the "status" command:
#
if {[llength $argv]>=1
&& [string compare -nocase status [lindex $argv 0]]==0
} {
set delay 0
set cls 0
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="-d" && $ii+1<[llength $argv]} {
incr ii
set delay [lindex $argv $ii]
if {![string is integer -strict $delay]} {
puts "Argument to -d should be an integer"
exit 1
}
} elseif {$a0=="-cls" || $a0=="--cls"} {
set cls 1
} else {
puts "unknown option: \"$a0\""
exit 1
} }
} }
if {![file readable $TRG(dbname)]} {
puts "Database missing: $TRG(dbname)"
exit
}
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
# Clear the whole screen initially.
#
if {$delay>0 || $cls} {puts -nonewline "\033\[2J"}
while {1} {
show_status mydb [expr {$delay>0 || $cls}]
if {$delay<=0} break
after [expr {$delay*1000}]
}
mydb close mydb close
exit exit
} }
# Scan the output of all jobs looking for the summary lines that
# report the number of test cases and the number of errors.
# Aggregate these numbers and return them.
#
proc aggregate_test_counts {db} {
set ncase 0
set nerr 0
$db eval {SELECT output FROM jobs WHERE displaytype IN ('tcl','fuzz')} {
set n 0
set m 0
if {[regexp {(\d+) errors out of (\d+) tests} $output all n m]
&& [string is integer -strict $n]
&& [string is integer -strict $m]} {
incr ncase $m
incr nerr $n
} elseif {[regexp {sessionfuzz.*: *(\d+) cases, (\d+) crash} $output \
all m n]
&& [string is integer -strict $m]
&& [string is integer -strict $n]} {
incr ncase $m
incr nerr $n
}
}
return [list $nerr $ncase]
}
#--------------------------------------------------------------------------
# Check if this is the "errors" command:
#
if {[llength $argv]>=1 && [llength $argv]<=2
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
[string match err* [lindex $argv 0]]==1)
} {
set verbose 0
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="-v" || $a0=="--verbose" || $a0=="-verbose"} {
set verbose 1
} else {
puts "unknown option: \"$a0\"". Use --help for more info."
exit 1
}
}
set cnt 0
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval {SELECT displaytype, displayname, output
FROM jobs WHERE state='failed'} {
puts "**** $displayname ****"
if {$verbose || $displaytype!="tcl"} {
puts $output
} else {
foreach line [split $output \n] {
if {[string match {!*} $line] || [string match *failed* $line]} {
puts $line
}
}
}
incr cnt
}
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
exit
}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Parse the command line. # Parse the command line.
# #
@@ -490,6 +627,16 @@ for {set ii 0} {$ii < [llength $argv]} {incr ii} {
set TRG(stopOnError) 1 set TRG(stopOnError) 1
} elseif {[string match "$a*" --stop-on-coredump]} { } elseif {[string match "$a*" --stop-on-coredump]} {
set TRG(stopOnCore) 1 set TRG(stopOnCore) 1
} elseif {[string match "$a*" --status]} {
if {$tcl_platform(platform)=="windows"} {
puts stdout \
"The --status option is not available on Windows. A suggested work-around"
puts stdout \
"is to run the following command in a separate window:\n"
puts stdout " [info nameofexe] $argv0 status -d 2\n"
} else {
set TRG(fullstatus) 1
}
} else { } else {
usage usage
} }
@@ -603,12 +750,6 @@ proc r_get_next_job {iJob} {
return $ret return $ret
} }
#rename r_get_next_job r_get_next_job_r
#proc r_get_next_job {iJob} {
#puts [time { set res [r_get_next_job_r $iJob] }]
#set res
#}
# Usage: # Usage:
# #
# add_job OPTION ARG OPTION ARG... # add_job OPTION ARG OPTION ARG...
@@ -1125,49 +1266,58 @@ proc launch_another_job {iJob} {
return 1 return 1
} }
proc one_line_report {} { # Show the testing progress report
#
proc progress_report {} {
global TRG global TRG
set tm [expr [clock_milliseconds] - $TRG(starttime)] if {$TRG(fullstatus)} {
set tm [format "%d" [expr int($tm/1000.0 + 0.5)]] if {$::tcl_platform(platform)=="windows"} {
exec [info nameofexe] $::argv0 status --cls
r_write_db { } else {
trdb eval { show_status trdb 1
SELECT displaytype, state, count(*) AS cnt
FROM jobs
GROUP BY 1, 2
} {
set v($state,$displaytype) $cnt
incr t($displaytype) $cnt
} }
}
set text ""
foreach j [lsort [array names t]] {
foreach k {done failed running} { incr v($k,$j) 0 }
set fin [expr $v(done,$j) + $v(failed,$j)]
lappend text "${j}($fin/$t($j))"
if {$v(failed,$j)>0} {
lappend text "f$v(failed,$j)"
}
if {$v(running,$j)>0} {
lappend text "r$v(running,$j)"
}
}
if {[info exists TRG(reportlength)]} {
puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
}
set report "${tm} [join $text { }]"
set TRG(reportlength) [string length $report]
if {[string length $report]<100} {
puts -nonewline "$report\r"
flush stdout
} else { } else {
puts $report set tm [expr [clock_milliseconds] - $TRG(starttime)]
} set tm [format "%d" [expr int($tm/1000.0 + 0.5)]]
after $TRG(reporttime) one_line_report r_write_db {
trdb eval {
SELECT displaytype, state, count(*) AS cnt
FROM jobs
GROUP BY 1, 2
} {
set v($state,$displaytype) $cnt
incr t($displaytype) $cnt
}
}
set text ""
foreach j [lsort [array names t]] {
foreach k {done failed running} { incr v($k,$j) 0 }
set fin [expr $v(done,$j) + $v(failed,$j)]
lappend text "${j}($fin/$t($j))"
if {$v(failed,$j)>0} {
lappend text "f$v(failed,$j)"
}
if {$v(running,$j)>0} {
lappend text "r$v(running,$j)"
}
}
if {[info exists TRG(reportlength)]} {
puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
}
set report "${tm} [join $text { }]"
set TRG(reportlength) [string length $report]
if {[string length $report]<100} {
puts -nonewline "$report\r"
flush stdout
} else {
puts $report
}
}
after $TRG(reporttime) progress_report
} }
proc launch_some_jobs {} { proc launch_some_jobs {} {
@@ -1192,13 +1342,14 @@ proc run_testset {} {
launch_some_jobs launch_some_jobs
one_line_report if {$TRG(fullstatus)} {puts "\033\[2J"}
progress_report
while {[dirs_nHelper]>0} { while {[dirs_nHelper]>0} {
after 500 {incr ::wakeup} after 500 {incr ::wakeup}
vwait ::wakeup vwait ::wakeup
} }
close $TRG(log) close $TRG(log)
one_line_report progress_report
r_write_db { r_write_db {
set tm [clock_milliseconds] set tm [clock_milliseconds]

View File

@@ -97,7 +97,11 @@ do_execsql_test 2.0 {
} }
foreach tn {0 1} { foreach tn {0 1} {
optimization_control db push-down $tn if {$tn} {
optimization_control db all on
} else {
optimization_control db push-down off
}
do_execsql_test 2.$tn.1.1 { do_execsql_test 2.$tn.1.1 {
SELECT * FROM v1; SELECT * FROM v1;

View File

@@ -350,6 +350,50 @@ do_eqp_test 400 {
FROM (SELECT f.*, exp(b) - 1 AS nFin, exp(a* (-1) + b) - 1 AS nPrev FROM (SELECT f.*, exp(b) - 1 AS nFin, exp(a* (-1) + b) - 1 AS nPrev
FROM fit f JOIN init i on i.country = f.country AND f.date <= date(i.fin,'-3 days')) FROM fit f JOIN init i on i.country = f.country AND f.date <= date(i.fin,'-3 days'))
WHERE nPrev > 0 AND nFin > 0; WHERE nPrev > 0 AND nFin > 0;
} {
QUERY PLAN
|--MATERIALIZE sums
| |--MATERIALIZE src
| | |--MATERIALIZE init
| | | `--SCAN raw USING INDEX sqlite_autoindex_raw_1
| | |--SCAN i
| | |--SEARCH raw USING COVERING INDEX sqlite_autoindex_raw_1 (country=? AND date>?)
| | `--USE TEMP B-TREE FOR ORDER BY
| |--SCAN src
| `--SEARCH raw USING INDEX sqlite_autoindex_raw_1 (country=? AND date>? AND date<?)
|--SCAN sums
|--BLOOM FILTER ON sums (country=? AND date=?)
|--SEARCH sums USING AUTOMATIC COVERING INDEX (country=? AND date=?)
|--BLOOM FILTER ON sums (country=? AND date=?)
|--SEARCH sums USING AUTOMATIC COVERING INDEX (country=? AND date=?)
|--BLOOM FILTER ON sums (country=? AND date=?)
|--SEARCH sums USING AUTOMATIC COVERING INDEX (country=? AND date=?)
|--BLOOM FILTER ON i (country=?)
`--SEARCH i USING AUTOMATIC COVERING INDEX (country=?)
}
optimization_control db order-by-subquery off
db cache flush
do_eqp_test 410 {
with recursive
init(country, date, fin) AS (SELECT country, min(date), max(date) FROM raw WHERE total > 0 GROUP BY country),
src(country, date) AS (SELECT raw.country, raw.date
FROM raw JOIN init i on raw.country = i.country AND raw.date > i.date
ORDER BY raw.country, raw.date),
vals(country, date, x, y) AS (SELECT src.country, src.date, julianday(raw.date) - julianday(src.date), log(delta+1)
FROM src JOIN raw on raw.country = src.country AND raw.date > date(src.date,'-7 days') AND raw.date <= src.date AND delta >= 0),
sums(country, date, x2, x, n, xy, y) AS (SELECT country, date, sum(x*x*1.0), sum(x*1.0), sum(1.0), sum(x*y*1.0), sum(y*1.0) FROM vals GROUP BY 1, 2),
mult(country, date, m) AS (SELECT country, date, 1.0/(x2 * n - x * x) FROM sums),
inv(country, date, a,b,c,d) AS (SELECT mult.country, mult.date, n * m, -x * m, -x * m, x2 * m
FROM mult JOIN sums on sums.country=mult.country AND mult.date=sums.date),
fit(country, date, a, b) AS (SELECT inv.country, inv.date, a * xy + b * y, c * xy + d * y
FROM inv
JOIN mult on mult.country = inv.country AND mult.date = inv.date
JOIN sums on sums.country = mult.country AND sums.date = mult.date
)
SELECT *, nFin/nPrev - 1 AS growth, log(2)/log(nFin/nPrev) AS doubling
FROM (SELECT f.*, exp(b) - 1 AS nFin, exp(a* (-1) + b) - 1 AS nPrev
FROM fit f JOIN init i on i.country = f.country AND f.date <= date(i.fin,'-3 days'))
WHERE nPrev > 0 AND nFin > 0;
} { } {
QUERY PLAN QUERY PLAN
|--MATERIALIZE sums |--MATERIALIZE sums

254
tool/buildtclext.tcl Normal file
View File

@@ -0,0 +1,254 @@
#!/usr/bin/tclsh
#
set help \
{Run this TCL script to build and install the TCL interface library for
SQLite. Run the script with the specific "tclsh" for which the installation
should occur.
There must be a valid "tclsqlite3.c" file in the working directory prior
to running this script. Use "make tclsqlite3.c" to generate that file.
Options:
--build-only Only build the extension, don't install it
--cc COMPILER Build using this compiler
--info Show info on existing SQLite TCL extension installs
--install-only Install an extension previously build
--uninstall Uninstall the extension
Other options are retained and passed through into the compiler.}
set build 1
set install 1
set uninstall 0
set infoonly 0
set CC {}
set OPTS {}
for {set ii 0} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="--install-only"} {
set build 0
} elseif {$a0=="--build-only"} {
set install 0
} elseif {$a0=="--uninstall"} {
set build 0
set install 0
set uninstall 1
} elseif {$a0=="--info"} {
set build 0
set install 0
set infoonly 1
} elseif {$a0=="--cc" && $ii+1<[llength $argv]} {
incr ii
set CC [lindex $argv $ii]
} elseif {[string match -* $a0]} {
append OPTS " $a0"
} else {
puts stderr "Unknown option: \"$a0\"\n"
puts stderr $help
exit 1
}
}
# Find the root of the SQLite source tree
#
set srcdir [file normalize [file dir $argv0]/..]
# Get the SQLite version number into $VERSION
#
set fd [open $srcdir/VERSION]
set VERSION [string trim [read $fd]]
close $fd
if {$tcl_platform(platform)=="windows"} {
# We are only able to install, uninstall, and list on Windows.
# The build process is handled by the Makefile.msc, specifically
# using "nmake /f Makefile.msc pkgIndex.tcl tclsqlite3.dll"
#
if {$build} {
puts "Unable to build on Windows using the builttclext.tcl script."
puts "To build, run\n"
puts " \"nmake /f Makefile.msc pkgIndex.tcl tclsqlite3.dll"
exit 1
}
set OUT tclsqlite3.dll
} else {
# Figure out the location of the tclConfig.sh file used by the
# tclsh that is executing this script.
#
if {[catch {
set LIBDIR [tcl::pkgconfig get libdir,install]
}]} {
puts stderr "$argv0: tclsh does not support tcl::pkgconfig."
exit 1
}
if {![file exists $LIBDIR]} {
puts stderr "$argv0: cannot find the tclConfig.sh file."
puts stderr "$argv0: tclsh reported library directory \"$LIBDIR\"\
does not exist."
exit 1
}
if {![file exists $LIBDIR/tclConfig.sh]
|| [file size $LIBDIR/tclConfig.sh]<5000} {
set n1 $LIBDIR/tcl$::tcl_version
if {[file exists $n1/tclConfig.sh]
&& [file size $n1/tclConfig.sh]>5000} {
set LIBDIR $n1
} else {
puts stderr "$argv0: cannot find tclConfig.sh in either $LIBDIR or $n1"
exit 1
}
}
# Read the tclConfig.sh file into the $tclConfig variable
#
#puts "using $LIBDIR/tclConfig.sh"
set fd [open $LIBDIR/tclConfig.sh rb]
set tclConfig [read $fd]
close $fd
# Extract parameter we will need from the tclConfig.sh file
#
set TCLMAJOR 8
regexp {TCL_MAJOR_VERSION='(\d)'} $tclConfig all TCLMAJOR
set SUFFIX so
regexp {TCL_SHLIB_SUFFIX='\.([^']+)'} $tclConfig all SUFFIX
if {$CC==""} {
set cc {}
regexp {TCL_CC='([^']+)'} $tclConfig all cc
if {$cc!=""} {
set CC $cc
}
}
if {$CC==""} {
set CC gcc
}
set CFLAGS -fPIC
regexp {TCL_SHLIB_CFLAGS='([^']+)'} $tclConfig all CFLAGS
set LIBS {}
regexp {TCL_STUB_LIB_SPEC='([^']+)'} $tclConfig all LIBS
set INC "-I$srcdir/src"
set inc {}
regexp {TCL_INCLUDE_SPEC='([^']+)'} $tclConfig all inc
if {$inc!=""} {
append INC " $inc"
}
set cmd {${CC} ${CFLAGS} ${LDFLAGS} -shared}
regexp {TCL_SHLIB_LD='([^']+)'} $tclConfig all cmd
set LDFLAGS "$INC -DUSE_TCL_STUBS"
if {[string length $OPTS]>1} {
append LDFLAGS $OPTS
}
set CMD [subst $cmd]
if {$TCLMAJOR>8} {
set OUT libtcl9sqlite$VERSION.$SUFFIX
} else {
set OUT libsqlite$VERSION.$SUFFIX
}
}
# Show information about prior installs
#
if {$infoonly} {
set cnt 0
foreach dir $auto_path {
foreach subdir [glob -nocomplain -types d $dir/sqlite3*] {
if {[file exists $subdir/pkgIndex.tcl]} {
puts $subdir
incr cnt
}
}
}
if {$cnt==0} {
puts "no current installations of the SQLite TCL extension"
}
exit
}
# Uninstall the extension
#
if {$uninstall} {
set cnt 0
foreach dir $auto_path {
if {[file isdirectory $dir/sqlite$VERSION]} {
incr cnt
if {![file writable $dir] || ![file writable $dir/sqlite$VERSION]} {
puts "cannot uninstall $dir/sqlite$VERSION - permission denied"
} else {
puts "uninstalling $dir/sqlite$VERSION..."
file delete -force $dir/sqlite$VERSION
}
}
}
if {$cnt==0} {
puts "nothing to uninstall"
}
exit
}
if {$install} {
# Figure out where the extension will be installed. Put the extension
# in the first writable directory on $auto_path.
#
set DEST {}
foreach dir $auto_path {
if {[file writable $dir]} {
set DEST $dir
break
} elseif {[glob -nocomplain $dir/sqlite3*/pkgIndex.tcl]!=""} {
set conflict [lindex [glob $dir/sqlite3*/pkgIndex.tcl] 0]
puts "Unable to install. There is already a conflicting version"
puts "of the SQLite TCL Extension that cannot be overwritten at\n"
puts " [file dirname $conflict]\n"
puts "Consider running using sudo to work around this problem."
exit 1
}
}
if {$DEST==""} {
puts "None of the directories on \$auto_path are writable by this process,"
puts "so the installation cannot take place. Consider running using sudo"
puts "to work around this problem.\n"
puts "These are the (unwritable) \$auto_path directories:\n"
foreach dir $auto_path {
puts " * $dir"
}
exit 1
}
}
if {$build} {
# Generate the pkgIndex.tcl file
#
puts "generating pkgIndex.tcl..."
set fd [open pkgIndex.tcl w]
puts $fd [subst -nocommands {# -*- tcl -*-
# Tcl package index file, version ???
#
package ifneeded sqlite3 $VERSION \\
[list load [file join \$dir $OUT] sqlite3]
}]
close $fd
# Generate and execute the command with which to do the compilation.
#
set cmd "$CMD tclsqlite3.c -o $OUT $LIBS"
puts $cmd
file delete -force $OUT
catch {exec {*}$cmd} errmsg
if {$errmsg!="" && ![file exists $OUT]} {
puts $errmsg
exit 1
}
}
if {$install} {
# Install the extension
set DEST2 $DEST/sqlite$VERSION
file mkdir $DEST2
puts "installing $DEST2/pkgIndex.tcl"
file copy -force pkgIndex.tcl $DEST2
puts "installing $DEST2/$OUT"
file copy -force $OUT $DEST2
}

24
tool/find_tclconfig.tcl Normal file
View File

@@ -0,0 +1,24 @@
#
# Run this TCL script to find and print the pathname for the tclConfig.sh
# file. Used by ../configure
#
if {[catch {
set libdir [tcl::pkgconfig get libdir,install]
}]} {
puts stderr "tclsh too old: does not support tcl::pkgconfig"
exit 1
}
if {![file exists $libdir]} {
puts stderr "tclsh reported library directory \"$libdir\" does not exist"
exit 1
}
if {![file exists $libdir/tclConfig.sh]} {
set n1 $libdir/tcl$::tcl_version
if {[file exists $n1/tclConfig.sh]} {
set libdir $n1
} else {
puts stderr "cannot find tclConfig.sh in either $libdir or $n1"
exit 1
}
}
puts $libdir