diff --git a/Makefile.in b/Makefile.in index 313a6db51b..75e99feef5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -121,10 +121,6 @@ TCLSH_CMD = @TCLSH_CMD@ # 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 # 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 @@ -1560,12 +1556,37 @@ install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ + tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a $(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: rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* diff --git a/Makefile.msc b/Makefile.msc index a9b38f22a4..88c43cf396 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1821,6 +1821,19 @@ pkgIndex.tcl: $(TOP)\VERSION $(SQLITE3TCLDLL): libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl $(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 + + # <> $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) diff --git a/configure b/configure index efd0422ac1..2c57d6ac3a 100755 --- a/configure +++ b/configure @@ -781,18 +781,6 @@ TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE TARGET_READLINE_INC 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 SQLITE_OS_WIN SQLITE_OS_UNIX @@ -806,6 +794,10 @@ RELEASE VERSION program_prefix TCLLIBDIR +HAVE_TCL +TCL_STUB_LIB_SPEC +TCL_LIB_SPEC +TCL_INCLUDE_SPEC TCLSH_CMD INSTALL_DATA INSTALL_SCRIPT @@ -894,12 +886,12 @@ enable_fast_install with_gnu_ld enable_libtool_lock enable_largefile +with_tclsh +with_tcl with_wasi_sdk enable_threadsafe enable_releasemode enable_tempstore -enable_tcl -with_tcl enable_editline enable_readline with_readline_lib @@ -1555,7 +1547,6 @@ Optional Features: --enable-releasemode Support libtool link to release mode --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) - --disable-tcl do not build TCL extension --enable-editline enable BSD editline support --disable-readline disable readline support --enable-debug enable debugging & verbose explain @@ -1583,10 +1574,10 @@ Optional Packages: --with-pic try to use only PIC/non-PIC objects [default=use both] --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 cross-compile to WASM. - --with-tcl=DIR directory containing tcl configuration - (tclConfig.sh) --with-readline-lib specify readline library --with-readline-inc specify readline include paths --with-linenoise=DIR source directory for linenoise library @@ -3945,13 +3936,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3948: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3939: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3951: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3942: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3954: output\"" >&5) + (eval echo "\"\$as_me:3945: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5157,7 +5148,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5160 "configure"' > conftest.$ac_ext + echo '#line 5151 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6682,11 +6673,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6685: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6676: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6689: \$? = $ac_status" >&5 + echo "$as_me:6680: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7021,11 +7012,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7024: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7015: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7028: \$? = $ac_status" >&5 + echo "$as_me:7019: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7126,11 +7117,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7129: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7120: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7133: \$? = $ac_status" >&5 + echo "$as_me:7124: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7181,11 +7172,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7184: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7175: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7188: \$? = $ac_status" >&5 + echo "$as_me:7179: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9561,7 +9552,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9564 "configure" +#line 9555 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9657,7 +9648,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9660 "configure" +#line 9651 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10314,24 +10305,23 @@ done USE_AMALGAMATION=1 ######### -# See whether we can run specific tclsh versions known to work well; -# if not, then we fall back to plain tclsh. -# TODO: try other versions before falling back? +# Figure out all the name of a working tclsh and parameters needed to compile against Tcl. +# The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. # -if test x"${with_tcl}" != x; then - if test ! -r ${with_tcl}/tclConfig.sh; then - as_fn_error $? "no tclConfig.sh file found in --with-tcl: ${with_tcl}" "$LINENO" 5 - else - . ${with_tcl}/tclConfig.sh - 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 -$as_echo "$as_me: WARNING: cannot use tclsh at: ${TCLSH_CMD}" >&2;} - TCLSH_CMD=none - fi - fi -else - for ac_prog in tclsh8.6 tclsh8.5 tclsh + +# Check whether --with-tclsh was given. +if test "${with_tclsh+set}" = set; then : + withval=$with_tclsh; +fi + + +# Check whether --with-tcl was given. +if test "${with_tcl+set}" = set; then : + withval=$with_tcl; +fi + +if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then + for ac_prog in tclsh8.6 tclsh tclsh9.0 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -10374,25 +10364,96 @@ fi done 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; } + 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 +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. + +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 if test "$TCLSH_CMD" = "none"; then # If we can't find a local tclsh, then building the amalgamation will fail. # 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 TCLSH_CMD="tclsh" -fi -if test x"$TCLSH_CMD" = x; then - as_fn_error $? "cannot find a usable tclsh" "$LINENO" 5 + HAVE_TCL=0 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: using $TCLSH_CMD" >&5 -$as_echo "using $TCLSH_CMD" >&6; } + HAVE_TCL=1 fi + if test "x${TCLLIBDIR+set}" != "xset" ; then - TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do if test -d $i ; then TCLLIBDIR=$i @@ -10789,213 +10850,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 # that use "readline()" library. diff --git a/configure.ac b/configure.ac index 9d8c594bae..095df5e4f6 100644 --- a/configure.ac +++ b/configure.ac @@ -116,41 +116,97 @@ AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_s USE_AMALGAMATION=1 ######### -# See whether we can run specific tclsh versions known to work well; -# if not, then we fall back to plain tclsh. -# TODO: try other versions before falling back? +# Figure out all the name of a working tclsh and parameters needed to compile against Tcl. +# The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. # -if test x"${with_tcl}" != x; then - if test ! -r ${with_tcl}/tclConfig.sh; then - AC_MSG_ERROR([no tclConfig.sh file found in --with-tcl: ${with_tcl}]) +AC_ARG_WITH(tclsh, AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use])) +AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)])) +if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then + AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh tclsh9.0],none) + with_tclsh=${TCLSH_CMD} +fi +if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then + TCLSH_CMD=${with_tclsh} + AC_MSG_RESULT([using tclsh at "$TCLSH_CMD"]) + 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 - . ${with_tcl}/tclConfig.sh - TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} - if test ! -x ${TCLSH_CMD}; then - AC_MSG_WARN([cannot use tclsh at: ${TCLSH_CMD}]) - TCLSH_CMD=none - fi + AC_MSG_WARN([$TCLSH_CMD is unable to recommend a tclConfig.sh]) + fi +fi +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 - AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none) + # 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. + +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 if test "$TCLSH_CMD" = "none"; then # If we can't find a local tclsh, then building the amalgamation will fail. # 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 TCLSH_CMD="tclsh" -fi -if test x"$TCLSH_CMD" = x; then - AC_MSG_ERROR([cannot find a usable tclsh]) + HAVE_TCL=0 else - AC_MSG_RESULT([using $TCLSH_CMD]) + HAVE_TCL=1 fi AC_SUBST(TCLSH_CMD) +AC_SUBST(HAVE_TCL) AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) if test "x${TCLLIBDIR+set}" != "xset" ; then - TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do if test -d $i ; then TCLLIBDIR=$i @@ -357,190 +413,6 @@ AC_SUBST(SQLITE_OS_UNIX) AC_SUBST(SQLITE_OS_WIN) 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 # that use "readline()" library. diff --git a/ext/consio/console_io.c b/ext/consio/console_io.c index 3e2f556f52..3fa613ba9d 100755 --- a/ext/consio/console_io.c +++ b/ext/consio/console_io.c @@ -53,11 +53,6 @@ # define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ #endif -#if CIO_WIN_WC_XLATE -/* Character used to represent a known-incomplete UTF-8 char group (�) */ -static WCHAR cBadGroup = 0xfffd; -#endif - #if CIO_WIN_WC_XLATE static HANDLE handleOfFile(FILE *pf){ int fileDesc = _fileno(pf); diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test index c456c30c52..72c4fd72cd 100644 --- a/ext/expert/expert1.test +++ b/ext/expert/expert1.test @@ -465,6 +465,13 @@ do_execsql_test 5.3 { 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 { do_test expert1-6.0 { catchcmd :memory: { diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 276c2cc9fe..b59a59728d 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -626,7 +626,7 @@ static int expertFilter( pCsr->pData = 0; if( rc==SQLITE_OK ){ 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( sqlite3_context *pCtx, @@ -1513,7 +1513,7 @@ static void idxRemFunc( assert( argc==2 ); iSlot = sqlite3_value_int(argv[0]); - assert( iSlot<=p->nSlot ); + assert( iSlotnSlot ); pSlot = &p->aSlot[iSlot]; switch( pSlot->eType ){ @@ -1624,7 +1624,8 @@ static int idxPopulateOneStat1( const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); 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); } @@ -1757,13 +1758,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ if( rc==SQLITE_OK ){ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); - rc = sqlite3_create_function( - dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 + rc = sqlite3_create_function(dbrem, "sqlite_expert_rem", + 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 ); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function( - p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 + rc = sqlite3_create_function(p->db, "sqlite_expert_sample", + 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); } + 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); return rc; } diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index f6caabf4c9..80f62eb3bb 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -398,6 +398,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ return 1; } + assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; inPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 732d4cf893..a39cc16bbf 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2263,6 +2263,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ } } +/* +** Add pSub as a child of p. +*/ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ @@ -2407,19 +2410,23 @@ Fts5ExprNode *sqlite3Fts5ParseNode( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; + pNear = 0; + assert( pLeft==0 && pRight==0 ); } } }else{ + assert( pNear==0 ); fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); + pLeft = pRight = 0; if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ sqlite3Fts5ParseError(pParse, "fts5 expression tree is too large (maximum depth %d)", SQLITE_FTS5_MAX_EXPR_DEPTH ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } @@ -2457,6 +2464,7 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF + || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) ); if( pLeft->eType==FTS5_AND ){ diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index c6e7e346aa..c862e2f956 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -2235,11 +2235,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){ } static void fts5ApiPhraseNext( - Fts5Context *pUnused, + Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ - UNUSED_PARAM(pUnused); if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; @@ -2247,8 +2246,12 @@ static void fts5ApiPhraseNext( int iVal; pIter->a += fts5GetVarint32(pIter->a, iVal); 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); - *piCol = iVal; + *piCol = (iVal>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index 3e9fdff3eb..9f5cd24c3c 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -79,7 +79,7 @@ static int fts5AsciiCreate( int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); - for(i=0; rc==SQLITE_OK && ibFold = 1; pNew->iFoldParam = 0; - for(i=0; rc==SQLITE_OK && iiFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index e2a91e51ef..cfe1438eda 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -8958,7 +8958,6 @@ do_catchsql_test 61.2 { SELECT * FROM t3 ORDER BY rowid; } {/*malformed database schema*/} -breakpoint #------------------------------------------------------------------------- do_test 62.0 { sqlite3 db {} @@ -10768,6 +10767,7 @@ do_catchsql_test 73.1 { reset_db do_test 74.0 { sqlite3 db {} + sqlite3_fts5_register_matchinfo db db deserialize [decode_hexdb { | size 106496 pagesize 4096 filename x.db | page 1 offset 0 @@ -14587,14 +14587,19 @@ do_test 74.0 { | end x.db }]} {} -do_catchsql_test 74.1 { - SELECT rowid, quote(matchinfo(t1,'p�xyb', '<') FROM t1('BB mess'); } {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 diff --git a/ext/fts5/test/fts5trigram.test b/ext/fts5/test/fts5trigram.test index 351c059bf5..752686620c 100644 --- a/ext/fts5/test/fts5trigram.test +++ b/ext/fts5/test/fts5trigram.test @@ -69,6 +69,9 @@ do_execsql_test 2.0 { INSERT INTO t1 VALUES('abcdefghijklm'); 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} { 1 abc "(abc)defghijklm" @@ -206,7 +209,7 @@ do_execsql_test 7.0 { (20, "жираф.png"), (30, "cat.png"), (40, "кот.png"), - (50, "misic-🎵-.mp3"); + (50, "misic-🎵-.mp3"); } do_execsql_test 7.1 { SELECT rowid FROM f WHERE +filename GLOB '*ир*'; diff --git a/ext/fts5/test/fts5trigram2.test b/ext/fts5/test/fts5trigram2.test index 00f6d43952..c81684a22b 100644 --- a/ext/fts5/test/fts5trigram2.test +++ b/ext/fts5/test/fts5trigram2.test @@ -21,6 +21,9 @@ do_execsql_test 1.0 " INSERT INTO t1 VALUES('abc\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 { SELECT highlight(t1, 0, '(', ')') FROM t1('abc'); @@ -117,4 +120,18 @@ do_execsql_test 4.2 { SELECT rowid FROM t4 WHERE z LIKE '%abc%' } {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 diff --git a/ext/fts5/test/fts5unicode2.test b/ext/fts5/test/fts5unicode2.test index dccaff0b1c..3fc1f673a4 100644 --- a/ext/fts5/test/fts5unicode2.test +++ b/ext/fts5/test/fts5unicode2.test @@ -470,120 +470,4 @@ do_execsql_test 8.2.3 { SELECT rowid FROM t4 WHERE t4 MATCH 'a' ORDER BY rowid ASC; } {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 diff --git a/ext/recover/dbdata.c b/ext/recover/dbdata.c index 109aeef2d6..001840b17e 100644 --- a/ext/recover/dbdata.c +++ b/ext/recover/dbdata.c @@ -679,6 +679,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ ** near the end of a corrupt record. */ rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); if( rc!=SQLITE_OK ) return rc; + assert( pCsr->rec.aBuf!=0 ); assert( nPayload!=0 ); /* Load the nLocal bytes of payload */ diff --git a/ext/recover/sqlite3recover.c b/ext/recover/sqlite3recover.c index 1d858c0ab9..afa1ae8619 100644 --- a/ext/recover/sqlite3recover.c +++ b/ext/recover/sqlite3recover.c @@ -363,8 +363,8 @@ static int recoverError( va_start(ap, zFmt); if( zFmt ){ z = sqlite3_vmprintf(zFmt, ap); - va_end(ap); } + va_end(ap); sqlite3_free(p->zErrMsg); p->zErrMsg = z; p->errCode = errCode; diff --git a/manifest b/manifest index 71d23b859c..4c5b2cebf8 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sreuse-schema\sbranch. -D 2024-08-01T01:06:47.733 +C Merge\sthe\slatest\strunk\senhancements\sinto\smain\sreuse-schema\sbranch. +D 2024-08-10T20:24:10.480 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 6563ad6492706df9d6251e6ab8c204cb60324f830811fae45062cbeecd28eb36 +F Makefile.in f472b68f999c348b8e9186f212b4d9c8d67246939dc4cef6d8a883e721a27a2e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 -F Makefile.msc cb30394a31363d12ed47da8c6acb79eda276def29082a771fb761e061cd0e4d5 +F Makefile.msc 68c6730323c18343cde7fe49d63101079c14608265149ab711f780b44b17c8c5 F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -35,8 +35,8 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034 F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure e0efd210b151971f4158e3fdf93b34322882a668a96f88b6167a6f7a51edebec x -F configure.ac 7361a1dd862c0ba0d2daa3d978bc3b93fcccc1ef3efe204d0238722c19bbdcf5 +F configure 8c74221e3e3af939270c27f0600281a5485ac2e5014dd7581b056e24a528d625 x +F configure.ac 9a3d92b38ad56456d09c1272f83131794f73110437f0f53fb94c90ce0d7a351a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd 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/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94 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/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c -F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4 +F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b +F ext/expert/sqlite3expert.c 8b09aeb2b95a9fca8b6628b522bf4d69aa746ff64c38eb1e99a9b5fad8cf03b9 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70 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_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 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_test.c 7a9cb3d61774134211bf4bfdf1adcb581a1a0377f2d050a121ae7ab44baef0e3 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_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_config.c 68cb87a49215f8e7028000b681df4057c430a4a6afbd676463886da94c9e1c37 -F ext/fts5/fts5_expr.c c7336d5f9ecc0e2b014d700be2bec0ea383b0e82c494a7c5c4ac622327c2bfad +F ext/fts5/fts5_expr.c 3a24c6ab5b7545312a5ec03085ae705ede820a08f9a63f1d72829ed4a35da6f6 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 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_tcl.c 5ca3e3e35010d326f5b821a563e4fcde3913e052935f5c2c72c264122a26b48f F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee 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_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 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/fts5corrupt.test a9bda1ded5112ebf1ee85c5381bd1fe8974952e2523cede4d5072804d2011503 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/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76 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/fts5ea.test cefdf66024550fa7920c03395c71ce5046235ed1a1a7a469d79b19e7aad5afb5 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/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 @@ -230,13 +231,13 @@ F ext/fts5/test/fts5synonym2.test 58f357b997cf2fedeeb9d0de4db9f880fa96fa2fe27a74 F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98 -F ext/fts5/test/fts5tokenizer2.test 9c1ad8ef0465076cbc9ff5c764782594329b3bce3e0f6a931a026902d006f495 -F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0 -F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566 +F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6 +F ext/fts5/test/fts5trigram.test be914555deb8504dde682bd5aa343d00c4da37dfad20709a5bac30d5f97f2ef5 +F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61 F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 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/fts5unicode4.test 728c8f0caafb05567f524ad313d9f8b780fa45987b8a8df04eff87923c74b4d0 F ext/fts5/test/fts5unindexed.test 168838d2c385e131120bbf5b516d2432a5fabc4caa2259c932e1d49ae209a4ae @@ -481,7 +482,7 @@ F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69 F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 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/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 @@ -497,7 +498,7 @@ F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52 F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 -F ext/recover/sqlite3recover.c 65ef0f56301a16c0536c9839fb7e23540c9c4f75da0afe3b7b4d163c8f624404 +F ext/recover/sqlite3recover.c 2dcf6b56c5e0e2b43fc4c6115b689ab194c374ced7f7f8380ad9a24d8ef24ac9 F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -616,10 +617,10 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122 F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e -F ext/wasm/api/sqlite3-api-glue.c-pp.js 54b32b5321105a72d6f3d3e8b77f28f162d0367b08c63184263d3f85f3d7dbed w ext/wasm/api/sqlite3-api-glue.js -F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f w ext/wasm/api/sqlite3-api-oo1.js +F ext/wasm/api/sqlite3-api-glue.c-pp.js 54b32b5321105a72d6f3d3e8b77f28f162d0367b08c63184263d3f85f3d7dbed +F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f F ext/wasm/api/sqlite3-api-prologue.js 6f1257e04885632ed9f44d43aba200b86e0bc16709ffdba29abbbeb1bc8e8b76 -F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d w ext/wasm/api/sqlite3-api-worker1.js +F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js e8f1df56e97a29004a95a2eddd26778f52c33b3e797d32d4b1b668a38e6493dd F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d @@ -692,7 +693,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c 8fd1f87dbf8b49f4e037817640d62d5e28661ad194d68fa10455fe5aada79ee9 +F src/alter.c 628af24886f2a8c2bc351aca3a406e7e16cdaee32994903bf194712c7023c51d F src/analyze.c e39333f0dbbdbd93871887438e5cda477764b75f39de53f8e420f70cbdb2ef6c F src/attach.c 2af98700f1a3867a78475aa164571a2fbacce09c681076b01b119ef31b8ef4ac F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 @@ -719,7 +720,7 @@ F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c +F src/insert.c 8ff11e9e54c5fc1fe89707b3d41cf44ad2822f712bd3b5da68338ea42518847e F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 @@ -749,7 +750,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y 2bd540b3b1e79017eb41fca2396633a75e7dd430c05383c61fe52c6f4e97c6d8 +F src/parse.y 318ef86fbe358b1a93262a42e152f37b97b3fddae8d319dffbd24ce2300f6c88 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 @@ -758,20 +759,20 @@ F src/pragma.h 50f6d3b408ed56bde4f4e4aead8c0b2022030b692e8de237c1b7a0b5ce87a0c8 F src/prepare.c 44dd5fd6f40a2687619d967387992d81868012622f93d5167ce947a0405a6f42 F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 7e8d23ce7cdbfedf351a47e759f2722e8182ca10fd7580be43f4ce1f1a228145 +F src/resolve.c 0aee8a2e5340ba95a966917305dfaff5147fcad78d0839cd364b16e4746b8bcb F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 6a95a2bffa6c09584dea99db5a7ae10c813305c09c92920ffc54f6eae2ba399e -F src/shell.c.in 74b34ee0e30a9240217e812690ad178b3208deaba878b844860ad37844dba82d +F src/shell.c.in 85f2df121b29154a8d4eb669aa7284a4b1a6c5c2abbb8f9019f7f34a80cb1b84 F src/sqlite.h.in 730e0c510b9699816ca04f56966a92be8b1ee239aba22a813c2389c8ff4ab5ad F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h d421ab1ced9647d73a8c8df036d26e0f6b872c75a6909c8544ac8e211bc1ac58 +F src/sqliteInt.h 5717254931a1b77edcf2d1eae6aa2a59326554400bc1008678502019e7524e51 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c 5028a0afee355aa492f26f0b6a3ec23145caa9261a93164d96cd0b9bf1b2318f F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c ef55aeb328c58e8721ff584cd94bd94c2800492d17abe20c976dcfaab6a4c180 +F src/tclsqlite.c f3c74b7612c6f583c94af48531caa1a7fecc53202bf4e0b202d39e54dc9322bc F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262 -F src/test1.c 51159784f29d3dfd4b50fd6ed9c43c8f7f36925c501a3ad3083528e5e5544bd7 +F src/test1.c be8cc208c0d50b3a7e570049e55f25ae40c1dfec8165b7ce12c2c8ed9f5b3030 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -791,7 +792,7 @@ F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c9 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851 -F src/test_hexio.c af6db9300edd2d7b786a2d40d64177cad4b8ee22085e8ca5fe812cdeffdb6502 +F src/test_hexio.c 0f777bf9fbb2684bb4978372bacc90ef7337d5d9e3cebe067a9409941e88bacf F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 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_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c F src/test_tclsh.c 3799a1f527224b3ae71c75460f0421a0ce076b3f356b11deae9a68fafbf0f533 -F src/test_tclvar.c 2c42fe9a74af0f3c8f87a339f66d9d3bd3a967fb5db1ed2500348055b954e391 +F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424 F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3 F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2 @@ -839,7 +840,7 @@ F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df F src/vdbeaux.c c3f96ee10c4b7c7458d347adba9c959bf14b7ae606a76476b3992f27f6c00051 F src/vdbeblob.c 968d66a7dbeeb4036997db8bc02162429de0f068846759b781bc30e7345f864a F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89 -F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 +F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c f99a7413a957f5175702f56b52488ff3df51ce04cc1b58b56a076a0f82dbc059 @@ -847,7 +848,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c 6329349181129cf5fde458a2a33b511d30fa0b7066011bc2ccb11a2f89553b60 +F src/where.c e507fb69f3bab9fca6ed17edeb6e31f3194ba5e285d3113de289928025c5399b F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65 F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290 @@ -948,6 +949,7 @@ F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede3967 F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/bestindexC.test 2df6ada16d8f00d9bb6a9664d9c323560aeed0e0ebc7a32b99d85d70037fd250 +F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1213,7 +1215,7 @@ F test/fts3query.test 45806a302921b245a9dba5d85c9d51fb98b3f137eea6e6bf6eae4883e0 F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e -F test/fts3snippet.test 0887196d67cffbe365edde535b95ecc642a532ce8551ccd9a73aab5999c3ffae +F test/fts3snippet.test 560c7f38c5fa591d88e367eac1313b64e503625616708ff61da9d5f52cbf75e5 F test/fts3snippet2.test 03f6738ab3897bea2ba6be424a0613872e167acbf37a66200d655d737b470f65 F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 @@ -1272,7 +1274,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc -F test/fuzzinvariants.c 0729b9d8ed77ad0f8c5c7601168a707d5803087d2da030ede9057c51c809cc6c +F test/fuzzinvariants.c 81167c9a7e82c0539a1d704aeb3384046d01f4108cda160a2447cb2a149d6362 F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 @@ -1599,7 +1601,7 @@ F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f -F test/select7.test f659f231489349e8c5734e610803d7654207318f +F test/select7.test b825420da8a0b5722fdb77f3369f6396a3d198c46e8787eb26ff9425d4ac9d27 F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812 F test/selectA.test 1da8ce3884c326e11d2855baffb76436b0d7e044404af8a2a70d1399a4ff7e29 @@ -1714,7 +1716,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 3c1b54f8c5782d5da6d301a28d375e44886a842c343a7bbafc3147cd17ba28a4 -F test/testrunner.tcl d21653d558436b5d06883820ed79dc346d7455bc4958a48aa748b597b6a9a02a +F test/testrunner.tcl 2260439d9014b22bd7b3fd698ad75b9400337c3b842a0a2cc4fcf83a1776c781 F test/testrunner_data.tcl 9cb9ac3708ad022697b542f0570db8491b3e254430f4dae6b7ce0c87fa6550fa F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2103,6 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5 +F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b8421e1428a F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2114,6 +2117,7 @@ F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651e F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c c129ae2924a48310c7b766810391da9e8fda532b9f6bd3f9a9e3a799a1b42af9 +F tool/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/fuzzershell.c 41480c8a1e4749351f381431ecfdfceba645396c5d836f8d26b51a33c4a21b33 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 @@ -2210,8 +2214,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8f6b8594133b71ef5d8a3e2d0bd32366bb85168fb49045a966e8a2aa8d03bd5d ea9d88f9ca3399bca83bf03893689a927b73e481604b94527e42de43f103eb46 -R f0ec32b4501bc6d8c56a26b5472052ab +P ff9fdd07d21a929eb5e15f90965a0530de178ffc6cbcc1049113a3ef692727f7 d4014c87ba9b011a6a04c2bf85879b668dc762ebcbbfb50a2f8a417ce594ef88 +R 28834e90a314071f2fd8a945e31158d4 U drh -Z f730877eb68407be03286546e7225af0 +Z b36b0bd8d6ae853098b8ed44e3bcfc75 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1bce46938c..d278d39bcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff9fdd07d21a929eb5e15f90965a0530de178ffc6cbcc1049113a3ef692727f7 +31a71a79bf9bd4737bf4a266056c7a4f4796c9bcc19e35e3f94e1235585cae9d diff --git a/src/alter.c b/src/alter.c index 233b76f5ba..310e7db10a 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1320,7 +1320,7 @@ static int renameResolveTrigger(Parse *pParse){ /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ - rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; } /* Resolve symbols in WHEN clause */ diff --git a/src/insert.c b/src/insert.c index 072386e656..a7e94420bf 100644 --- a/src/insert.c +++ b/src/insert.c @@ -717,6 +717,7 @@ Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; + if( pRet->pPrior ) pRet->selFlags |= SF_Values; pLeft->pPrior = 0; pLeft->op = TK_SELECT; assert( pLeft->pNext==0 ); diff --git a/src/parse.y b/src/parse.y index de8282e81f..68c00f0a7f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -532,9 +532,9 @@ cmd ::= select(X). { break; } } - if( (p->selFlags & SF_MultiValue)==0 && - (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && - cnt>mxSelect + if( (p->selFlags & (SF_MultiValue|SF_Values))==0 + && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 + && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } diff --git a/src/resolve.c b/src/resolve.c index d5c1515a74..dbb54198cb 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -2154,6 +2154,9 @@ int sqlite3ResolveExprNames( ** Resolve all names for all expression in an expression list. This is ** just like sqlite3ResolveExprNames() except that it works for an 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( NameContext *pNC, /* Namespace to resolve expressions in. */ @@ -2162,7 +2165,7 @@ int sqlite3ResolveExprListNames( int i; int savedHasAgg = 0; Walker w; - if( pList==0 ) return WRC_Continue; + if( pList==0 ) return SQLITE_OK; w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; @@ -2176,7 +2179,7 @@ int sqlite3ResolveExprListNames( #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ - return WRC_Abort; + return SQLITE_ERROR; } #endif sqlite3WalkExprNN(&w, pExpr); @@ -2193,10 +2196,10 @@ int sqlite3ResolveExprListNames( (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; - return WRC_Continue; + return SQLITE_OK; } /* diff --git a/src/shell.c.in b/src/shell.c.in index 8d0c2360dd..fd08e4ada5 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3546,6 +3546,14 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){ sqlite3_bind_double(pStmt, i, INFINITY); #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{ sqlite3_bind_null(pStmt, i); } @@ -11928,7 +11936,10 @@ static int doAutoDetectRestore(ShellState *p, const char *zSql){ case 0: { const char *zExpect = "PRAGMA foreign_keys=OFF;"; 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; }else{ p->eRestoreState = 7; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ad9ee9c5a5..4e179916e2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2934,9 +2934,15 @@ struct AggInfo { ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** 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 AggInfoFuncReg(A,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. diff --git a/src/tclsqlite.c b/src/tclsqlite.c index ed36b16c0f..04df285cc9 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -369,12 +369,19 @@ static int SQLITE_TCLAPI incrblobOutput( 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. */ -static long long SQLITE_TCLAPI incrblobWideSeek( +static WideSeekProcType SQLITE_TCLAPI incrblobWideSeek( ClientData instanceData, - long long offset, + WideSeekProcType offset, int seekMode, int *errorCodePtr ){ diff --git a/src/test1.c b/src/test1.c index 88bfdc06d2..9def739f4c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8324,7 +8324,7 @@ static int SQLITE_TCLAPI sorter_test_sort4_helper( for(iStep=0; iStepnAlloc ){ int nNew = nAlloc?nAlloc*2:128; diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 9be8774491..6299960a6c 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -68,8 +68,8 @@ struct tclvar_cursor { Tcl_Obj *pList1; /* Result of [info vars ?pattern?] */ Tcl_Obj *pList2; /* Result of [array names [lindex $pList1 $i1]] */ - int i1; /* Current item in pList1 */ - int i2; /* Current item (if any) in pList2 */ + Tcl_Size i1; /* Current item in pList1 */ + Tcl_Size i2; /* Current item (if any) in pList2 */ }; /* 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; pCur->i2++; Tcl_ListObjLength(0, pCur->pList2, &n); - if( pCur->i2>=(int)n ){ + if( pCur->i2>=n ){ Tcl_DecrRefCount(pCur->pList2); pCur->pList2 = 0; pCur->i2 = 0; @@ -170,7 +170,7 @@ static int tclvarNext(sqlite3_vtab_cursor *cur){ Tcl_Interp *interp = ((tclvar_vtab *)(cur->pVtab))->interp; Tcl_ListObjLength(0, pCur->pList1, &n); - while( !ok && pCur->i1<(int)n ){ + while( !ok && pCur->i1pList1, pCur->i1, &pObj); ok = next2(interp, pCur, pObj); if( !ok ){ diff --git a/src/vdbesort.c b/src/vdbesort.c index 0083690308..239c0a0f36 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -556,13 +556,14 @@ static int vdbePmaReadBlob( while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ 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; if( nRem>p->nBuffer ) nCopy = p->nBuffer; rc = vdbePmaReadBlob(p, nCopy, &aNext); if( rc!=SQLITE_OK ) return rc; assert( aNext!=p->aAlloc ); + assert( aNext!=0 ); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); nRem -= nCopy; } diff --git a/src/where.c b/src/where.c index ea6a9e4f3d..95091bec5c 100644 --- a/src/where.c +++ b/src/where.c @@ -1501,6 +1501,19 @@ static sqlite3_index_info *allocateIndexInfo( pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; 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; inKeyCol; i++){ + int iCol = pPk->aiColumn[i]; + assert( iCol>=0 ); + if( iCol>=BMS-1 ) iCol = BMS-1; + pIdxInfo->colUsed |= MASKBIT(iCol); + } + } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; @@ -4034,7 +4047,9 @@ static int whereLoopAddBtree( " according to whereIsCoveringIndex()\n", pProbe->zName)); } } - }else if( m==0 ){ + }else if( m==0 + && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) + ){ WHERETRACE(0x200, ("-> %s a covering index according to bitmasks\n", pProbe->zName, m==0 ? "is" : "is not")); @@ -4216,7 +4231,6 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ @@ -7066,26 +7080,6 @@ whereBeginError: } #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 ** sqlite3WhereBegin() for additional information. @@ -7385,16 +7379,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - || pOp->opcode==OP_Offset - ); -#else - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - ); -#endif + if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + sqlite3ErrorMsg(pParse, "internal query planner error"); + pParse->rc = SQLITE_INTERNAL; + } } }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; diff --git a/test/bestindexD.test b/test/bestindexD.test new file mode 100644 index 0000000000..b06d6b4270 --- /dev/null +++ b/test/bestindexD.test @@ -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 + + diff --git a/test/fts3snippet.test b/test/fts3snippet.test index ae022b68a6..ad1fbb3bef 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -561,7 +561,6 @@ do_test 4.3 { }] } {64} - #------------------------------------------------------------------------- # Request a snippet from a query with more than 64 phrases. # @@ -588,5 +587,9 @@ do_execsql_test 5.1 { {[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 finish_test diff --git a/test/fuzzinvariants.c b/test/fuzzinvariants.c index 80eb4aecb7..36121963f5 100644 --- a/test/fuzzinvariants.c +++ b/test/fuzzinvariants.c @@ -38,6 +38,31 @@ static void reportInvariantFailed( 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; i0} { set f "$S(failed) FAILED, " } - puts "Command line: \[testrunner.tcl$cmdline\]" - puts "Jobs: $nJob" - puts "Summary: ${tm}ms, ($fin/$total) finished, ${f}$S(running) running" + puts "Command line: \[testrunner.tcl$cmdline\]$clreol" + puts "Jobs: $nJob " + puts "Summary: ${tm}ms, ($fin/$total) finished,\ + ${f}$S(running) running " set srcdir [file dirname [file dirname $TRG(info_script)]] if {$S(running)>0} { puts "Running: " - mydb eval { + $db eval { SELECT * FROM jobs WHERE state='running' ORDER BY starttime } job { display_job [array get job] $now @@ -442,21 +463,137 @@ if {[llength $argv]==1 } if {$S(failed)>0} { puts "Failures: " - mydb eval { + $db eval { SELECT * FROM jobs WHERE state='failed' ORDER BY starttime } 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} { - 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 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. # @@ -490,6 +627,16 @@ for {set ii 0} {$ii < [llength $argv]} {incr ii} { set TRG(stopOnError) 1 } elseif {[string match "$a*" --stop-on-coredump]} { 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 { usage } @@ -603,12 +750,6 @@ proc r_get_next_job {iJob} { 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: # # add_job OPTION ARG OPTION ARG... @@ -1126,49 +1267,58 @@ proc launch_another_job {iJob} { return 1 } -proc one_line_report {} { +# Show the testing progress report +# +proc progress_report {} { global TRG - set tm [expr [clock_milliseconds] - $TRG(starttime)] - set tm [format "%d" [expr int($tm/1000.0 + 0.5)]] - - 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 + if {$TRG(fullstatus)} { + if {$::tcl_platform(platform)=="windows"} { + exec [info nameofexe] $::argv0 status --cls + } else { + show_status trdb 1 } - } - - 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 + set tm [expr [clock_milliseconds] - $TRG(starttime)] + set tm [format "%d" [expr int($tm/1000.0 + 0.5)]] + + 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) one_line_report + after $TRG(reporttime) progress_report } proc launch_some_jobs {} { @@ -1193,13 +1343,14 @@ proc run_testset {} { launch_some_jobs - one_line_report + if {$TRG(fullstatus)} {puts "\033\[2J"} + progress_report while {[dirs_nHelper]>0} { after 500 {incr ::wakeup} vwait ::wakeup } close $TRG(log) - one_line_report + progress_report r_write_db { set tm [clock_milliseconds] diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl new file mode 100644 index 0000000000..6d9e4c3063 --- /dev/null +++ b/tool/buildtclext.tcl @@ -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 +} diff --git a/tool/find_tclconfig.tcl b/tool/find_tclconfig.tcl new file mode 100644 index 0000000000..c3d3df8ec3 --- /dev/null +++ b/tool/find_tclconfig.tcl @@ -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