Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge trunk changes into this branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | fts5-locale |
Files: | files | file ages | folders |
SHA3-256: |
b243007525a825b3daf8aa9bb2d3088e |
User & Date: | dan 2024-08-10 20:03:01.148 |
Context
2024-08-12
| ||
11:13 | Update the auxiliary function API to include xTokenize_x2() instead of xSetLocale(). (check-in: f7d56a1f21 user: dan tags: fts5-locale) | |
2024-08-10
| ||
20:03 | Merge trunk changes into this branch. (check-in: b243007525 user: dan tags: fts5-locale) | |
19:57 | Prevent the fts5 xPhraseNext() or xPhraseFirst() APIs from returning an out-of-range column number, even if the database is corrupt. (check-in: d4014c87ba user: dan tags: trunk) | |
19:18 | Fix an uninitialized variable in fts5_tcl.c. (check-in: 924d3467ce user: dan tags: fts5-locale) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
117 118 119 120 121 122 123 | # TCLSH_CMD = @TCLSH_CMD@ # Where do we want to install the tcl plugin # TCLLIBDIR = @TCLLIBDIR@ | < < < < | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | # TCLSH_CMD = @TCLSH_CMD@ # Where do we want to install the tcl plugin # TCLLIBDIR = @TCLLIBDIR@ # 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 # causes build errors with -fprofile-arcs -ftest-coverage with some GCCs. # Supposedly GCC does the right thing if you use --coverage, but in # practice it still fails. See: # |
︙ | ︙ | |||
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 | $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir) $(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir) $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) 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) clean: rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* rm -rf .libs .deps rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) keywordhash.h | > > > > > > > > > > > > > > > > > > > > > > > > > | 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 | $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir) $(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir) $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) 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.* rm -rf .libs .deps rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) keywordhash.h |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 | for /F %%V in ('type "$(TOP)\VERSION"') do ( \ echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \ ) $(SQLITE3TCLDLL): libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS) # <</mark>> $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) # <<block2>> sqlite3.def: libsqlite3.lib | > > > > > > > > > > > > > | 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 | for /F %%V in ('type "$(TOP)\VERSION"') do ( \ echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \ ) $(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 # <</mark>> $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) # <<block2>> sqlite3.def: libsqlite3.lib |
︙ | ︙ |
Changes to autoconf/tea/tclconfig/tcl.m4.
︙ | ︙ |
Changes to autoconf/tea/win/rules.vc.
︙ | ︙ | |||
704 705 706 707 708 709 710 | !message *** Optional defines are '$(OPTDEFINES)' !message *** Compiler version $(VCVER). Target machine is $(MACHINE) !message *** Host architecture is $(NATIVE_ARCH) !message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' !message *** Link options '$(LINKERFLAGS)' !endif | < | 704 705 706 707 708 709 710 | !message *** Optional defines are '$(OPTDEFINES)' !message *** Compiler version $(VCVER). Target machine is $(MACHINE) !message *** Host architecture is $(NATIVE_ARCH) !message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)' !message *** Link options '$(LINKERFLAGS)' !endif |
Changes to configure.
︙ | ︙ | |||
777 778 779 780 781 782 783 | USE_AMALGAMATION TARGET_DEBUG TARGET_HAVE_LINENOISE TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE TARGET_READLINE_INC TARGET_READLINE_LIBS | < < < < < < < < < < < < > > > > | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 | USE_AMALGAMATION TARGET_DEBUG TARGET_HAVE_LINENOISE TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE TARGET_READLINE_INC TARGET_READLINE_LIBS TARGET_EXEEXT SQLITE_OS_WIN SQLITE_OS_UNIX BUILD_EXEEXT TEMP_STORE ALLOWRELEASE SQLITE_THREADSAFE BUILD_CC HAVE_WASI_SDK RELEASE VERSION program_prefix TCLLIBDIR HAVE_TCL TCL_STUB_LIB_SPEC TCL_LIB_SPEC TCL_INCLUDE_SPEC TCLSH_CMD INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CPP OTOOL64 OTOOL |
︙ | ︙ | |||
890 891 892 893 894 895 896 897 898 899 900 | enable_shared enable_static with_pic enable_fast_install with_gnu_ld enable_libtool_lock enable_largefile with_wasi_sdk enable_threadsafe enable_releasemode enable_tempstore | > > < < | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | enable_shared enable_static with_pic 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_editline enable_readline with_readline_lib with_readline_inc with_linenoise enable_debug enable_amalgamation |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --disable-threadsafe Disable mutexing --enable-releasemode Support libtool link to release mode --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) | < | 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 | optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --disable-threadsafe Disable mutexing --enable-releasemode Support libtool link to release mode --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) --enable-editline enable BSD editline support --disable-readline disable readline support --enable-debug enable debugging & verbose explain --disable-amalgamation Disable the amalgamation and instead build all files separately --disable-load-extension Disable loading of external extensions |
︙ | ︙ | |||
1579 1580 1581 1582 1583 1584 1585 1586 1587 | Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --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-wasi-sdk=DIR directory containing the WASI SDK. Triggers cross-compile to WASM. | > > < < | 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 | Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --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-readline-lib specify readline library --with-readline-inc specify readline include paths --with-linenoise=DIR source directory for linenoise library Some influential environment variables: CC C compiler command CFLAGS C compiler flags |
︙ | ︙ | |||
3941 3942 3943 3944 3945 3946 3947 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext | | | | | 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:3939: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&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:3945: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 |
︙ | ︙ | |||
5153 5154 5155 5156 5157 5158 5159 | ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. | | | 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 | ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. 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=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in |
︙ | ︙ | |||
6678 6679 6680 6681 6682 6683 6684 | # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` | | | | 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 | # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -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:6676: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&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. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes |
︙ | ︙ | |||
7017 7018 7019 7020 7021 7022 7023 | # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` | | | | 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 | # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -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:7015: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&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. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes |
︙ | ︙ | |||
7122 7123 7124 7125 7126 7127 7128 | # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` | | | | 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 | # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -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:7120: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&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 # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then |
︙ | ︙ | |||
7177 7178 7179 7180 7181 7182 7183 | # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` | | | | 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 | # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -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:7175: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&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 # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then |
︙ | ︙ | |||
9557 9558 9559 9560 9561 9562 9563 | else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF | | | 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 | else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 9555 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> |
︙ | ︙ | |||
9653 9654 9655 9656 9657 9658 9659 | else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF | | | 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 | else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 9651 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> |
︙ | ︙ | |||
10310 10311 10312 10313 10314 10315 10316 | ######### # By default, we use the amalgamation (this may be changed below...) # USE_AMALGAMATION=1 ######### | > > > | > > > > | | > > > > | > | | 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 | ######### # By default, we use the amalgamation (this may be changed below...) # USE_AMALGAMATION=1 ######### # 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. # # 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_TCLSH_CMD+:} false; then : $as_echo_n "(cached) " >&6 |
︙ | ︙ | |||
10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 | fi test -n "$TCLSH_CMD" && break done test -n "$TCLSH_CMD" || TCLSH_CMD="none" 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. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > < | 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 | fi test -n "$TCLSH_CMD" && break 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. { $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" HAVE_TCL=0 else HAVE_TCL=1 fi if test "x${TCLLIBDIR+set}" != "xset" ; then for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do if test -d $i ; then TCLLIBDIR=$i break fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" |
︙ | ︙ | |||
10764 10765 10766 10767 10768 10769 10770 | CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" fi | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 | CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" fi ########## # Figure out what C libraries are required to compile programs # that use "readline()" library. # TARGET_READLINE_LIBS="" TARGET_READLINE_INC="" |
︙ | ︙ |
Changes to configure.ac.
︙ | ︙ | |||
112 113 114 115 116 117 118 | ######### # By default, we use the amalgamation (this may be changed below...) # USE_AMALGAMATION=1 ######### | | | < | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > < | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | ######### # By default, we use the amalgamation (this may be changed below...) # USE_AMALGAMATION=1 ######### # 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. # 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 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 # 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. AC_MSG_WARN([Warning: can't find tclsh - defaulting to non-amalgamation build.]) USE_AMALGAMATION=0 TCLSH_CMD="tclsh" HAVE_TCL=0 else 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 for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do if test -d $i ; then TCLLIBDIR=$i break fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" |
︙ | ︙ | |||
335 336 337 338 339 340 341 | fi AC_SUBST(BUILD_EXEEXT) AC_SUBST(SQLITE_OS_UNIX) AC_SUBST(SQLITE_OS_WIN) AC_SUBST(TARGET_EXEEXT) | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | fi AC_SUBST(BUILD_EXEEXT) AC_SUBST(SQLITE_OS_UNIX) AC_SUBST(SQLITE_OS_WIN) AC_SUBST(TARGET_EXEEXT) ########## # Figure out what C libraries are required to compile programs # that use "readline()" library. # TARGET_READLINE_LIBS="" TARGET_READLINE_INC="" TARGET_HAVE_READLINE=0 |
︙ | ︙ |
Changes to ext/consio/console_io.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 | # endif # define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ # endif #else # define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ #endif | < < < < < | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # endif # define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ # endif #else # define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ #endif #if CIO_WIN_WC_XLATE static HANDLE handleOfFile(FILE *pf){ int fileDesc = _fileno(pf); union { intptr_t osfh; HANDLE fh; } fid = { (fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE }; return fid.fh; |
︙ | ︙ |
Changes to ext/expert/expert1.test.
︙ | ︙ | |||
461 462 463 464 465 466 467 468 469 470 471 472 473 474 | t1 t1_idx_00000062 {100 20} t1 t1_idx_000123a7 {100 50 17} t2 t2_idx_00000063 {100 20} t2 t2_idx_00000064 {100 5} t2 t2_idx_0001295b {100 20 5} } if 0 { do_test expert1-6.0 { catchcmd :memory: { .expert select base64(''); .expert select name from pragma_collation_list order by name collate uint; | > > > > > > > | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | t1 t1_idx_00000062 {100 20} t1 t1_idx_000123a7 {100 50 17} t2 t2_idx_00000063 {100 20} t2 t2_idx_00000064 {100 5} t2 t2_idx_0001295b {100 20 5} } do_catchsql_test 5.4 { SELECT sqlite_expert_rem(123, 123); } {1 {no such function: sqlite_expert_rem}} do_catchsql_test 5.5 { SELECT sqlite_expert_sample(); } {1 {no such function: sqlite_expert_sample}} if 0 { do_test expert1-6.0 { catchcmd :memory: { .expert select base64(''); .expert select name from pragma_collation_list order by name collate uint; |
︙ | ︙ |
Changes to ext/expert/sqlite3expert.c.
︙ | ︙ | |||
622 623 624 625 626 627 628 | (void)idxStr; (void)argc; (void)argv; rc = sqlite3_finalize(pCsr->pData); pCsr->pData = 0; if( rc==SQLITE_OK ){ rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, | | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | (void)idxStr; (void)argc; (void)argv; rc = sqlite3_finalize(pCsr->pData); pCsr->pData = 0; if( rc==SQLITE_OK ){ rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, "SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName ); } if( rc==SQLITE_OK ){ rc = expertNext(cur); } return rc; |
︙ | ︙ | |||
1496 1497 1498 1499 1500 1501 1502 | int nByte; /* Bytes of space allocated at z */ int n; /* Size of buffer z */ char *z; /* SQLITE_TEXT/BLOB value */ } aSlot[1]; }; /* | | | | 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | int nByte; /* Bytes of space allocated at z */ int n; /* Size of buffer z */ char *z; /* SQLITE_TEXT/BLOB value */ } aSlot[1]; }; /* ** Implementation of scalar function sqlite_expert_rem(). */ static void idxRemFunc( sqlite3_context *pCtx, int argc, sqlite3_value **argv ){ struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); struct IdxRemSlot *pSlot; int iSlot; assert( argc==2 ); iSlot = sqlite3_value_int(argv[0]); assert( iSlot<p->nSlot ); pSlot = &p->aSlot[iSlot]; switch( pSlot->eType ){ case SQLITE_NULL: /* no-op */ break; |
︙ | ︙ | |||
1620 1621 1622 1623 1624 1625 1626 | /* Formulate the query text */ sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ const char *zComma = zCols==0 ? "" : ", "; const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); zCols = idxAppendText(&rc, zCols, | > | | 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 | /* Formulate the query text */ sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ const char *zComma = zCols==0 ? "" : ", "; 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 sqlite_expert_rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl ); zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); } sqlite3_reset(pIndexXInfo); if( rc==SQLITE_OK ){ if( p->iSample==100 ){ zQuery = sqlite3_mprintf( |
︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 | if( rc==SQLITE_OK ){ int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); } if( rc==SQLITE_OK ){ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); | | | | | | 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 | if( rc==SQLITE_OK ){ int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); } if( rc==SQLITE_OK ){ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); 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, "sqlite_expert_sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 ); } if( rc==SQLITE_OK ){ pCtx->nSlot = nMax+1; rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); } |
︙ | ︙ | |||
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | sqlite3_free(pCtx); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); } sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); return rc; } /* ** Define and possibly pretend to use a useless collation sequence. ** This pretense allows expert to accept SQL using custom collations. | > > > | 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 | sqlite3_free(pCtx); } if( rc==SQLITE_OK ){ 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; } /* ** Define and possibly pretend to use a useless collation sequence. ** This pretense allows expert to accept SQL using custom collations. |
︙ | ︙ |
Changes to ext/expert/test_expert.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | */ #if defined(SQLITE_TEST) #include "sqlite3expert.h" #include <assert.h> #include <string.h> | < < < < | < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | */ #if defined(SQLITE_TEST) #include "sqlite3expert.h" #include <assert.h> #include <string.h> #include "tclsqlite.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Extract an sqlite3* db handle from the object passed as the second ** argument. If successful, set *pDb to point to the db handle and return ** TCL_OK. Otherwise, return TCL_ERROR. |
︙ | ︙ |
Changes to ext/fts3/fts3_snippet.c.
︙ | ︙ | |||
394 395 396 397 398 399 400 401 402 403 404 405 406 407 | iEnd = pPhrase->iHead; } } if( iEnd==0x7FFFFFFF ){ return 1; } pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; i<pIter->nPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); } } | > | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | iEnd = pPhrase->iHead; } } if( iEnd==0x7FFFFFFF ){ return 1; } assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; i<pIter->nPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); } } |
︙ | ︙ |
Changes to ext/fts3/fts3_test.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** testing. It contains a Tcl command that can be used to test if a document ** matches an FTS NEAR expression. ** ** As of March 2012, it also contains a version 1 tokenizer used for testing ** that the sqlite3_tokenizer_module.xLanguage() method is invoked correctly. */ | < < < | < < < < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** testing. It contains a Tcl command that can be used to test if a document ** matches an FTS NEAR expression. ** ** As of March 2012, it also contains a version 1 tokenizer used for testing ** that the sqlite3_tokenizer_module.xLanguage() method is invoked correctly. */ #include "tclsqlite.h" #include <string.h> #include <assert.h> #if defined(SQLITE_TEST) #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) /* Required so that the "ifdef SQLITE_ENABLE_FTS3" below works */ |
︙ | ︙ | |||
163 164 165 166 167 168 169 | NearPhrase *aPhrase = 0; NearDocument doc = {0, 0}; Tcl_Obj **apDocToken; Tcl_Obj *pRet; Tcl_Obj *pPhrasecount = 0; Tcl_Obj **apExprToken; | | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | NearPhrase *aPhrase = 0; NearDocument doc = {0, 0}; Tcl_Obj **apDocToken; Tcl_Obj *pRet; Tcl_Obj *pPhrasecount = 0; Tcl_Obj **apExprToken; Tcl_Size nExprToken; Tcl_Size nn; UNUSED_PARAMETER(clientData); /* Must have 3 or more arguments. */ if( objc<3 || (objc%2)==0 ){ Tcl_WrongNumArgs(interp, 1, objv, "DOCUMENT EXPR ?OPTION VALUE?..."); rc = TCL_ERROR; |
︙ | ︙ | |||
197 198 199 200 201 202 203 | switch( aOpt[iOpt].eOpt ){ case NM_PHRASECOUNTS: pPhrasecount = objv[ii+1]; break; } } | | > | > | | | | > | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | switch( aOpt[iOpt].eOpt ){ case NM_PHRASECOUNTS: pPhrasecount = objv[ii+1]; break; } } rc = Tcl_ListObjGetElements(interp, objv[1], &nn, &apDocToken); doc.nToken = (int)nn; if( rc!=TCL_OK ) goto near_match_out; doc.aToken = (NearToken *)ckalloc(doc.nToken*sizeof(NearToken)); for(ii=0; ii<doc.nToken; ii++){ doc.aToken[ii].z = Tcl_GetStringFromObj(apDocToken[ii], &nn); doc.aToken[ii].n = (int)nn; } rc = Tcl_ListObjGetElements(interp, objv[2], &nExprToken, &apExprToken); if( rc!=TCL_OK ) goto near_match_out; nPhrase = (int)(nExprToken + 1) / 2; aPhrase = (NearPhrase *)ckalloc(nPhrase * sizeof(NearPhrase)); memset(aPhrase, 0, nPhrase * sizeof(NearPhrase)); for(ii=0; ii<nPhrase; ii++){ Tcl_Obj *pPhrase = apExprToken[ii*2]; Tcl_Obj **apToken; Tcl_Size nToken; int jj; rc = Tcl_ListObjGetElements(interp, pPhrase, &nToken, &apToken); if( rc!=TCL_OK ) goto near_match_out; if( nToken>NM_MAX_TOKEN ){ Tcl_AppendResult(interp, "Too many tokens in phrase", 0); rc = TCL_ERROR; goto near_match_out; } for(jj=0; jj<(int)nToken; jj++){ NearToken *pT = &aPhrase[ii].aToken[jj]; pT->z = Tcl_GetStringFromObj(apToken[jj], &nn); pT->n = (int)nn; } aPhrase[ii].nToken = (int)nToken; } for(ii=1; ii<nPhrase; ii++){ Tcl_Obj *pNear = apExprToken[2*ii-1]; int nNear; rc = Tcl_GetIntFromObj(interp, pNear, &nNear); if( rc!=TCL_OK ) goto near_match_out; aPhrase[ii].nNear = nNear; |
︙ | ︙ |
Changes to ext/fts3/fts3_tokenizer.c.
︙ | ︙ | |||
222 223 224 225 226 227 228 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST | < < < | < | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST #include "tclsqlite.h" #include <string.h> /* ** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This ** function must be called with two or more arguments: ** |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 | default: assert( pNode->eType==FTS5_NOT ); { pNode->xNext = fts5ExprNodeNext_NOT; break; }; } } static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); p->nChild += pSub->nChild; sqlite3_free(pSub); | > > > | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 | default: assert( pNode->eType==FTS5_NOT ); { pNode->xNext = fts5ExprNodeNext_NOT; break; }; } } /* ** 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 ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); p->nChild += pSub->nChild; sqlite3_free(pSub); |
︙ | ︙ | |||
2403 2404 2405 2406 2407 2408 2409 | || pPhrase->nTerm>1 || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) ){ sqlite3Fts5ParseError(pParse, "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); | | > > > > | | 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 | || pPhrase->nTerm>1 || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) ){ sqlite3Fts5ParseError(pParse, "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); 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 ); sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } } } } |
︙ | ︙ | |||
2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 | || pLeft->eType==FTS5_TERM || pLeft->eType==FTS5_EOF || pLeft->eType==FTS5_AND ); assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF ); if( pLeft->eType==FTS5_AND ){ pPrev = pLeft->apChild[pLeft->nChild-1]; }else{ pPrev = pLeft; } | > | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 | || pLeft->eType==FTS5_TERM || pLeft->eType==FTS5_EOF || pLeft->eType==FTS5_AND ); assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) ); if( pLeft->eType==FTS5_AND ){ pPrev = pLeft->apChild[pLeft->nChild-1]; }else{ pPrev = pLeft; } |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
2487 2488 2489 2490 2491 2492 2493 | } } return pRet; } static void fts5ApiPhraseNext( | | < > > > > | | 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 | } } return pRet; } static void fts5ApiPhraseNext( Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; }else{ 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>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } *piOff += (iVal-2); } } |
︙ | ︙ |
Changes to ext/fts5/fts5_tcl.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ****************************************************************************** ** */ #ifdef SQLITE_TEST | < < < | < < < < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ****************************************************************************** ** */ #ifdef SQLITE_TEST #include "tclsqlite.h" #ifdef SQLITE_ENABLE_FTS5 #include "fts5.h" #include <string.h> #include <assert.h> |
︙ | ︙ | |||
294 295 296 297 298 299 300 | rc = p->pApi->xColumnTotalSize(p->pFts, iCol, &nSize); if( rc==SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSize)); } break; } CASE(3, "xTokenize") { | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | rc = p->pApi->xColumnTotalSize(p->pFts, iCol, &nSize); if( rc==SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSize)); } break; } CASE(3, "xTokenize") { Tcl_Size nText; char *zText = Tcl_GetStringFromObj(objv[2], &nText); F5tFunction ctx; ctx.interp = interp; ctx.pScript = objv[3]; rc = p->pApi->xTokenize(p->pFts, zText, (int)nText, &ctx, xTokenizeCb); if( rc==SQLITE_OK ){ Tcl_ResetResult(interp); } return rc; } CASE(4, "xPhraseCount") { int nPhrase; |
︙ | ︙ | |||
616 617 618 619 620 621 622 | Tcl_DecrRefCount(pEval); Tcl_DeleteCommand(p->interp, zCmd); if( rc!=TCL_OK ){ sqlite3_result_error(pCtx, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); | < > | | > > | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | Tcl_DecrRefCount(pEval); Tcl_DeleteCommand(p->interp, zCmd); if( rc!=TCL_OK ){ sqlite3_result_error(pCtx, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ /* Only return a BLOB type if the Tcl variable is a bytearray and ** has no string representation. */ Tcl_Size nn; unsigned char *data = Tcl_GetByteArrayFromObj(pVar, &nn); sqlite3_result_blob(pCtx, data, (int)nn, SQLITE_TRANSIENT); }else if( c=='b' && strcmp(zType,"boolean")==0 ){ int n; Tcl_GetIntFromObj(0, pVar, &n); sqlite3_result_int(pCtx, n); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(0, pVar, &r); sqlite3_result_double(pCtx, r); }else if( (c=='w' && strcmp(zType,"wideInt")==0) || (c=='i' && strcmp(zType,"int")==0) ){ Tcl_WideInt v; Tcl_GetWideIntFromObj(0, pVar, &v); sqlite3_result_int64(pCtx, v); }else{ Tcl_Size nn; unsigned char *data = (unsigned char *)Tcl_GetStringFromObj(pVar, &nn); sqlite3_result_text(pCtx, (char*)data, (int)nn, SQLITE_TRANSIENT); } } } static void xF5tDestroy(void *pCtx){ F5tFunction *p = (F5tFunction*)pCtx; Tcl_DecrRefCount(p->pScript); |
︙ | ︙ | |||
731 732 733 734 735 736 737 | static int SQLITE_TCLAPI f5tTokenize( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char *zText; | | | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | static int SQLITE_TCLAPI f5tTokenize( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char *zText; Tcl_Size nText; sqlite3 *db = 0; fts5_api *pApi = 0; Fts5Tokenizer *pTok = 0; fts5_tokenizer tokenizer; Tcl_Obj *pRet = 0; void *pUserdata; int rc; Tcl_Size nArg; const char **azArg; F5tTokenizeCtx ctx; if( objc!=4 && objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-subst? DB NAME TEXT"); return TCL_ERROR; } |
︙ | ︙ | |||
772 773 774 775 776 777 778 | rc = pApi->xFindTokenizer(pApi, azArg[0], &pUserdata, &tokenizer); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], 0); return TCL_ERROR; } | | | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | rc = pApi->xFindTokenizer(pApi, azArg[0], &pUserdata, &tokenizer); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], 0); return TCL_ERROR; } rc = tokenizer.xCreate(pUserdata, &azArg[1], (int)(nArg-1), &pTok); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error in tokenizer.xCreate()", 0); return TCL_ERROR; } pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); ctx.bSubst = (objc==5); ctx.pRet = pRet; ctx.zInput = zText; rc = tokenizer.xTokenize( pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText,(int)nText, xTokenizeCb2 ); tokenizer.xDelete(pTok); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", 0); Tcl_DecrRefCount(pRet); return TCL_ERROR; } |
︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ F5tTokenizerContext *p = (F5tTokenizerContext*)clientData; int iStart; int iEnd; | | | | 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ F5tTokenizerContext *p = (F5tTokenizerContext*)clientData; int iStart; int iEnd; Tcl_Size nToken; int tflags = 0; char *zToken; int rc; if( objc==5 ){ Tcl_Size nArg; char *zArg = Tcl_GetStringFromObj(objv[1], &nArg); if( nArg<=10 && nArg>=2 && memcmp("-colocated", zArg, nArg)==0 ){ tflags |= FTS5_TOKEN_COLOCATED; }else{ goto usage; } }else if( objc!=4 ){ |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | if( p->xToken==0 ){ Tcl_AppendResult(interp, "sqlite3_fts5_token may only be used by tokenizer callback", 0 ); return TCL_ERROR; } | | | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 | if( p->xToken==0 ){ Tcl_AppendResult(interp, "sqlite3_fts5_token may only be used by tokenizer callback", 0 ); return TCL_ERROR; } rc = p->xToken(p->pCtx, tflags, zToken, (int)nToken, iStart, iEnd); Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); return rc==SQLITE_OK ? TCL_OK : TCL_ERROR; usage: Tcl_WrongNumArgs(interp, 1, objv, "?-colocated? TEXT START END"); return TCL_ERROR; } |
︙ | ︙ | |||
1306 1307 1308 1309 1310 1311 1312 | static int SQLITE_TCLAPI f5tTokenHash( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char *z; | | | | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | static int SQLITE_TCLAPI f5tTokenHash( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char *z; Tcl_Size n; unsigned int iVal; int nSlot; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "NSLOT TOKEN"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &nSlot) ){ return TCL_ERROR; } z = Tcl_GetStringFromObj(objv[2], &n); iVal = f5t_fts5HashKey(nSlot, z, (int)n); Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal)); return TCL_OK; } static int SQLITE_TCLAPI f5tRegisterMatchinfo( void * clientData, Tcl_Interp *interp, |
︙ | ︙ |
Changes to ext/fts5/fts5_tokenize.c.
︙ | ︙ | |||
75 76 77 78 79 80 81 | p = sqlite3_malloc(sizeof(AsciiTokenizer)); if( p==0 ){ rc = SQLITE_NOMEM; }else{ int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); | | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | p = sqlite3_malloc(sizeof(AsciiTokenizer)); if( p==0 ){ rc = SQLITE_NOMEM; }else{ int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ fts5AsciiAddExceptions(p, zArg, 1); }else if( 0==sqlite3_stricmp(azArg[i], "separators") ){ fts5AsciiAddExceptions(p, zArg, 0); }else{ rc = SQLITE_ERROR; } } if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR; if( rc!=SQLITE_OK ){ fts5AsciiDelete((Fts5Tokenizer*)p); p = 0; } } } |
︙ | ︙ | |||
377 378 379 380 381 382 383 | p->nFold = 64; p->aFold = sqlite3_malloc64(p->nFold * sizeof(char)); if( p->aFold==0 ){ rc = SQLITE_NOMEM; } /* Search for a "categories" argument */ | | < | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | p->nFold = 64; p->aFold = sqlite3_malloc64(p->nFold * sizeof(char)); if( p->aFold==0 ){ rc = SQLITE_NOMEM; } /* Search for a "categories" argument */ for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ if( 0==sqlite3_stricmp(azArg[i], "categories") ){ zCat = azArg[i+1]; } } if( rc==SQLITE_OK ){ rc = unicodeSetCategories(p, zCat); } for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; }else{ p->eRemoveDiacritic = (zArg[0] - '0'); assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE |
︙ | ︙ | |||
412 413 414 415 416 417 418 419 420 421 422 423 424 425 | }else if( 0==sqlite3_stricmp(azArg[i], "categories") ){ /* no-op */ }else{ rc = SQLITE_ERROR; } } }else{ rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ fts5UnicodeDelete((Fts5Tokenizer*)p); p = 0; | > | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | }else if( 0==sqlite3_stricmp(azArg[i], "categories") ){ /* no-op */ }else{ rc = SQLITE_ERROR; } } if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; }else{ rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ fts5UnicodeDelete((Fts5Tokenizer*)p); p = 0; |
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | UNUSED_PARAM(pUnused); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ int i; pNew->bFold = 1; pNew->iFoldParam = 0; | | > | 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 | UNUSED_PARAM(pUnused); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ int i; pNew->bFold = 1; pNew->iFoldParam = 0; for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ rc = SQLITE_ERROR; }else{ pNew->bFold = (zArg[0]=='0'); } }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; }else{ pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; } }else{ rc = SQLITE_ERROR; } } if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; } if( rc!=SQLITE_OK ){ fts5TriDelete((Fts5Tokenizer*)pNew); |
︙ | ︙ |
Changes to ext/fts5/test/fts5aa.test.
︙ | ︙ | |||
436 437 438 439 440 441 442 | CREATE VIRTUAL TABLE n1 USING fts5(a); INSERT INTO n1 VALUES('a b c d'); } proc funk {} { db eval { UPDATE n1_config SET v=50 WHERE k='version' } set fd [db incrblob main n1_data block 10] | | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | CREATE VIRTUAL TABLE n1 USING fts5(a); INSERT INTO n1 VALUES('a b c d'); } proc funk {} { db eval { UPDATE n1_config SET v=50 WHERE k='version' } set fd [db incrblob main n1_data block 10] fconfigure $fd -translation binary # puts -nonewline $fd "\x44\x45" close $fd } db func funk funk # This test case corrupts the structure record within the first invocation # of function funk(). Which used to cause the bm25() function to throw an # exception. But since bm25() can now used the cached structure record, # it never sees the corruption introduced by funk() and so the following # statement no longer fails. # do_catchsql_test 16.2 { SELECT funk(), format('%g',bm25(n1)), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' } {0 {{} -1e-06 {}}} # {1 {SQL logic error}} #------------------------------------------------------------------------- # reset_db sqlite3_fts5_register_origintext db |
︙ | ︙ |
Changes to ext/fts5/test/fts5corrupt2.test.
︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # corruption. It may not report the db as corrupt because truncating the # final leaf to some sizes may create a valid leaf page. # set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}] set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}] set all [db eval {SELECT rowid FROM t1}] sqlite3_db_config db DEFENSIVE 0 for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} { do_execsql_test 2.$i.1 { BEGIN; UPDATE t1_data SET block = substr(block, 1, $i) WHERE rowid=$lrowid; } do_catchsql_test 2.$i.2 { | > | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | # corruption. It may not report the db as corrupt because truncating the # final leaf to some sizes may create a valid leaf page. # set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}] set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}] set all [db eval {SELECT rowid FROM t1}] sqlite3_db_config db DEFENSIVE 0 unset -nocomplain res for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} { do_execsql_test 2.$i.1 { BEGIN; UPDATE t1_data SET block = substr(block, 1, $i) WHERE rowid=$lrowid; } do_catchsql_test 2.$i.2 { |
︙ | ︙ | |||
148 149 150 151 152 153 154 | foreach rowid [db eval {SELECT rowid FROM x3_data WHERE rowid>10}] { if {$rowid & $mask} continue incr tn2 do_test 3.$tn.$tn2.1 { execsql BEGIN set fd [db incrblob main x3_data block $rowid] | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | foreach rowid [db eval {SELECT rowid FROM x3_data WHERE rowid>10}] { if {$rowid & $mask} continue incr tn2 do_test 3.$tn.$tn2.1 { execsql BEGIN set fd [db incrblob main x3_data block $rowid] fconfigure $fd -translation binary set existing [read $fd [string length $hdr]] seek $fd 0 puts -nonewline $fd $hdr close $fd set res [catchsql {SELECT rowid FROM x3 WHERE x3 MATCH 'x AND a'}] if {$res == "1 {database disk image is malformed}"} {incr nCorrupt} |
︙ | ︙ | |||
234 235 236 237 238 239 240 | foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] { if {$rowid & $mask} continue incr tn2 do_test 5.$tn.$tn2 { execsql BEGIN set fd [db incrblob main x5_data block $rowid] | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] { if {$rowid & $mask} continue incr tn2 do_test 5.$tn.$tn2 { execsql BEGIN set fd [db incrblob main x5_data block $rowid] fconfigure $fd -translation binary puts -nonewline $fd $hdr close $fd catchsql { INSERT INTO x5(x5) VALUES('integrity-check') } set {} {} } {} |
︙ | ︙ |
Changes to ext/fts5/test/fts5corrupt3.test.
︙ | ︙ | |||
8954 8955 8956 8957 8958 8959 8960 | CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' ); } {/*malformed database schema*/} do_catchsql_test 61.2 { SELECT * FROM t3 ORDER BY rowid; } {/*malformed database schema*/} | < | 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 | CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' ); } {/*malformed database schema*/} do_catchsql_test 61.2 { SELECT * FROM t3 ORDER BY rowid; } {/*malformed database schema*/} #------------------------------------------------------------------------- do_test 62.0 { sqlite3 db {} db deserialize [decode_hexdb { .open --hexdb | size 28672 pagesize 4096 filename crash-44942694542e1e.db | page 1 offset 0 |
︙ | ︙ | |||
10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 | * FROM ttt('e* NOT ee*e* NOT ee* NOT ee*e* NOT e*') ; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 74.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 106496 pagesize 4096 filename x.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 1a .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ | > | 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 | * FROM ttt('e* NOT ee*e* NOT ee* NOT ee*e* NOT e*') ; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- 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 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 1a .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ |
︙ | ︙ | |||
14583 14584 14585 14586 14587 14588 14589 | | 4032: b8 64 0a 02 34 02 03 b2 9a 9e 05 04 83 16 02 04 .d..4........... | 4048: b4 a7 93 36 06 04 83 7d 03 02 ba 9c 02 04 83 07 ...6............ | 4064: 04 09 09 0a 0a 0c 0b 08 09 09 08 09 08 09 0a 0a ................ | 4080: 0a 09 0a 0a 08 0a 08 09 0a 09 09 09 09 09 09 0a ................ | end x.db }]} {} | | | > > > > > | 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 | | 4032: b8 64 0a 02 34 02 03 b2 9a 9e 05 04 83 16 02 04 .d..4........... | 4048: b4 a7 93 36 06 04 83 7d 03 02 ba 9c 02 04 83 07 ...6............ | 4064: 04 09 09 0a 0a 0c 0b 08 09 09 08 09 08 09 0a 0a ................ | 4080: 0a 09 0a 0a 08 0a 08 09 0a 09 09 09 09 09 09 0a ................ | end x.db }]} {} do_catchsql_test 74.0.5 { SELECT matchinfo(1,2); } {1 {unable to use function matchinfo in the requested context}} do_catchsql_test 74.1 { SELECT rowid, quote(matchinfo(t1,'pxyb<s')) FROM t1 WHERE t1 MATCH 'e*'; } {1 {unrecognized matchinfo flag: <}} #------------------------------------------------------------------------- reset_db do_test 75.0 { sqlite3 db {} sqlite3_fts5_register_matchinfo db db deserialize [decode_hexdb { | size 32768 pagesize 4096 filename crash-033d665d5caa8d.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ | 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 | 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............ |
︙ | ︙ | |||
14787 14788 14789 14790 14791 14792 14793 | | page 8 offset 28672 | 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int... | end crash-033d665d5caa8d.db }]} {} do_catchsql_test 75.1 { SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*'; | | | 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 | | page 8 offset 28672 | 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int... | end crash-033d665d5caa8d.db }]} {} do_catchsql_test 75.1 { SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*'; } {1 {database disk image is malformed}} #------------------------------------------------------------------------- reset_db do_test 76.0 { sqlite3 db {} db deserialize [decode_hexdb { | size 40960 pagesize 4096 filename crash-03b68c01d30713.db |
︙ | ︙ |
Changes to ext/fts5/test/fts5eb.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 | } do_execsql_test 3.0 { CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61'); INSERT INTO e1 VALUES ('just a few words with a / inside'); } do_execsql_test 3.1 { | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | } do_execsql_test 3.0 { CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61'); INSERT INTO e1 VALUES ('just a few words with a / inside'); } do_execsql_test 3.1 { SELECT rowid, format('%g',bm25(e1)) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank; } {1 -1e-06} do_execsql_test 3.2 { SELECT rowid FROM e1 WHERE e1 MATCH '"/" OR "just"' } 1 do_execsql_test 3.3 { SELECT rowid, format('%g',bm25(e1)) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank; } {1 -1e-06} do_execsql_test 3.4 " SELECT fts5_expr_tcl('e AND \" \"'); " {{AND [nearset -- {e}] [{}]}} |
︙ | ︙ |
Added ext/fts5/test/fts5expr.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # 2024 August 8 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5expr # If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return } do_execsql_test 1.0 { CREATE VIRTUAL TABLE x1 USING fts5(a); INSERT INTO x1(rowid, a) VALUES (113, 'fts5 expr test'); } do_execsql_test 1.1 { SELECT rowid FROM x1('expr'); } {113} for {set ii 0} {$ii < 300} {incr ii} { set expr "expr " append expr [string repeat "NOT abcd " $ii] if {$ii<257} { set res {0 113} } else { set res {1 {fts5 expression tree is too large (maximum depth 256)}} } do_catchsql_test 1.1.$ii { SELECT rowid FROM x1($expr) } $res } finish_test |
Changes to ext/fts5/test/fts5first.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | } do_execsql_test 1.0 { CREATE VIRTUAL TABLE x1 USING fts5(a, b); } foreach {tn expr ok} { 1 {^abc} 1 2 {^abc + def} 1 3 {^ "abc def"} 1 4 {^"abc def"} 1 5 {abc ^def} 1 6 {abc + ^def} 0 | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | } do_execsql_test 1.0 { CREATE VIRTUAL TABLE x1 USING fts5(a, b); } unset -nocomplain res foreach {tn expr ok} { 1 {^abc} 1 2 {^abc + def} 1 3 {^ "abc def"} 1 4 {^"abc def"} 1 5 {abc ^def} 1 6 {abc + ^def} 0 |
︙ | ︙ |
Changes to ext/fts5/test/fts5integrity.test.
︙ | ︙ | |||
149 150 151 152 153 154 155 156 157 158 159 160 161 162 | INSERT INTO gg(gg) VALUES('optimize'); } do_execsql_test 5.3 { INSERT INTO gg(gg) VALUES('integrity-check'); } do_test 5.4.1 { set ok 0 for {set i 0} {$i < 10000} {incr i} { set T [format %.5d $i] set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }] set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }] if {$res == [lsort -integer $res2]} { incr ok } | > | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | INSERT INTO gg(gg) VALUES('optimize'); } do_execsql_test 5.3 { INSERT INTO gg(gg) VALUES('integrity-check'); } unset -nocomplain res do_test 5.4.1 { set ok 0 for {set i 0} {$i < 10000} {incr i} { set T [format %.5d $i] set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }] set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }] if {$res == [lsort -integer $res2]} { incr ok } |
︙ | ︙ |
Changes to ext/fts5/test/fts5interrupt.test.
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | proc progress_handler {args} { incr ::progress_handler_delay -1 if {$::progress_handler_delay<=0} { return 1 } return 0 } foreach {tn sql} { 1 { INSERT INTO t1(rowid, a) VALUES(0, 'z z z z') } 2 { COMMIT } } { set bDone 0 for {set i 1} {$bDone==0} {incr i} { do_test 1.$tn.$i { | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | proc progress_handler {args} { incr ::progress_handler_delay -1 if {$::progress_handler_delay<=0} { return 1 } return 0 } unset -nocomplain res foreach {tn sql} { 1 { INSERT INTO t1(rowid, a) VALUES(0, 'z z z z') } 2 { COMMIT } } { set bDone 0 for {set i 1} {$bDone==0} {incr i} { do_test 1.$tn.$i { |
︙ | ︙ | |||
60 61 62 63 64 65 66 | } set {} {} } {} } } finish_test | < | 61 62 63 64 65 66 67 | } set {} {} } {} } } finish_test |
Changes to ext/fts5/test/fts5restart.test.
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | CREATE VIRTUAL TABLE f1 USING fts5(ff); } #------------------------------------------------------------------------- # Run the 'optimize' command. Check that it does not disturb ongoing # full-text queries. # do_test 1.1 { for {set i 1} {$i < 1000} {incr i} { execsql { INSERT INTO f1 VALUES('a b c d e') } lappend lRowid $i } } {} | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | CREATE VIRTUAL TABLE f1 USING fts5(ff); } #------------------------------------------------------------------------- # Run the 'optimize' command. Check that it does not disturb ongoing # full-text queries. # unset -nocomplain lRowid do_test 1.1 { for {set i 1} {$i < 1000} {incr i} { execsql { INSERT INTO f1 VALUES('a b c d e') } lappend lRowid $i } } {} |
︙ | ︙ |
Changes to ext/fts5/test/fts5tokenizer2.test.
︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 | do_execsql_test 1.6 { SELECT highlight(t1, 0, '>', '<') FROM t1('mess'); } {AAdontBB>mess<} do_execsql_test 1.7 { SELECT highlight(t1, 0, '>', '<') FROM t1('BB mess'); } {AAdont>BBmess<} finish_test | > > > > > > > > > > > > > > > > > > > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | do_execsql_test 1.6 { SELECT highlight(t1, 0, '>', '<') FROM t1('mess'); } {AAdontBB>mess<} do_execsql_test 1.7 { SELECT highlight(t1, 0, '>', '<') 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 |
Changes to ext/fts5/test/fts5trigram.test.
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize="trigram case_sensitive 1"); INSERT INTO t1 VALUES('abcdefghijklm'); INSERT INTO t1 VALUES('กรุงเทพมหานคร'); } foreach {tn s res} { 1 abc "(abc)defghijklm" 2 defgh "abc(defgh)ijklm" 3 abcdefghijklm "(abcdefghijklm)" 4 กรุ "(กรุ)งเทพมหานคร" 5 งเทพมห "กรุ(งเทพมห)านคร" | > > > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize="trigram case_sensitive 1"); 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" 2 defgh "abc(defgh)ijklm" 3 abcdefghijklm "(abcdefghijklm)" 4 กรุ "(กรุ)งเทพมหานคร" 5 งเทพมห "กรุ(งเทพมห)านคร" |
︙ | ︙ | |||
202 203 204 205 206 207 208 | do_execsql_test 7.0 { CREATE VIRTUAL TABLE f USING FTS5(filename, tokenize="trigram"); INSERT INTO f (rowid, filename) VALUES (10, "giraffe.png"), (20, "жираф.png"), (30, "cat.png"), (40, "кот.png"), | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | do_execsql_test 7.0 { CREATE VIRTUAL TABLE f USING FTS5(filename, tokenize="trigram"); INSERT INTO f (rowid, filename) VALUES (10, "giraffe.png"), (20, "жираф.png"), (30, "cat.png"), (40, "кот.png"), (50, "misic-ðµ-.mp3"); } do_execsql_test 7.1 { SELECT rowid FROM f WHERE +filename GLOB '*ир*'; } {20} do_execsql_test 7.2 { SELECT rowid FROM f WHERE filename GLOB '*ир*'; } {20} |
︙ | ︙ |
Changes to ext/fts5/test/fts5trigram2.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | set ::testprefix fts5trigram2 do_execsql_test 1.0 " CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize='trigram remove_diacritics 1'); INSERT INTO t1 VALUES('abc\u0303defghijklm'); INSERT INTO t1 VALUES('a\u0303b\u0303c\u0303defghijklm'); " do_execsql_test 1.1 { SELECT highlight(t1, 0, '(', ')') FROM t1('abc'); } [list \ "(abc\u0303)defghijklm" \ "(a\u0303b\u0303c\u0303)defghijklm" \ ] | > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | set ::testprefix fts5trigram2 do_execsql_test 1.0 " CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize='trigram remove_diacritics 1'); 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'); } [list \ "(abc\u0303)defghijklm" \ "(a\u0303b\u0303c\u0303)defghijklm" \ ] |
︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 | do_eqp_test 4.1 { SELECT rowid FROM t4 WHERE z LIKE '%abc%' } {VIRTUAL TABLE INDEX 0:L0} do_execsql_test 4.2 { SELECT rowid FROM t4 WHERE z LIKE '%abc%' } {1} finish_test | > > > > > > > > > > > > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | do_eqp_test 4.1 { SELECT rowid FROM t4 WHERE z LIKE '%abc%' } {VIRTUAL TABLE INDEX 0:L0} 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 |
Changes to ext/fts5/test/fts5unicode.test.
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | " {t1 t2} #------------------------------------------------------------------------- # Check that codepoints that require 4 bytes to store in utf-8 (those that # require 17 or more bits to store). # set A [db one {SELECT char(0x1F75E)}] ;# Type So set B [db one {SELECT char(0x1F5FD)}] ;# Type So set C [db one {SELECT char(0x2F802)}] ;# Type Lo set D [db one {SELECT char(0x2F808)}] ;# Type Lo do_execsql_test 3.0 " CREATE VIRTUAL TABLE xyz USING fts5(x, | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | " {t1 t2} #------------------------------------------------------------------------- # Check that codepoints that require 4 bytes to store in utf-8 (those that # require 17 or more bits to store). # unset -nocomplain A B C D set A [db one {SELECT char(0x1F75E)}] ;# Type So set B [db one {SELECT char(0x1F5FD)}] ;# Type So set C [db one {SELECT char(0x2F802)}] ;# Type Lo set D [db one {SELECT char(0x2F808)}] ;# Type Lo do_execsql_test 3.0 " CREATE VIRTUAL TABLE xyz USING fts5(x, |
︙ | ︙ |
Changes to ext/fts5/test/fts5unicode2.test.
︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 | Improvements to the handling of CSV inputs in the command-line shell } { Fix a bug introduced in version 3.7.10 that might cause a LEFT JOIN to be incorrectly converted into an INNER JOIN if the WHERE clause indexable terms connected by OR. }] set map(a) [list "\u00C4" "\u00E4"] ; # LATIN LETTER A WITH DIAERESIS set map(e) [list "\u00CB" "\u00EB"] ; # LATIN LETTER E WITH DIAERESIS set map(i) [list "\u00CF" "\u00EF"] ; # LATIN LETTER I WITH DIAERESIS set map(o) [list "\u00D6" "\u00F6"] ; # LATIN LETTER O WITH DIAERESIS set map(u) [list "\u00DC" "\u00FC"] ; # LATIN LETTER U WITH DIAERESIS set map(y) [list "\u0178" "\u00FF"] ; # LATIN LETTER Y WITH DIAERESIS set map(h) [list "\u1E26" "\u1E27"] ; # LATIN LETTER H WITH DIAERESIS | > | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | Improvements to the handling of CSV inputs in the command-line shell } { Fix a bug introduced in version 3.7.10 that might cause a LEFT JOIN to be incorrectly converted into an INNER JOIN if the WHERE clause indexable terms connected by OR. }] unset -nocomplain map set map(a) [list "\u00C4" "\u00E4"] ; # LATIN LETTER A WITH DIAERESIS set map(e) [list "\u00CB" "\u00EB"] ; # LATIN LETTER E WITH DIAERESIS set map(i) [list "\u00CF" "\u00EF"] ; # LATIN LETTER I WITH DIAERESIS set map(o) [list "\u00D6" "\u00F6"] ; # LATIN LETTER O WITH DIAERESIS set map(u) [list "\u00DC" "\u00FC"] ; # LATIN LETTER U WITH DIAERESIS set map(y) [list "\u0178" "\u00FF"] ; # LATIN LETTER Y WITH DIAERESIS set map(h) [list "\u1E26" "\u1E27"] ; # LATIN LETTER H WITH DIAERESIS |
︙ | ︙ | |||
465 466 467 468 469 470 471 | do_execsql_test 8.2.2 { SELECT rowid FROM t4 WHERE t4 MATCH 'o' ORDER BY rowid ASC; } {1 3} do_execsql_test 8.2.3 { SELECT rowid FROM t4 WHERE t4 MATCH 'a' ORDER BY rowid ASC; } {2 4} | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 466 467 468 469 470 471 472 473 | do_execsql_test 8.2.2 { SELECT rowid FROM t4 WHERE t4 MATCH 'o' ORDER BY rowid ASC; } {1 3} do_execsql_test 8.2.3 { SELECT rowid FROM t4 WHERE t4 MATCH 'a' ORDER BY rowid ASC; } {2 4} finish_test |
Changes to ext/fts5/test/fts5vocab.test.
︙ | ︙ | |||
509 510 511 512 513 514 515 516 517 518 519 520 521 522 | INSERT INTO ft(a) VALUES('4 5 6'); INSERT INTO ft(a) VALUES('1 2 3'); INSERT INTO ft(a) VALUES('4 5 6'); INSERT INTO ft(a) VALUES('1 2 3'); INSERT INTO ft(a) VALUES('4 5 6'); } do_test 10.6 { set res [list] db eval { SELECT rowid FROM ft('4') } x { db eval { SELECT * FROM t2 } lappend res $x(rowid) } db eval COMMIT | > | 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 | INSERT INTO ft(a) VALUES('4 5 6'); INSERT INTO ft(a) VALUES('1 2 3'); INSERT INTO ft(a) VALUES('4 5 6'); INSERT INTO ft(a) VALUES('1 2 3'); INSERT INTO ft(a) VALUES('4 5 6'); } unset -nocomplain x res do_test 10.6 { set res [list] db eval { SELECT rowid FROM ft('4') } x { db eval { SELECT * FROM t2 } lappend res $x(rowid) } db eval COMMIT |
︙ | ︙ |
Changes to ext/intck/test_intck.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" #include "sqlite3intck.h" | < < < < | < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" #include "sqlite3intck.h" #include "tclsqlite.h" #include <string.h> #include <assert.h> /* In test1.c */ int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); const char *sqlite3ErrName(int); |
︙ | ︙ |
Changes to ext/rbu/test_rbu.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "sqlite3.h" #if defined(SQLITE_TEST) #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) #include "sqlite3rbu.h" | < < < | < < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include "sqlite3.h" #if defined(SQLITE_TEST) #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) #include "sqlite3rbu.h" #include "tclsqlite.h" #include <assert.h> #include <string.h> typedef struct TestRbu TestRbu; struct TestRbu { sqlite3rbu *pRbu; Tcl_Interp *interp; |
︙ | ︙ | |||
428 429 430 431 432 433 434 | for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } #else | < < < | < | 421 422 423 424 425 426 427 428 429 430 431 | for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } #else #include "tclsqlite.h" int SqliteRbu_Init(Tcl_Interp *interp){ return TCL_OK; } #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ #endif /* defined(SQLITE_TEST) */ |
Changes to ext/recover/dbdata.c.
︙ | ︙ | |||
675 676 677 678 679 680 681 682 683 684 685 686 687 688 | }else{ /* Allocate space for payload. And a bit more to catch small buffer ** overruns caused by attempting to read a varint or similar from ** near the end of a corrupt record. */ rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); if( rc!=SQLITE_OK ) return rc; assert( nPayload!=0 ); /* Load the nLocal bytes of payload */ memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal); iOff += nLocal; /* Load content from overflow pages */ | > | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | }else{ /* Allocate space for payload. And a bit more to catch small buffer ** overruns caused by attempting to read a varint or similar from ** 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 */ memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal); iOff += nLocal; /* Load content from overflow pages */ |
︙ | ︙ |
Changes to ext/recover/recovercorrupt4.test.
︙ | ︙ | |||
30 31 32 33 34 35 36 | } db close do_test 1.1 { set sz [expr [file size test.db] - 1024] set fd [open test.db] | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | } db close do_test 1.1 { set sz [expr [file size test.db] - 1024] set fd [open test.db] fconfigure $fd -translation binary set data [read $fd $sz] set fd2 [open test.db2 w] fconfigure $fd2 -translation binary puts -nonewline $fd2 $data close $fd2 set {} {} } {} do_test 1.2 { forcedelete test.db3 |
︙ | ︙ | |||
57 58 59 60 61 62 63 | execsql { SELECT indexed, unindexed FROM rows } } {1 1 2 2 4 4 8 8} } finish_test | < | 57 58 59 60 61 62 63 | execsql { SELECT indexed, unindexed FROM rows } } {1 1 2 2 4 4 8 8} } finish_test |
Changes to ext/recover/recoverpgsz.test.
︙ | ︙ | |||
35 36 37 38 39 40 41 | UPDATE t1 SET c = randomblob(100000); } } db close set fd [open test.db] | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | UPDATE t1 SET c = randomblob(100000); } } db close set fd [open test.db] fconfigure $fd -translation binary seek $fd $pgsz set pg1 [read $fd $pgsz] set pg2 [read $fd $pgsz] close $fd set fd2 [open test.db2 w] fconfigure $fd2 -translation binary seek $fd2 $pgsz puts -nonewline $fd2 $pg1 close $fd2 sqlite3 db2 test.db2 do_test 1.$pgsz.$bOverflow.2 { set R [sqlite3_recover_init db2 main test.db3] |
︙ | ︙ | |||
67 68 69 70 71 72 73 | db2 close db3 close forcedelete test.db3 forcedelete test.db2 set fd2 [open test.db2 w] | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | db2 close db3 close forcedelete test.db3 forcedelete test.db2 set fd2 [open test.db2 w] fconfigure $fd2 -translation binary seek $fd2 $pgsz puts -nonewline $fd2 $pg2 close $fd2 sqlite3 db2 test.db2 do_test 1.$pgsz.$bOverflow.4 { set R [sqlite3_recover_init db2 main test.db3] |
︙ | ︙ | |||
91 92 93 94 95 96 97 | db2 close db3 close } finish_test | < < < | 91 92 93 94 95 96 97 | db2 close db3 close } finish_test |
Changes to ext/recover/sqlite3recover.c.
︙ | ︙ | |||
359 360 361 362 363 364 365 | const char *zFmt, ... ){ char *z = 0; va_list ap; va_start(ap, zFmt); if( zFmt ){ z = sqlite3_vmprintf(zFmt, ap); | < > | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | const char *zFmt, ... ){ char *z = 0; va_list ap; va_start(ap, zFmt); if( zFmt ){ z = sqlite3_vmprintf(zFmt, ap); } va_end(ap); sqlite3_free(p->zErrMsg); p->zErrMsg = z; p->errCode = errCode; return errCode; } |
︙ | ︙ |
Changes to ext/recover/test_recover.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** */ #include "sqlite3recover.h" #include "sqliteInt.h" | < | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** */ #include "sqlite3recover.h" #include "sqliteInt.h" #include "tclsqlite.h" #include <assert.h> #ifndef SQLITE_OMIT_VIRTUALTABLE typedef struct TestRecover TestRecover; struct TestRecover { sqlite3_recover *p; |
︙ | ︙ | |||
304 305 306 307 308 309 310 | for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){ struct Cmd *p = &aCmd[i]; Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, p->pArg, 0); } #endif return TCL_OK; } | < | 303 304 305 306 307 308 309 | for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){ struct Cmd *p = &aCmd[i]; Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, p->pArg, 0); } #endif return TCL_OK; } |
Changes to ext/rtree/test_rtreedoc.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" #include "tclsqlite.h" /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" #ifdef SQLITE_ENABLE_RTREE typedef struct BoxGeomCtx BoxGeomCtx; |
︙ | ︙ | |||
86 87 88 89 90 91 92 | sqlite3_snprintf(sizeof(aPtr)-1, aPtr, "%p", (void*)p); Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(aPtr,-1)); rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc!=TCL_OK ){ rc = SQLITE_ERROR; }else{ | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | sqlite3_snprintf(sizeof(aPtr)-1, aPtr, "%p", (void*)p); Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(aPtr,-1)); rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc!=TCL_OK ){ rc = SQLITE_ERROR; }else{ Tcl_Size nObj = 0; Tcl_Obj **aObj = 0; pRes = Tcl_GetObjResult(interp); if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj) ) return TCL_ERROR; if( nObj>0 ){ const char *zCmd = Tcl_GetString(aObj[0]); if( 0==sqlite3_stricmp(zCmd, "zero") ){ |
︙ | ︙ | |||
275 276 277 278 279 280 281 | ); Tcl_ListObjAppendElement(interp, pEval, pArg); rc = Tcl_EvalObjEx(interp, pEval, 0) ? SQLITE_ERROR : SQLITE_OK; if( rc==SQLITE_OK ){ double rScore = 0.0; | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | ); Tcl_ListObjAppendElement(interp, pEval, pArg); rc = Tcl_EvalObjEx(interp, pEval, 0) ? SQLITE_ERROR : SQLITE_OK; if( rc==SQLITE_OK ){ double rScore = 0.0; Tcl_Size nObj = 0; int eP = 0; Tcl_Obj **aObj = 0; Tcl_Obj *pRes = Tcl_GetObjResult(interp); if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj) || nObj!=2 || Tcl_GetDoubleFromObj(interp, aObj[1], &rScore) |
︙ | ︙ |
Changes to ext/session/changesetfuzz1.test.
︙ | ︙ | |||
23 24 25 26 27 28 29 | if {$CF==""} { finish_test return } proc writefile {zFile data} { set fd [open $zFile w] | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | if {$CF==""} { finish_test return } proc writefile {zFile data} { set fd [open $zFile w] fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } do_execsql_test 1.0 { CREATE TABLE t1(a, b, c, d, PRIMARY KEY(c, d)); CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c); |
︙ | ︙ | |||
77 78 79 80 81 82 83 | forcecopy input.patchset-0 input.patchset } } } {} finish_test | < | 77 78 79 80 81 82 83 | forcecopy input.patchset-0 input.patchset } } } {} finish_test |
Changes to ext/session/session4.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2011 March 25 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for the session module. # | > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # 2011 March 25 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for the session module. # if {$tcl_version<8.6} { puts "This module requires Tcl 8.6 or later" return } if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl ifcapable !session {finish_test; return} |
︙ | ︙ | |||
132 133 134 135 136 137 138 | 54 540101743400120003001200010000000000000002120002400C000000000002120002400C00000000000050040100000074310017FF0050040100000074310017FF7F00000000000000050100000000000000030100000003001700010000666F7572 55 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000100010080000001000000020003010100000300170100000003001700010000666F7572 56 5487ffffff7f } { do_test 2.$tn { set changeset [binary decode hex $blob] #set fd [open x.change w+] | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | 54 540101743400120003001200010000000000000002120002400C000000000002120002400C00000000000050040100000074310017FF0050040100000074310017FF7F00000000000000050100000000000000030100000003001700010000666F7572 55 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000100010080000001000000020003010100000300170100000003001700010000666F7572 56 5487ffffff7f } { do_test 2.$tn { set changeset [binary decode hex $blob] #set fd [open x.change w+] #fconfigure $fd -translation binary #puts -nonewline $fd $changeset #close $fd list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg } {1 SQLITE_CORRUPT} } finish_test |
Changes to ext/session/sessiondiff.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 | dbtmp close md5 $txt } proc readfile {filename} { set fd [open $filename] | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | dbtmp close md5 $txt } proc readfile {filename} { set fd [open $filename] fconfigure $fd -translation binary set data [read $fd] close $fd set data } proc get_changeset {db1 db2} { exec $::PROG --changeset changeset.bin $db1 $db2 |
︙ | ︙ |
Changes to ext/session/sessionfault.test.
︙ | ︙ | |||
363 364 365 366 367 368 369 370 371 372 373 374 375 376 | faultsim_delete_and_reopen do_execsql_test 7.prep1 { CREATE TABLE t1(a, b, PRIMARY KEY(a)); } faultsim_save_and_close set res [list] for {set ::i 0} {$::i < 480} {incr ::i 4} { lappend res "INSERT t1 0 X. {} {i $::i i $::i}" } set res [lsort $res] do_faultsim_test 7 -faults oom-transient -prep { catch { S delete } | > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | faultsim_delete_and_reopen do_execsql_test 7.prep1 { CREATE TABLE t1(a, b, PRIMARY KEY(a)); } faultsim_save_and_close unset -nocomplain res set res [list] for {set ::i 0} {$::i < 480} {incr ::i 4} { lappend res "INSERT t1 0 X. {} {i $::i i $::i}" } set res [lsort $res] do_faultsim_test 7 -faults oom-transient -prep { catch { S delete } |
︙ | ︙ |
Changes to ext/session/test_session.c.
1 2 3 4 5 6 7 | #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_SESSION) \ && defined(SQLITE_ENABLE_PREUPDATE_HOOK) #include "sqlite3session.h" #include <assert.h> #include <string.h> | < < < | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_SESSION) \ && defined(SQLITE_ENABLE_PREUPDATE_HOOK) #include "sqlite3session.h" #include <assert.h> #include <string.h> #include "tclsqlite.h" #ifndef SQLITE_AMALGAMATION typedef unsigned char u8; #endif typedef struct TestSession TestSession; struct TestSession { |
︙ | ︙ | |||
513 514 515 516 517 518 519 | struct TestConflictHandler { Tcl_Interp *interp; Tcl_Obj *pConflictScript; Tcl_Obj *pFilterScript; }; static int test_obj_eq_string(Tcl_Obj *p, const char *z){ | | | | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | struct TestConflictHandler { Tcl_Interp *interp; Tcl_Obj *pConflictScript; Tcl_Obj *pFilterScript; }; static int test_obj_eq_string(Tcl_Obj *p, const char *z){ Tcl_Size n; Tcl_Size nObj; char *zObj; n = (Tcl_Size)strlen(z); zObj = Tcl_GetStringFromObj(p, &nObj); return (nObj==n && (n==0 || 0==memcmp(zObj, z, n))); } static int test_filter_handler( void *pCtx, /* Pointer to TestConflictHandler structure */ |
︙ | ︙ | |||
792 793 794 795 796 797 798 | int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; /* Database handle */ Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; /* Database handle */ Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ Tcl_Size nChangeset; /* Size of buffer aChangeset in bytes */ TestConflictHandler ctx; TestStreamInput sStr; void *pRebase = 0; int nRebase = 0; int flags = 0; /* Flags for apply_v2() */ memset(&sStr, 0, sizeof(sStr)); |
︙ | ︙ | |||
849 850 851 852 853 854 855 | pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); ctx.pConflictScript = objv[3]; ctx.pFilterScript = objc==5 ? objv[4] : 0; ctx.interp = interp; if( sStr.nStream==0 ){ if( bV2==0 ){ | | | | | 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); ctx.pConflictScript = objv[3]; ctx.pFilterScript = objc==5 ? objv[4] : 0; ctx.interp = interp; if( sStr.nStream==0 ){ if( bV2==0 ){ rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx ); }else{ rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset, (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx, &pRebase, &nRebase, flags ); } }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = (int)nChangeset; if( bV2==0 ){ rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx ); }else{ rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr, |
︙ | ︙ | |||
923 924 925 926 927 928 929 | int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; /* Database handle */ Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ | | | > > | > | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 | int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; /* Database handle */ Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ Tcl_Size nChangeset; /* Size of buffer aChangeset in bytes */ if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB CHANGESET"); return TCL_ERROR; } if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) ){ Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[2]), 0); return TCL_ERROR; } db = *(sqlite3 **)info.objClientData; pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, 0, replace_handler,0); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc, 0); } Tcl_ResetResult(interp); return TCL_OK; } /* ** sqlite3changeset_invert CHANGESET */ static int SQLITE_TCLAPI test_sqlite3changeset_invert( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ Tcl_Size nn; TestStreamInput sIn; /* Input stream */ TestSessionsBlob sOut; /* Output blob */ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANGESET"); return TCL_ERROR; } memset(&sIn, 0, sizeof(sIn)); memset(&sOut, 0, sizeof(sOut)); sIn.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); sIn.aData = Tcl_GetByteArrayFromObj(objv[1], &nn); sIn.nData = (int)nn; if( sIn.nStream ){ rc = sqlite3changeset_invert_strm( testStreamInput, (void*)&sIn, testStreamOutput, (void*)&sOut ); }else{ rc = sqlite3changeset_invert(sIn.nData, sIn.aData, &sOut.n, &sOut.p); |
︙ | ︙ | |||
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | static int SQLITE_TCLAPI test_sqlite3changeset_concat( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ TestStreamInput sLeft; /* Input stream */ TestStreamInput sRight; /* Input stream */ TestSessionsBlob sOut = {0,0}; /* Output blob */ if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "LEFT RIGHT"); return TCL_ERROR; } memset(&sLeft, 0, sizeof(sLeft)); memset(&sRight, 0, sizeof(sRight)); | > | > | > | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | static int SQLITE_TCLAPI test_sqlite3changeset_concat( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ Tcl_Size nn; TestStreamInput sLeft; /* Input stream */ TestStreamInput sRight; /* Input stream */ TestSessionsBlob sOut = {0,0}; /* Output blob */ if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "LEFT RIGHT"); return TCL_ERROR; } memset(&sLeft, 0, sizeof(sLeft)); memset(&sRight, 0, sizeof(sRight)); sLeft.aData = Tcl_GetByteArrayFromObj(objv[1], &nn); sLeft.nData = (int)nn; sRight.aData = Tcl_GetByteArrayFromObj(objv[2], &nn); sRight.nData = (int)nn; sLeft.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); sRight.nStream = sLeft.nStream; if( sLeft.nStream>0 ){ rc = sqlite3changeset_concat_strm( testStreamInput, (void*)&sLeft, testStreamInput, (void*)&sRight, |
︙ | ︙ | |||
1102 1103 1104 1105 1106 1107 1108 | static int SQLITE_TCLAPI test_sqlite3session_foreach( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *pChangeset; | | | 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 | static int SQLITE_TCLAPI test_sqlite3session_foreach( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *pChangeset; Tcl_Size nChangeset; sqlite3_changeset_iter *pIter; int rc; Tcl_Obj *pVarname; Tcl_Obj *pCS; Tcl_Obj *pScript; int isCheckNext = 0; int isInvert = 0; |
︙ | ︙ | |||
1144 1145 1146 1147 1148 1149 1150 | pScript = objv[3]; pChangeset = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeset); sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); if( isInvert ){ int f = SQLITE_CHANGESETSTART_INVERT; if( sStr.nStream==0 ){ | | | | | | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 | pScript = objv[3]; pChangeset = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeset); sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); if( isInvert ){ int f = SQLITE_CHANGESETSTART_INVERT; if( sStr.nStream==0 ){ rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, f); }else{ void *pCtx = (void*)&sStr; sStr.aData = (unsigned char*)pChangeset; sStr.nData = (int)nChangeset; rc = sqlite3changeset_start_v2_strm(&pIter, testStreamInput, pCtx, f); } }else{ if( sStr.nStream==0 ){ rc = sqlite3changeset_start(&pIter, (int)nChangeset, pChangeset); }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = (int)nChangeset; rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr); } } if( rc!=SQLITE_OK ){ return test_session_error(interp, rc, 0); } |
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 | return TCL_ERROR; } assert( iSub==0 || iSub==1 || iSub==2 ); assert( rc==SQLITE_OK ); switch( iSub ){ case 0: { /* configure */ | | | > | > | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 | return TCL_ERROR; } assert( iSub==0 || iSub==1 || iSub==2 ); assert( rc==SQLITE_OK ); switch( iSub ){ case 0: { /* configure */ Tcl_Size nRebase = 0; unsigned char *pRebase = Tcl_GetByteArrayFromObj(objv[2], &nRebase); rc = sqlite3rebaser_configure(p, (int)nRebase, pRebase); break; } case 1: /* delete */ Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); break; default: { /* rebase */ TestStreamInput sStr; /* Input stream */ TestSessionsBlob sOut; /* Output blob */ Tcl_Size nn; memset(&sStr, 0, sizeof(sStr)); memset(&sOut, 0, sizeof(sOut)); sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &nn); sStr.nData = nn; sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); if( sStr.nStream ){ rc = sqlite3rebaser_rebase_strm(p, testStreamInput, (void*)&sStr, testStreamOutput, (void*)&sOut ); |
︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 | static int SQLITE_TCLAPI test_changeset( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *pChangeset = 0; /* Buffer containing changeset */ | | | | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 | static int SQLITE_TCLAPI test_changeset( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *pChangeset = 0; /* Buffer containing changeset */ Tcl_Size nChangeset = 0; /* Size of buffer aChangeset in bytes */ int rc = SQLITE_OK; char *z = 0; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANGESET"); return TCL_ERROR; } pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeset); Tcl_ResetResult(interp); rc = sqlite3_test_changeset((int)nChangeset, pChangeset, &z); if( rc!=SQLITE_OK ){ char *zErr = sqlite3_mprintf("(%d) - \"%s\"", rc, z); Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); sqlite3_free(zErr); } sqlite3_free(z); |
︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 | } rc = sqlite3changegroup_schema(p->pGrp, db, zDb); if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); break; }; case 1: { /* add */ | | | | 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | } rc = sqlite3changegroup_schema(p->pGrp, db, zDb); if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); break; }; case 1: { /* add */ Tcl_Size nByte = 0; const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte); rc = sqlite3changegroup_add(p->pGrp, (int)nByte, (void*)aByte); if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); break; }; case 2: { /* output */ int nByte = 0; u8 *aByte = 0; |
︙ | ︙ | |||
1674 1675 1676 1677 1678 1679 1680 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int isInvert = 0; void *pChangeset = 0; /* Buffer containing changeset */ | | | | | | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int isInvert = 0; void *pChangeset = 0; /* Buffer containing changeset */ Tcl_Size nChangeset = 0; /* Size of buffer aChangeset in bytes */ TestChangeIter *pNew = 0; sqlite3_changeset_iter *pIter = 0; int flags = 0; int rc = SQLITE_OK; static int iCmd = 1; char zCmd[64]; if( objc==3 ){ Tcl_Size n = 0; const char *z = Tcl_GetStringFromObj(objv[1], &n); isInvert = (n>=2 && sqlite3_strnicmp(z, "-invert", (int)n)==0); } if( objc!=2 && (objc!=3 || !isInvert) ){ Tcl_WrongNumArgs(interp, 1, objv, "?-invert? CHANGESET"); return TCL_ERROR; } flags = isInvert ? SQLITE_CHANGESETSTART_INVERT : 0; pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[objc-1], &nChangeset); rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, flags); if( rc!=SQLITE_OK ){ char *zErr = sqlite3_mprintf( "error in sqlite3changeset_start_v2() - %d", rc ); Tcl_AppendResult(interp, zErr, (char*)0); return TCL_ERROR; } |
︙ | ︙ |
Changes to src/alter.c.
︙ | ︙ | |||
1316 1317 1318 1319 1320 1321 1322 | pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ | | | 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 | pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* 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)!=0; } /* Resolve symbols in WHEN clause */ if( rc==SQLITE_OK && pNew->pWhen ){ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); } |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
713 714 715 716 717 718 719 720 721 722 723 724 725 726 | } if( pRet ){ SelectDest dest; pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; pLeft->pPrior = 0; pLeft->op = TK_SELECT; assert( pLeft->pNext==0 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; p->pSelect = pLeft; p->fg.viaCoroutine = 1; | > | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | } if( pRet ){ SelectDest dest; 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 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; p->pSelect = pLeft; p->fg.viaCoroutine = 1; |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
528 529 530 531 532 533 534 | if( pLoop->pOrderBy || pLoop->pLimit ){ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", sqlite3SelectOpName(pNext->op)); break; } } | | | | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | if( pLoop->pOrderBy || pLoop->pLimit ){ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", sqlite3SelectOpName(pNext->op)); break; } } 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"); } } } /* Attach a With object describing the WITH clause to a Select |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 | return pNC->nNcErr>0 || w.pParse->nErr>0; } /* ** 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. */ int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ int i; int savedHasAgg = 0; Walker w; | > > > | | | | | 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 | return pNC->nNcErr>0 || w.pParse->nErr>0; } /* ** 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. */ ExprList *pList /* The expression list to be analyzed. */ ){ int i; int savedHasAgg = 0; Walker w; if( pList==0 ) return SQLITE_OK; w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; w.xSelectCallback2 = 0; w.u.pNC = pNC; savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); for(i=0; i<pList->nExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr==0 ) continue; #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ return SQLITE_ERROR; } #endif sqlite3WalkExprNN(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif assert( EP_Agg==NC_HasAgg ); assert( EP_Win==NC_HasWin ); testcase( pNC->ncFlags & NC_HasAgg ); testcase( pNC->ncFlags & NC_HasWin ); if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } if( w.pParse->nErr>0 ) return SQLITE_ERROR; } pNC->ncFlags |= savedHasAgg; return SQLITE_OK; } /* ** Resolve all names in all expressions of a SELECT and in all ** descendants of the SELECT, including compounds off of p->pPrior, ** subqueries in expressions, and subqueries used as FROM clause ** terms. |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 | }else if( sqlite3_strlike("_NAN", zVar, 0)==0 ){ sqlite3_bind_double(pStmt, i, NAN); #endif #ifdef INFINITY }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){ sqlite3_bind_double(pStmt, i, INFINITY); #endif }else{ sqlite3_bind_null(pStmt, i); } sqlite3_reset(pQ); } sqlite3_finalize(pQ); } | > > > > > > > > | 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 | }else if( sqlite3_strlike("_NAN", zVar, 0)==0 ){ sqlite3_bind_double(pStmt, i, NAN); #endif #ifdef INFINITY }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); } sqlite3_reset(pQ); } sqlite3_finalize(pQ); } |
︙ | ︙ | |||
11636 11637 11638 11639 11640 11641 11642 | int rc = SQLITE_OK; if( p->eRestoreState<7 ){ switch( p->eRestoreState ){ case 0: { const char *zExpect = "PRAGMA foreign_keys=OFF;"; assert( strlen(zExpect)==24 ); | | > > > | 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 | int rc = SQLITE_OK; if( p->eRestoreState<7 ){ switch( p->eRestoreState ){ case 0: { const char *zExpect = "PRAGMA foreign_keys=OFF;"; assert( strlen(zExpect)==24 ); if( p->bSafeMode==0 && strlen(zSql)>=24 && memcmp(zSql, zExpect, 25)==0 ){ p->eRestoreState = 1; }else{ p->eRestoreState = 7; } break; }; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 | /* ** Macros to compute aCol[] and aFunc[] register numbers. ** ** These macros should not be used prior to the call to ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications | > > > > > > | 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 | /* ** Macros to compute aCol[] and aFunc[] register numbers. ** ** These macros should not be used prior to the call to ** 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. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 38 | /* ** If requested, include the SQLite compiler options file for MSVC. */ #if defined(INCLUDE_MSVC_H) # include "msvc.h" #endif #if defined(INCLUDE_SQLITE_TCL_H) | > | | | > > > > > > > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* ** If requested, include the SQLite compiler options file for MSVC. */ #if defined(INCLUDE_MSVC_H) # include "msvc.h" #endif /****** Copy of tclsqlite.h ******/ #if defined(INCLUDE_SQLITE_TCL_H) # include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ #else # include <tcl.h> /* All normal cases */ # ifndef SQLITE_TCLAPI # define SQLITE_TCLAPI # endif #endif /* Compatability between Tcl8.6 and Tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define CONST const #else typedef int Tcl_Size; #endif /**** End copy of tclsqlite.h ****/ #include <errno.h> /* ** Some additional include files are needed if this file is not ** appended to the amalgamation. */ #ifndef SQLITE_AMALGAMATION |
︙ | ︙ | |||
205 206 207 208 209 210 211 | int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ | | > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ sqlite3_int64 iSeek; /* Current seek offset */ unsigned int isClosed; /* TCL_CLOSE_READ or TCL_CLOSE_WRITE */ Tcl_Channel channel; /* Channel identifier */ IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ }; /* ** Compute a string length that is limited to what can be stored in |
︙ | ︙ | |||
245 246 247 248 249 250 251 | Tcl_UnregisterChannel(pDb->interp, p->channel); } } /* ** Close an incremental blob channel. */ | | | > | > > > > > > > > > > > > > > > | | | | | | | | > > > > > > > | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | Tcl_UnregisterChannel(pDb->interp, p->channel); } } /* ** Close an incremental blob channel. */ static int SQLITE_TCLAPI incrblobClose2( ClientData instanceData, Tcl_Interp *interp, int flags ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; int rc; sqlite3 *db = p->pDb->db; if( flags ){ p->isClosed |= flags; return TCL_OK; } /* If we reach this point, then we really do need to close the channel */ rc = sqlite3_blob_close(p->pBlob); /* Remove the channel from the SqliteDb.pIncrblob list. */ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } if( p->pPrev ){ p->pPrev->pNext = p->pNext; } if( p->pDb->pIncrblob==p ){ p->pDb->pIncrblob = p->pNext; } /* Free the IncrblobChannel structure */ Tcl_Free((char *)p); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } static int SQLITE_TCLAPI incrblobClose( ClientData instanceData, Tcl_Interp *interp ){ return incrblobClose2(instanceData, interp, 0); } /* ** Read data from an incremental blob channel. */ static int SQLITE_TCLAPI incrblobInput( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; sqlite3_int64 nRead = bufSize; /* Number of bytes to read */ sqlite3_int64 nBlob; /* Total size of the blob */ int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nRead)>nBlob ){ nRead = nBlob-p->iSeek; } if( nRead<=0 ){ return 0; } rc = sqlite3_blob_read(p->pBlob, (void *)buf, (int)nRead, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = rc; return -1; } p->iSeek += nRead; return nRead; } /* ** Write data to an incremental blob channel. */ static int SQLITE_TCLAPI incrblobOutput( ClientData instanceData, CONST char *buf, int toWrite, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; sqlite3_int64 nWrite = toWrite; /* Number of bytes to write */ sqlite3_int64 nBlob; /* Total size of the blob */ int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nWrite)>nBlob ){ *errorCodePtr = EINVAL; return -1; } if( nWrite<=0 ){ return 0; } rc = sqlite3_blob_write(p->pBlob, (void*)buf,(int)nWrite, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = EIO; return -1; } p->iSeek += nWrite; return nWrite; } /* The datatype of Tcl_DriverWideSeekProc changes between tcl8.6 and tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define WideSeekProcType long long #else # define WideSeekProcType Tcl_WideInt #endif /* ** Seek an incremental blob channel. */ static WideSeekProcType SQLITE_TCLAPI incrblobWideSeek( ClientData instanceData, WideSeekProcType offset, int seekMode, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; switch( seekMode ){ case SEEK_SET: |
︙ | ︙ | |||
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | break; default: assert(!"Bad seekMode"); } return p->iSeek; } static void SQLITE_TCLAPI incrblobWatch( ClientData instanceData, int mode ){ /* NO-OP */ } static int SQLITE_TCLAPI incrblobHandle( ClientData instanceData, int dir, ClientData *hPtr ){ return TCL_ERROR; } static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ | > > > > > > > > | | | | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | break; default: assert(!"Bad seekMode"); } return p->iSeek; } static int SQLITE_TCLAPI incrblobSeek( ClientData instanceData, long offset, int seekMode, int *errorCodePtr ){ return incrblobWideSeek(instanceData,offset,seekMode,errorCodePtr); } static void SQLITE_TCLAPI incrblobWatch( ClientData instanceData, int mode ){ /* NO-OP */ } static int SQLITE_TCLAPI incrblobHandle( ClientData instanceData, int dir, ClientData *hPtr ){ return TCL_ERROR; } static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ TCL_CHANNEL_VERSION_5, /* version */ incrblobClose, /* closeProc */ incrblobInput, /* inputProc */ incrblobOutput, /* outputProc */ incrblobSeek, /* seekProc */ 0, /* setOptionProc */ 0, /* getOptionProc */ incrblobWatch, /* watchProc (this is a no-op) */ incrblobHandle, /* getHandleProc (always returns error) */ incrblobClose2, /* close2Proc */ 0, /* blockModeProc */ 0, /* flushProc */ 0, /* handlerProc */ incrblobWideSeek, /* wideSeekProc */ }; /* ** Create a new incrblob channel. */ static int createIncrblobChannel( Tcl_Interp *interp, |
︙ | ︙ | |||
429 430 431 432 433 434 435 | rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); | | > | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); memset(p, 0, sizeof(*p)); p->pBlob = pBlob; if( (flags & TCL_WRITABLE)==0 ) p->isClosed |= TCL_CLOSE_WRITE; sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); Tcl_RegisterChannel(interp, p->channel); /* Link the new channel into the SqliteDb.pIncrblob list. */ p->pNext = pDb->pIncrblob; |
︙ | ︙ | |||
470 471 472 473 474 475 476 | */ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ /* We could try to do something with Tcl_Parse(). But we will instead ** just do a search for forbidden characters. If any of the forbidden ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; | | | 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | */ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ /* We could try to do something with Tcl_Parse(). But we will instead ** just do a search for forbidden characters. If any of the forbidden ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; Tcl_Size n; z = Tcl_GetStringFromObj(pCmd, &n); while( n-- > 0 ){ int c = *(z++); if( c=='$' || c=='[' || c==';' ) return 0; } return 1; } |
︙ | ︙ | |||
977 978 979 980 981 982 983 | ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; | | | 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; Tcl_Size nArg; if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; } pCmd = Tcl_NewListObj(nArg, aArg); Tcl_IncrRefCount(pCmd); for(i=0; i<argc; i++){ |
︙ | ︙ | |||
1040 1041 1042 1043 1044 1045 1046 | Tcl_DecrRefCount(pCmd); } if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); | | | 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 | Tcl_DecrRefCount(pCmd); } if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; int eType = p->eType; if( eType==SQLITE_NULL ){ if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ |
︙ | ︙ | |||
1451 1452 1453 1454 1455 1456 1457 | rc = TCL_ERROR; break; }else{ pVar = 0; } } if( pVar ){ | | > | | | 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | rc = TCL_ERROR; break; }else{ pVar = 0; } } if( pVar ){ Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); c = zType[0]; if( zVar[0]=='@' || (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ /* Load a BLOB type if the Tcl variable is a bytearray and ** it has no string representation or the host ** parameter name begins with "@". */ data = Tcl_GetByteArrayFromObj(pVar, &n); sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; }else if( c=='b' && strcmp(zType,"boolean")==0 ){ int nn; Tcl_GetIntFromObj(interp, pVar, &nn); sqlite3_bind_int(pStmt, i, nn); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); sqlite3_bind_double(pStmt, i, r); }else if( (c=='w' && strcmp(zType,"wideInt")==0) || (c=='i' && strcmp(zType,"int")==0) ){ Tcl_WideInt v; |
︙ | ︙ | |||
2030 2031 2032 2033 2034 2035 2036 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zAuth ){ Tcl_AppendResult(interp, pDb->zAuth, (char*)0); } }else{ char *zAuth; | | | 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zAuth ){ Tcl_AppendResult(interp, pDb->zAuth, (char*)0); } }else{ char *zAuth; Tcl_Size len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } zAuth = Tcl_GetStringFromObj(objv[2], &len); if( zAuth && len>0 ){ pDb->zAuth = Tcl_Alloc( len + 1 ); memcpy(pDb->zAuth, zAuth, len+1); |
︙ | ︙ | |||
2133 2134 2135 2136 2137 2138 2139 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBindFallback ){ Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); } }else{ char *zCallback; | | | 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBindFallback ){ Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); } }else{ char *zCallback; Tcl_Size len; if( pDb->zBindFallback ){ Tcl_Free(pDb->zBindFallback); } zCallback = Tcl_GetStringFromObj(objv[2], &len); if( zCallback && len>0 ){ pDb->zBindFallback = Tcl_Alloc( len + 1 ); memcpy(pDb->zBindFallback, zCallback, len+1); |
︙ | ︙ | |||
2163 2164 2165 2166 2167 2168 2169 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBusy ){ Tcl_AppendResult(interp, pDb->zBusy, (char*)0); } }else{ char *zBusy; | | | 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBusy ){ Tcl_AppendResult(interp, pDb->zBusy, (char*)0); } }else{ char *zBusy; Tcl_Size len; if( pDb->zBusy ){ Tcl_Free(pDb->zBusy); } zBusy = Tcl_GetStringFromObj(objv[2], &len); if( zBusy && len>0 ){ pDb->zBusy = Tcl_Alloc( len + 1 ); memcpy(pDb->zBusy, zBusy, len+1); |
︙ | ︙ | |||
2270 2271 2272 2273 2274 2275 2276 | ** Create a new SQL collation function called NAME. Whenever ** that function is called, invoke SCRIPT to evaluate the function. */ case DB_COLLATE: { SqlCollate *pCollate; char *zName; char *zScript; | | | 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 | ** Create a new SQL collation function called NAME. Whenever ** that function is called, invoke SCRIPT to evaluate the function. */ case DB_COLLATE: { SqlCollate *pCollate; char *zName; char *zScript; Tcl_Size nScript; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); return TCL_ERROR; } zName = Tcl_GetStringFromObj(objv[2], 0); zScript = Tcl_GetStringFromObj(objv[3], &nScript); pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); |
︙ | ︙ | |||
2329 2330 2331 2332 2333 2334 2335 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zCommit ){ Tcl_AppendResult(interp, pDb->zCommit, (char*)0); } }else{ const char *zCommit; | | | 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zCommit ){ Tcl_AppendResult(interp, pDb->zCommit, (char*)0); } }else{ const char *zCommit; Tcl_Size len; if( pDb->zCommit ){ Tcl_Free(pDb->zCommit); } zCommit = Tcl_GetStringFromObj(objv[2], &len); if( zCommit && len>0 ){ pDb->zCommit = Tcl_Alloc( len + 1 ); memcpy(pDb->zCommit, zCommit, len+1); |
︙ | ︙ | |||
2649 2650 2651 2652 2653 2654 2655 | (char*)0); rc = TCL_ERROR; #else const char *zSchema = 0; Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; | > | | 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 | (char*)0); rc = TCL_ERROR; #else const char *zSchema = 0; Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; Tcl_Size len; int xrc; sqlite3_int64 mxSize = 0; int i; int isReadonly = 0; if( objc<3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); |
︙ | ︙ | |||
3020 3021 3022 3023 3024 3025 3026 | */ case DB_NULLVALUE: { if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); return TCL_ERROR; } if( objc==3 ){ | | | 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 | */ case DB_NULLVALUE: { if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); return TCL_ERROR; } if( objc==3 ){ Tcl_Size len; char *zNull = Tcl_GetStringFromObj(objv[2], &len); if( pDb->zNull ){ Tcl_Free(pDb->zNull); } if( zNull && len>0 ){ pDb->zNull = Tcl_Alloc( len + 1 ); memcpy(pDb->zNull, zNull, len); |
︙ | ︙ | |||
3074 3075 3076 3077 3078 3079 3080 | Tcl_AppendResult(interp, pDb->zProgress, (char*)0); } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK sqlite3_progress_handler(pDb->db, 0, 0, 0); #endif }else if( objc==4 ){ char *zProgress; | | | 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 | Tcl_AppendResult(interp, pDb->zProgress, (char*)0); } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK sqlite3_progress_handler(pDb->db, 0, 0, 0); #endif }else if( objc==4 ){ char *zProgress; Tcl_Size len; int N; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ return TCL_ERROR; }; if( pDb->zProgress ){ Tcl_Free(pDb->zProgress); } |
︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zProfile ){ Tcl_AppendResult(interp, pDb->zProfile, (char*)0); } }else{ char *zProfile; | | | 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zProfile ){ Tcl_AppendResult(interp, pDb->zProfile, (char*)0); } }else{ char *zProfile; Tcl_Size len; if( pDb->zProfile ){ Tcl_Free(pDb->zProfile); } zProfile = Tcl_GetStringFromObj(objv[2], &len); if( zProfile && len>0 ){ pDb->zProfile = Tcl_Alloc( len + 1 ); memcpy(pDb->zProfile, zProfile, len+1); |
︙ | ︙ | |||
3331 3332 3333 3334 3335 3336 3337 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTrace ){ Tcl_AppendResult(interp, pDb->zTrace, (char*)0); } }else{ char *zTrace; | | | 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTrace ){ Tcl_AppendResult(interp, pDb->zTrace, (char*)0); } }else{ char *zTrace; Tcl_Size len; if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } zTrace = Tcl_GetStringFromObj(objv[2], &len); if( zTrace && len>0 ){ pDb->zTrace = Tcl_Alloc( len + 1 ); memcpy(pDb->zTrace, zTrace, len+1); |
︙ | ︙ | |||
3371 3372 3373 3374 3375 3376 3377 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTraceV2 ){ Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); } }else{ char *zTraceV2; | | | 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 | return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTraceV2 ){ Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); } }else{ char *zTraceV2; Tcl_Size len; Tcl_WideInt wMask = 0; if( objc==4 ){ static const char *TTYPE_strs[] = { "statement", "profile", "row", "close", 0 }; enum TTYPE_enum { TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE |
︙ | ︙ | |||
3957 3958 3959 3960 3961 3962 3963 | /* Because it accesses the file-system and uses persistent state, SQLite ** is not considered appropriate for safe interpreters. Hence, we cause ** the _SafeInit() interfaces return TCL_ERROR. */ EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} | | | | > > > > > | | | | > > | > > > > | 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 | /* Because it accesses the file-system and uses persistent state, SQLite ** is not considered appropriate for safe interpreters. Hence, we cause ** the _SafeInit() interfaces return TCL_ERROR. */ EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} /* ** Versions of all of the above entry points that omit the "3" at the end ** of the name. Years ago (circa 2004) the "3" was necessary to distinguish ** SQLite version 3 from Sqlite version 2. But two decades have elapsed. ** SQLite2 is not longer a conflict. So it is ok to omit the "3". ** ** Omitting the "3" helps TCL find the entry point. */ EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} /* Also variants with a lowercase "s" */ EXTERN int sqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} /* ** If the TCLSH macro is defined, add code to make a stand-alone program. */ #if defined(TCLSH) /* This is the main routine for an ordinary TCL shell. If there are |
︙ | ︙ |
Added src/tclsqlite.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* ** 2024-07-30 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface to TCL as used by SQLite. ** SQLite subcomponents that use TCL (the libsqlite3.c interface library ** and various test*.c pieces) should #include this file rather than ** including tcl.h directly. */ /****** Any edits to this file must mirrored in tclsqlite.c ***********/ /* When compiling for Windows using STDCALL instead of CDECL calling ** conventions, the MSVC makefile has to build a customized version of ** the "tcl.h" header that specifies the calling conventions for each ** interface. That customized "tcl.h" is named "sqlite_tcl.h". */ #if defined(INCLUDE_SQLITE_TCL_H) # include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ #else # include <tcl.h> /* All normal cases */ # ifndef SQLITE_TCLAPI # define SQLITE_TCLAPI # endif #endif /****** Any edits to this file must mirrored in tclsqlite.c ***********/ /* Compatability between Tcl8.6 and Tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define CONST const #else typedef int Tcl_Size; #endif /****** Any edits to this file must mirrored in tclsqlite.c ***********/ |
Changes to src/test1.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | # if defined(__APPLE__) # include <sys/param.h> # include <sys/sysctl.h> # endif #endif #include "vdbeInt.h" | < < < | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # if defined(__APPLE__) # include <sys/param.h> # include <sys/sysctl.h> # endif #endif #include "vdbeInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> /* ** This is a copy of the first part of the SqliteDb structure in ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine ** can extract the sqlite3* pointer from an existing Tcl SQLite |
︙ | ︙ | |||
1768 1769 1770 1771 1772 1773 1774 | static int SQLITE_TCLAPI blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob ){ char *z; | | | 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 | static int SQLITE_TCLAPI blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob ){ char *z; Tcl_Size n; z = Tcl_GetStringFromObj(pObj, &n); if( n==0 ){ *ppBlob = 0; }else{ int notUsed; Tcl_Channel channel; |
︙ | ︙ | |||
2335 2336 2337 2338 2339 2340 2341 | } aTbl[] = { {"complex", SQLITE_SCANSTAT_COMPLEX}, {"debug", -1}, {0, 0} }; Tcl_Obj **aFlag = 0; | | | | 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 | } aTbl[] = { {"complex", SQLITE_SCANSTAT_COMPLEX}, {"debug", -1}, {0, 0} }; Tcl_Obj **aFlag = 0; Tcl_Size nFlag = 0; int ii; if( Tcl_ListObjGetElements(interp, objv[2], &nFlag, &aFlag) ){ return TCL_ERROR; } for(ii=0; ii<(int)nFlag; ii++){ int iVal = 0; int res = Tcl_GetIndexFromObjStruct( interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal ); if( res ) return TCL_ERROR; if( aTbl[iVal].flag==-1 ){ bDebug = 1; |
︙ | ︙ | |||
2762 2763 2764 2765 2766 2767 2768 | int objc, Tcl_Obj *CONST objv[] ){ int rc; sqlite3 *db; char *zName; unsigned char *pBlob; | | | 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 | int objc, Tcl_Obj *CONST objv[] ){ int rc; sqlite3 *db; char *zName; unsigned char *pBlob; Tcl_Size nBlob; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zName = Tcl_GetString(objv[2]); |
︙ | ︙ | |||
2797 2798 2799 2800 2801 2802 2803 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int res; unsigned char *p1; unsigned char *p2; | | | | 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int res; unsigned char *p1; unsigned char *p2; Tcl_Size n1; Tcl_Size n2; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); return TCL_ERROR; } p1 = Tcl_GetByteArrayFromObj(objv[1], &n1); |
︙ | ︙ | |||
4098 4099 4100 4101 4102 4103 4104 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; int idx; | | | 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; int idx; Tcl_Size trueLength = 0; int bytes; char *value; int rc; char *toFree = 0; if( objc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", |
︙ | ︙ | |||
4156 4157 4158 4159 4160 4161 4162 | #ifndef SQLITE_OMIT_UTF16 sqlite3_stmt *pStmt; int idx; int bytes; char *value; char *toFree = 0; int rc; | | | 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 | #ifndef SQLITE_OMIT_UTF16 sqlite3_stmt *pStmt; int idx; int bytes; char *value; char *toFree = 0; int rc; Tcl_Size trueLength = 0; void (*xDel)(void*) = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT); Tcl_Obj *oStmt = objv[objc-4]; Tcl_Obj *oN = objv[objc-3]; Tcl_Obj *oString = objv[objc-2]; Tcl_Obj *oBytes = objv[objc-1]; |
︙ | ︙ | |||
4210 4211 4212 4213 4214 4215 4216 | static int SQLITE_TCLAPI test_bind_blob( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; | > | | 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 | static int SQLITE_TCLAPI test_bind_blob( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; Tcl_Size len; int idx; int bytes; char *value; int rc; sqlite3_destructor_type xDestructor = SQLITE_TRANSIENT; if( objc!=5 && objc!=6 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", |
︙ | ︙ | |||
4236 4237 4238 4239 4240 4241 4242 | value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len); if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; if( bytes>len ){ char zBuf[200]; sqlite3_snprintf(sizeof(zBuf), zBuf, | | | 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 | value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len); if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; if( bytes>len ){ char zBuf[200]; sqlite3_snprintf(sizeof(zBuf), zBuf, "cannot use %d blob bytes, have %d", bytes, (int)len); Tcl_AppendResult(interp, zBuf, (char*)0); return TCL_ERROR; } rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor); if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
4534 4535 4536 4537 4538 4539 4540 | aData = a; break; } case 4: { /* BLOB */ struct iovec *a = sqlite3_malloc( sizeof(struct iovec)*nData ); if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; } for(j=0; j<nData; j++){ | | | | 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 | aData = a; break; } case 4: { /* BLOB */ struct iovec *a = sqlite3_malloc( sizeof(struct iovec)*nData ); if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; } for(j=0; j<nData; j++){ Tcl_Size n = 0; unsigned char *v = Tcl_GetByteArrayFromObj(objv[i+i], &n); a[j].iov_len = (size_t)n; a[j].iov_base = sqlite3_malloc64( n ); if( a[j].iov_base==0 ){ a[j].iov_len = 0; }else{ memcpy(a[j].iov_base, v, n); } } |
︙ | ︙ | |||
5112 5113 5114 5115 5116 5117 5118 | const void *zSql; const void *zTail = 0; Tcl_Obj *pTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ | | | 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 | const void *zSql; const void *zTail = 0; Tcl_Obj *pTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ Tcl_Size objlen; /* The byte-array length of arg 2 */ if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
︙ | ︙ | |||
5172 5173 5174 5175 5176 5177 5178 | const void *zSql; const void *zTail = 0; Tcl_Obj *pTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ | | | 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 | const void *zSql; const void *zTail = 0; Tcl_Obj *pTail = 0; sqlite3_stmt *pStmt = 0; char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ Tcl_Size objlen; /* The byte-array length of arg 2 */ if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
︙ | ︙ | |||
5252 5253 5254 5255 5256 5257 5258 | const char *zFilename; const char *zVfs; int flags = 0; sqlite3 *db; int rc; char zBuf[100]; | | | | 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 | const char *zFilename; const char *zVfs; int flags = 0; sqlite3 *db; int rc; char zBuf[100]; Tcl_Size nFlag; Tcl_Obj **apFlag; Tcl_Size i; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS"); return TCL_ERROR; } zFilename = Tcl_GetString(objv[1]); zVfs = Tcl_GetString(objv[3]); |
︙ | ︙ | |||
5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 | pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); if( pVar==0 ) return TCL_ERROR; if( pVar->typePtr ){ Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); } return TCL_OK; } /* ** Usage: sqlite3_release_memory ?N? ** ** Attempt to release memory currently held but not actually required. ** The integer N is the number of bytes we are trying to release. The ** return value is the amount of memory actually released. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 | pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); if( pVar==0 ) return TCL_ERROR; if( pVar->typePtr ){ Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); } return TCL_OK; } #include <ctype.h> /* ** Usage: fpnum_compare STRING1 STRING2 ** ** Compare two strings. Return true if the strings are the same and ** false if they differ. ** ** For this comparison, the strings are analyzed as a sequenced of ** whitespace separated tokens. The whitespace is ignored. Only the ** tokens are compared. Comparison rules: ** ** A. Tokens that are not floating-point numbers must match exactly. ** ** B. Floating point number must have exactly the same digits before ** the decimal point. ** ** C. Digits must match after the decimal point up to 15 digits, ** taking rounding into consideration. ** ** D. An exponent on a floating point of the form "e+NN" will ** match "e+N" if NN==N. Likewise for the negative exponent. ** ** This routine is used for comparing results that might involve floating ** point values. Tcl9.0 and Tcl8.6 differ in the number of significant ** digits that they show, so there is no way to write a portable test result ** without this routine. ** ** This routine is only called after [string compare] fails, which is seldom, ** so performance is not a pressing concern. Better to get the correct answer ** slowly. */ static int SQLITE_TCLAPI fpnum_compare( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ const unsigned char *zA; const unsigned char *zB; int i, j; int nDigit; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "STRING1 STRING2"); return TCL_ERROR; } zA = (const unsigned char*)Tcl_GetString(objv[1]); zB = (const unsigned char*)Tcl_GetString(objv[2]); i = j = 0; while( 1 ){ /* Skip whitespace before and after tokens */ while( isspace(zA[i]) ){ i++; } while( isspace(zB[j]) ){ j++; } if( zA[i]!=zB[j] ) break; /* First character must match */ if( zA[i]=='-' && isdigit(zA[i+1]) ){ i++; j++; } /* Skip initial '-' */ if( !isdigit(zA[i]) ){ /* Not a number. Must match exactly */ while( !isspace(zA[i]) && zA[i] && zA[i]==zB[j] ){ i++; j++; } if( zA[i]!=zB[j] ) break; if( isspace(zA[i]) ) continue; break; } /* At this point we know we are dealing with a number zA[i] and zB[j] ** are both digits (leading "-" have been skipped). See if they are ** the same number. Start by matching digits before the decimal ** point, which must all be the same. */ nDigit = 0; while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; nDigit++; } if( zA[i]!=zB[j] ) break; if( zA[i]==0 ) break; if( zA[i]=='.' && zB[j]=='.' ){ /* Count more matching digits after the decimal point */ i++; j++; while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; nDigit++; } if( zA[i]==0 ){ while( zB[j]=='0' || (isdigit(zB[j]) && nDigit>=15) ){ j++; nDigit++; } break; } if( zB[j]==0 ){ while( zA[i]=='0' || (isdigit(zA[i]) && nDigit>=15) ){ i++; nDigit++; } break; } if( isspace(zA[i]) && isspace(zB[j]) ) continue; if( isdigit(zA[i]) && isdigit(zB[j]) ){ /* A and B are both digits, but different digits */ if( zA[i]==zB[j]+1 && !isdigit(zA[i+1]) && isdigit(zB[j+1]) ){ /* Is A a rounded up version of B? */ j++; while( zB[j]=='9' ){ j++; nDigit++; } if( nDigit<14 && (!isdigit(zB[j]) || zB[j]<5) ) break; while( isdigit(zB[j]) ){ j++; } i++; }else if( zB[j]==zA[i]+1 && !isdigit(zB[j+1]) && isdigit(zA[i+1]) ){ /* Is B a rounded up version of A? */ i++; while( zA[i]=='9' ){ i++; nDigit++; } if( nDigit<14 && (!isdigit(zA[i]) || zA[i]<5) ) break; while( isdigit(zA[i]) ){ i++; } j++; }else{ break; } }else if( !isdigit(zA[i]) && isdigit(zB[j]) ){ while( zB[j]=='0' ){ j++; nDigit++; } if( nDigit<15 ) break; while( isdigit(zB[j]) ){ j++; } }else if( !isdigit(zB[j]) && isdigit(zA[i]) ){ while( zA[i]=='0' ){ i++; nDigit++; } if( nDigit<15 ) break; while( isdigit(zA[i]) ){ i++; } }else{ break; } } if( zA[i]=='e' && zB[j]=='e' ){ i++; j++; if( (zA[i]=='+' || zA[i]=='-') && zB[j]==zA[i] ){ i++; j++; } if( zA[i]!=zB[j] ){ if( zA[i]=='0' && zA[i+1]==zB[j] ){ i++; } if( zB[j]=='0' && zB[j+1]==zA[i] ){ j++; } } while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; } if( zA[i]!=zB[j] ) break; if( zA[i]==0 ) break; continue; } } while( isspace(zA[i]) ){ i++; } while( isspace(zB[j]) ){ j++; } Tcl_SetObjResult(interp, Tcl_NewIntObj(zA[i]==0 && zB[j]==0)); return TCL_OK; } /* ** Usage: sqlite3_release_memory ?N? ** ** Attempt to release memory currently held but not actually required. ** The integer N is the number of bytes we are trying to release. The ** return value is the amount of memory actually released. |
︙ | ︙ | |||
6651 6652 6653 6654 6655 6656 6657 | # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) { char *testPath; int rc; | | | 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 | # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) { char *testPath; int rc; Tcl_Size nPwd; const char *zPwd; char proxyPath[400]; zPwd = Tcl_GetStringFromObj(objv[2], &nPwd); if( sizeof(proxyPath)<nPwd+20 ){ Tcl_AppendResult(interp, "PWD too big", (void*)0); return TCL_ERROR; |
︙ | ︙ | |||
7921 7922 7923 7924 7925 7926 7927 | Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0); CloseHandle(ev); return TCL_ERROR; } CloseHandle(ev); return TCL_OK; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 | Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0); CloseHandle(ev); return TCL_ERROR; } CloseHandle(ev); return TCL_OK; } #endif /* ** optimization_control DB OPT BOOLEAN ** ** Enable or disable query optimizations using the sqlite3_test_control() |
︙ | ︙ | |||
8323 8324 8325 8326 8327 8328 8329 | rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0); if( rc!=SQLITE_OK ) goto sql_error; iB = sqlite3_column_count(pStmt)-1; for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){ int a = sqlite3_column_int(pStmt, 0); if( a!=sqlite3_column_int(pStmt, iB) ){ | | | | | | | | | | | 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 | rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0); if( rc!=SQLITE_OK ) goto sql_error; iB = sqlite3_column_count(pStmt)-1; for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){ int a = sqlite3_column_int(pStmt, 0); if( a!=sqlite3_column_int(pStmt, iB) ){ Tcl_AppendResult(interp, "data error: (a!=b)", (void*)0); return TCL_ERROR; } iCksum1 += (iCksum1 << 3) + (unsigned int)a; } rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ) goto sql_error; rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0); if( rc!=SQLITE_OK ) goto sql_error; for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){ int a = sqlite3_column_int(pStmt, 0); iCksum2 += (iCksum2 << 3) + (unsigned int)a; } rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ) goto sql_error; if( iCksum1!=iCksum2 ){ Tcl_AppendResult(interp, "checksum mismatch", (void*)0); return TCL_ERROR; } return TCL_OK; sql_error: Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), (void*)0); return TCL_ERROR; } #ifdef SQLITE_USER_AUTHENTICATION #include "sqlite3userauth.h" /* ** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD */ static int SQLITE_TCLAPI test_user_authenticate( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ char *zUser = 0; char *zPasswd = 0; Tcl_Size nPasswd = 0; sqlite3 *db; int rc; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } zUser = Tcl_GetString(objv[2]); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); rc = sqlite3_user_authenticate(db, zUser, zPasswd, (int)nPasswd); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } #endif /* SQLITE_USER_AUTHENTICATION */ #ifdef SQLITE_USER_AUTHENTICATION /* ** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN */ static int SQLITE_TCLAPI test_user_add( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ char *zUser = 0; char *zPasswd = 0; Tcl_Size nPasswd = 0; int isAdmin = 0; sqlite3 *db; int rc; if( objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } zUser = Tcl_GetString(objv[2]); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); rc = sqlite3_user_add(db, zUser, zPasswd, (int)nPasswd, isAdmin); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } #endif /* SQLITE_USER_AUTHENTICATION */ #ifdef SQLITE_USER_AUTHENTICATION /* ** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN */ static int SQLITE_TCLAPI test_user_change( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ char *zUser = 0; char *zPasswd = 0; Tcl_Size nPasswd = 0; int isAdmin = 0; sqlite3 *db; int rc; if( objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } zUser = Tcl_GetString(objv[2]); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); rc = sqlite3_user_change(db, zUser, zPasswd, (int)nPasswd, isAdmin); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } #endif /* SQLITE_USER_AUTHENTICATION */ #ifdef SQLITE_USER_AUTHENTICATION /* |
︙ | ︙ | |||
8729 8730 8731 8732 8733 8734 8735 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db = 0; Tcl_WideInt iOff = 0; const unsigned char *aData = 0; | | | | 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db = 0; Tcl_WideInt iOff = 0; const unsigned char *aData = 0; Tcl_Size nData = 0; sqlite3_file *pFile = 0; int rc; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB OFFSET DATA"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; if( Tcl_GetWideIntFromObj(interp, objv[2], &iOff) ) return TCL_ERROR; aData = Tcl_GetByteArrayFromObj(objv[3], &nData); sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFile); rc = pFile->pMethods->xWrite(pFile, aData, (int)(nData&0x7fffffff), iOff); Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); return TCL_OK; } /* ** Usage: sqlite3_register_cksumvfs |
︙ | ︙ | |||
9154 9155 9156 9157 9158 9159 9160 | { "extra_schema_checks", extra_schema_checks, 0}, { "use_long_double", use_long_double, 0}, { "database_never_corrupt", database_never_corrupt, 0}, { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, | < < < < < | 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 | { "extra_schema_checks", extra_schema_checks, 0}, { "use_long_double", use_long_double, 0}, { "database_never_corrupt", database_never_corrupt, 0}, { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, #endif { "tcl_objproc", runAsObjProc, 0 }, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, |
︙ | ︙ | |||
9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 | { "add_test_collate", test_collate, 0 }, { "add_test_collate_needed", test_collate_needed, 0 }, { "add_test_function", test_function, 0 }, { "add_test_utf16bin_collate", test_utf16bin_collate, 0 }, #endif { "sqlite3_test_errstr", test_errstr, 0 }, { "tcl_variable_type", tcl_variable_type, 0 }, #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #ifndef SQLITE_OMIT_INCRBLOB | > | 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 | { "add_test_collate", test_collate, 0 }, { "add_test_collate_needed", test_collate_needed, 0 }, { "add_test_function", test_function, 0 }, { "add_test_utf16bin_collate", test_utf16bin_collate, 0 }, #endif { "sqlite3_test_errstr", test_errstr, 0 }, { "tcl_variable_type", tcl_variable_type, 0 }, { "fpnum_compare", fpnum_compare, 0 }, #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #ifndef SQLITE_OMIT_INCRBLOB |
︙ | ︙ |
Changes to src/test2.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <ctype.h> extern const char *sqlite3ErrName(int); /* |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" #include "btreeInt.h" | < < < | < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" #include "btreeInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> extern const char *sqlite3ErrName(int); /* ** A bogus sqlite3 connection structure for use in the btree |
︙ | ︙ | |||
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ){ BtCursor *pCur; int rc; BtreePayload x; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE"); return TCL_ERROR; } memset(&x, 0, sizeof(x)); if( objc==4 ){ if( Tcl_GetIntFromObj(interp, objv[2], &rc) ) return TCL_ERROR; x.nKey = rc; | > | > | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ){ BtCursor *pCur; int rc; BtreePayload x; Tcl_Size n; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE"); return TCL_ERROR; } memset(&x, 0, sizeof(x)); if( objc==4 ){ if( Tcl_GetIntFromObj(interp, objv[2], &rc) ) return TCL_ERROR; x.nKey = rc; x.pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &n); x.nData = (int)n; }else{ x.pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &n); x.nKey = (int)n; } pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3_mutex_enter(pCur->pBtree->db->mutex); sqlite3BtreeEnter(pCur->pBtree); rc = sqlite3BtreeInsert(pCur, &x, 0, 0); sqlite3BtreeLeave(pCur->pBtree); |
︙ | ︙ |
Changes to src/test4.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the SQLite library in a multithreaded environment. */ #include "sqliteInt.h" | < < < | < | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the SQLite library in a multithreaded environment. */ #include "sqliteInt.h" #include "tclsqlite.h" #if SQLITE_OS_UNIX && SQLITE_THREADSAFE #include <stdlib.h> #include <string.h> #include <pthread.h> #include <sched.h> #include <ctype.h> |
︙ | ︙ |
Changes to src/test5.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. Specifically, the code in this file ** is used for testing the SQLite routines for converting between ** the various supported unicode encodings. */ #include "sqliteInt.h" #include "vdbeInt.h" | < < < | < | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. Specifically, the code in this file ** is used for testing the SQLite routines for converting between ** the various supported unicode encodings. */ #include "sqliteInt.h" #include "vdbeInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> /* ** The first argument is a TCL UTF-8 string. Return the byte array ** object with the encoded representation of the string, including ** the NULL terminator. */ static int SQLITE_TCLAPI binarize( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Size len; char *bytes; Tcl_Obj *pRet; assert(objc==2); bytes = Tcl_GetStringFromObj(objv[1], &len); pRet = Tcl_NewByteArrayObj((u8*)bytes, len+1); Tcl_SetObjResult(interp, pRet); |
︙ | ︙ | |||
129 130 131 132 133 134 135 | Tcl_Obj *CONST objv[] ){ u8 enc_from; u8 enc_to; sqlite3_value *pVal; char *z; | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | Tcl_Obj *CONST objv[] ){ u8 enc_from; u8 enc_to; sqlite3_value *pVal; char *z; Tcl_Size len; void (*xDel)(void *p) = SQLITE_STATIC; if( objc!=4 && objc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " <string/blob> <from enc> <to enc>", 0 ); |
︙ | ︙ | |||
160 161 162 163 164 165 166 | z = sqlite3_mprintf("%s", z); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); }else{ z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); if( objc==5 ){ char *zTmp = z; | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | z = sqlite3_mprintf("%s", z); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); }else{ z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); if( objc==5 ){ char *zTmp = z; z = sqlite3_malloc64(len); memcpy(z, zTmp, len); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); } z = (char *)sqlite3ValueText(pVal, enc_to); len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2); |
︙ | ︙ |
Changes to src/test6.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** ** This file contains code that modified the OS layer in order to simulate ** the effect on the database file of an OS crash or power failure. This ** is used to test the ability of SQLite to recover from those situations. */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqliteInt.h" | < < < | < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This file contains code that modified the OS layer in order to simulate ** the effect on the database file of an OS crash or power failure. This ** is used to test the ability of SQLite to recover from those situations. */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqliteInt.h" #include "tclsqlite.h" #ifndef SQLITE_OMIT_DISKIO /* This file is a no-op if disk I/O is disabled */ /* #define TRACE_CRASHTEST */ typedef struct CrashFile CrashFile; typedef struct CrashGlobal CrashGlobal; |
︙ | ︙ | |||
747 748 749 750 751 752 753 | int i; int iDc = 0; int iSectorSize = 0; int setSectorsize = 0; int setDeviceChar = 0; for(i=0; i<objc; i+=2){ | | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 | int i; int iDc = 0; int iSectorSize = 0; int setSectorsize = 0; int setDeviceChar = 0; for(i=0; i<objc; i+=2){ Tcl_Size nOpt; char *zOpt = Tcl_GetStringFromObj(objv[i], &nOpt); if( (nOpt>11 || nOpt<2 || strncmp("-sectorsize", zOpt, nOpt)) && (nOpt>16 || nOpt<2 || strncmp("-characteristics", zOpt, nOpt)) ){ Tcl_AppendResult(interp, "Bad option: \"", zOpt, |
︙ | ︙ | |||
772 773 774 775 776 777 778 | if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){ return TCL_ERROR; } setSectorsize = 1; }else{ int j; Tcl_Obj **apObj; | | | | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){ return TCL_ERROR; } setSectorsize = 1; }else{ int j; Tcl_Obj **apObj; Tcl_Size nObj; if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){ return TCL_ERROR; } for(j=0; j<(int)nObj; j++){ int rc; int iChoice; Tcl_Obj *pFlag = Tcl_DuplicateObj(apObj[j]); Tcl_IncrRefCount(pFlag); Tcl_UtfToLower(Tcl_GetString(pFlag)); rc = Tcl_GetIndexFromObjStruct( |
︙ | ︙ | |||
921 922 923 924 925 926 927 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int iDelay; const char *zCrashFile; | > | | 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int iDelay; const char *zCrashFile; Tcl_Size nCrashFile; int iDc, iSectorSize; iDc = -1; iSectorSize = -1; if( objc<3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE"); goto error; |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #ifndef SQLITE_OMIT_VIRTUALTABLE typedef struct echo_vtab echo_vtab; typedef struct echo_cursor echo_cursor; |
︙ | ︙ |
Changes to src/test9.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** ** This file contains obscure tests of the C-interface required ** for completeness. Test code is written in C for these cases ** as there is not much point in binding to Tcl. */ #include "sqliteInt.h" | < < < | < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** ** This file contains obscure tests of the C-interface required ** for completeness. Test code is written in C for these cases ** as there is not much point in binding to Tcl. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> /* ** c_collation_test */ static int SQLITE_TCLAPI c_collation_test( |
︙ | ︙ |
Changes to src/test_async.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** ** This file contains a binding of the asynchronous IO extension interface ** (defined in ext/async/sqlite3async.h) to Tcl. */ | | < < < | < < < < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ** ************************************************************************* ** ** This file contains a binding of the asynchronous IO extension interface ** (defined in ext/async/sqlite3async.h) to Tcl. */ #define TCL_THREADS #include "tclsqlite.h" #ifdef SQLITE_ENABLE_ASYNCIO #include "sqlite3async.h" #include "sqlite3.h" #include <assert.h> |
︙ | ︙ |
Changes to src/test_autoext.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2006 August 23 ** ** 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. ** ************************************************************************* ** Test extension for testing the sqlite3_auto_extension() function. */ | < < < | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2006 August 23 ** ** 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. ** ************************************************************************* ** Test extension for testing the sqlite3_auto_extension() function. */ #include "tclsqlite.h" #include "sqlite3ext.h" #ifndef SQLITE_OMIT_LOAD_EXTENSION SQLITE_EXTENSION_INIT1 /* ** The sqr() SQL function returns the square of its input value. |
︙ | ︙ |
Changes to src/test_backup.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains test logic for the sqlite3_backup() interface. ** */ | < < < | < < < < | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains test logic for the sqlite3_backup() interface. ** */ #include "tclsqlite.h" #include "sqlite3.h" #include <assert.h> /* These functions are implemented in main.c. */ extern const char *sqlite3ErrName(int); /* These functions are implemented in test1.c. */ |
︙ | ︙ |
Changes to src/test_bestindex.c.
︙ | ︙ | |||
89 90 91 92 93 94 95 | ** for the current scan. The leftmost column returned by the SELECT is assumed ** to contain the rowid. Other columns must follow, in order from left to ** right. */ #include "sqliteInt.h" | < < < | < | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | ** for the current scan. The leftmost column returned by the SELECT is assumed ** to contain the rowid. Other columns must follow, in order from left to ** right. */ #include "sqliteInt.h" #include "tclsqlite.h" #ifndef SQLITE_OMIT_VIRTUALTABLE typedef struct tcl_vtab tcl_vtab; typedef struct tcl_cursor tcl_cursor; typedef struct TestFindFunction TestFindFunction; |
︙ | ︙ | |||
348 349 350 351 352 353 354 | ** list object with an even number of elements. The first element of each ** pair must be one of: ** ** "sql" (SQL statement to return data) */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; | | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | ** list object with an even number of elements. The first element of each ** pair must be one of: ** ** "sql" (SQL statement to return data) */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; Tcl_Size nElem; rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem); if( rc!=TCL_OK ){ const char *zErr = Tcl_GetStringResult(interp); rc = SQLITE_ERROR; pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr); }else{ for(ii=0; rc==SQLITE_OK && ii<(int)nElem; ii+=2){ const char *zCmd = Tcl_GetString(apElem[ii]); Tcl_Obj *p = apElem[ii+1]; if( sqlite3_stricmp("sql", zCmd)==0 ){ const char *zSql = Tcl_GetString(p); rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); if( rc!=SQLITE_OK ){ const char *zErr = sqlite3_errmsg(pTab->db); |
︙ | ︙ | |||
660 661 662 663 664 665 666 | ** "use" (index of used constraint in aConstraint[]) ** "idxnum" (value of idxNum field) ** "idxstr" (value of idxStr field) ** "omit" (index of omitted constraint in aConstraint[]) */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; | | | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | ** "use" (index of used constraint in aConstraint[]) ** "idxnum" (value of idxNum field) ** "idxstr" (value of idxStr field) ** "omit" (index of omitted constraint in aConstraint[]) */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; Tcl_Size nElem; rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem); if( rc!=TCL_OK ){ const char *zErr = Tcl_GetStringResult(interp); rc = SQLITE_ERROR; pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr); }else{ int ii; int iArgv = 1; for(ii=0; rc==SQLITE_OK && ii<(int)nElem; ii+=2){ const char *zCmd = Tcl_GetString(apElem[ii]); Tcl_Obj *p = apElem[ii+1]; if( sqlite3_stricmp("cost", zCmd)==0 ){ rc = Tcl_GetDoubleFromObj(interp, p, &pIdxInfo->estimatedCost); }else if( sqlite3_stricmp("orderby", zCmd)==0 ){ rc = Tcl_GetIntFromObj(interp, p, &pIdxInfo->orderByConsumed); |
︙ | ︙ |
Changes to src/test_blob.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** */ #include "sqliteInt.h" | < < < | < | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> #ifndef SQLITE_OMIT_INCRBLOB /* These functions are implemented in main.c. */ extern const char *sqlite3ErrName(int); |
︙ | ︙ | |||
54 55 56 57 58 59 60 | */ static int blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob ){ char *z; | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | */ static int blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob ){ char *z; Tcl_Size n; z = Tcl_GetStringFromObj(pObj, &n); if( n==0 ){ *ppBlob = 0; }else if( n>9 && 0==memcmp("incrblob_", z, 9) ){ int notUsed; Tcl_Channel channel; |
︙ | ︙ | |||
84 85 86 87 88 89 90 | } /* ** Like Tcl_GetString(), except that if the string is 0 bytes in size, a ** NULL Pointer is returned. */ static char *blobStringFromObj(Tcl_Obj *pObj){ | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | } /* ** Like Tcl_GetString(), except that if the string is 0 bytes in size, a ** NULL Pointer is returned. */ static char *blobStringFromObj(Tcl_Obj *pObj){ Tcl_Size n; char *z; z = Tcl_GetStringFromObj(pObj, &n); return (n ? z : 0); } /* ** sqlite3_blob_open DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME |
︙ | ︙ | |||
108 109 110 111 112 113 114 | sqlite3 *db; const char *zDb; const char *zTable; const char *zColumn; Tcl_WideInt iRowid; int flags; const char *zVarname; | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | sqlite3 *db; const char *zDb; const char *zTable; const char *zColumn; Tcl_WideInt iRowid; int flags; const char *zVarname; Tcl_Size nVarname; sqlite3_blob *pBlob = (sqlite3_blob*)&flags; /* Non-zero initialization */ int rc; if( objc!=8 ){ const char *zUsage = "DB DATABASE TABLE COLUMN ROWID FLAGS VARNAME"; Tcl_WrongNumArgs(interp, 1, objv, zUsage); |
︙ | ︙ | |||
277 278 279 280 281 282 283 | Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int iOffset; int rc; unsigned char *zBuf; | > | > | | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3_blob *pBlob; int iOffset; int rc; unsigned char *zBuf; Tcl_Size nBuf; int n; if( objc!=4 && objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET DATA ?NDATA?"); return TCL_ERROR; } if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ return TCL_ERROR; } zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); n = (int)(nBuf & 0x7fffffff); if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &n) ){ return TCL_ERROR; } rc = sqlite3_blob_write(pBlob, zBuf, n, iOffset); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); } return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); } #endif /* SQLITE_OMIT_INCRBLOB */ |
︙ | ︙ |
Changes to src/test_btree.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "btreeInt.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. */ #include "btreeInt.h" #include "tclsqlite.h" /* ** Usage: sqlite3_shared_cache_report ** ** Return a list of file that are shared and the number of ** references to each file. */ |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include "sqliteLimit.h" #include "sqliteInt.h" #if SQLITE_OS_WIN # include "os_win.h" #endif | < < < | < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "sqliteLimit.h" #include "sqliteInt.h" #if SQLITE_OS_WIN # include "os_win.h" #endif #include "tclsqlite.h" #include <stdlib.h> #include <string.h> /* ** Macro to stringify the results of the evaluation a pre-processor ** macro. i.e. so that STRINGVALUE(SQLITE_NOMEM) -> "7". */ |
︙ | ︙ |
Changes to src/test_demovfs.c.
︙ | ︙ | |||
641 642 643 644 645 646 647 | } #endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */ #ifdef SQLITE_TEST | < < < | < < < < | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | } #endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */ #ifdef SQLITE_TEST #include "tclsqlite.h" #if SQLITE_OS_UNIX static int SQLITE_TCLAPI register_demovfs( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ |
︙ | ︙ |
Changes to src/test_fs.c.
︙ | ︙ | |||
58 59 60 61 62 63 64 | ** contents of the file-system, starting at "/". To restrict the search ** space, the virtual table supports LIKE and GLOB constraints on the ** 'path' column. For example: ** ** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%' */ #include "sqliteInt.h" | < < < | < < | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | ** contents of the file-system, starting at "/". To restrict the search ** space, the virtual table supports LIKE and GLOB constraints on the ** 'path' column. For example: ** ** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%' */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #if SQLITE_OS_UNIX || defined(__MINGW_H) |
︙ | ︙ |
Changes to src/test_func.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements new SQL functions used by the test scripts. */ #include "sqlite3.h" | < < < | < | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements new SQL functions used by the test scripts. */ #include "sqlite3.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> #include "sqliteInt.h" #include "vdbeInt.h" |
︙ | ︙ |
Changes to src/test_hexio.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. */ #include "sqliteInt.h" | < < < | < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> /* ** Convert binary to hex. The input zBuf[] contains N bytes of |
︙ | ︙ | |||
151 152 153 154 155 156 157 | static int SQLITE_TCLAPI hexio_write( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int offset; | > | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | static int SQLITE_TCLAPI hexio_write( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int offset; Tcl_Size nIn; int nOut, written; const char *zFile; const unsigned char *zIn; unsigned char *aOut; FILE *out; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn); aOut = sqlite3_malloc64( 1 + nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = sqlite3TestHexToBin(zIn, (int)nIn, aOut); out = fopen(zFile, "r+b"); if( out==0 ){ out = fopen(zFile, "r+"); } if( out==0 ){ Tcl_AppendResult(interp, "cannot open output file ", zFile, 0); return TCL_ERROR; |
︙ | ︙ | |||
199 200 201 202 203 204 205 | static int SQLITE_TCLAPI hexio_get_int( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; | > | | | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | static int SQLITE_TCLAPI hexio_get_int( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; Tcl_Size nIn; int nOut; const unsigned char *zIn; unsigned char *aOut; unsigned char aNum[4]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA"); return TCL_ERROR; } zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); aOut = sqlite3_malloc64( 1 + nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = sqlite3TestHexToBin(zIn, (int)nIn, aOut); if( nOut>=4 ){ memcpy(aNum, aOut, 4); }else{ memset(aNum, 0, sizeof(aNum)); memcpy(&aNum[4-nOut], aOut, nOut); } sqlite3_free(aOut); |
︙ | ︙ | |||
296 297 298 299 300 301 302 | static int SQLITE_TCLAPI utf8_to_utf8( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #ifdef SQLITE_DEBUG | | | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | static int SQLITE_TCLAPI utf8_to_utf8( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #ifdef SQLITE_DEBUG Tcl_Size n; int nOut; const unsigned char *zOrig; unsigned char *z; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEX"); return TCL_ERROR; } zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n); z = sqlite3_malloc64( n+4 ); n = sqlite3TestHexToBin(zOrig, (int)n, z); z[n] = 0; nOut = sqlite3Utf8To8(z); sqlite3TestBinToHex(z,nOut); Tcl_AppendResult(interp, (char*)z, 0); sqlite3_free(z); return TCL_OK; #else |
︙ | ︙ | |||
357 358 359 360 361 362 363 | */ static int SQLITE_TCLAPI read_fts3varint( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | */ static int SQLITE_TCLAPI read_fts3varint( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Size nBlob; unsigned char *zBlob; sqlite3_int64 iVal; int nVal; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "BLOB VARNAME"); return TCL_ERROR; |
︙ | ︙ | |||
384 385 386 387 388 389 390 | static int SQLITE_TCLAPI make_fts3record( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Obj **aArg = 0; | | | | | | | | | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | static int SQLITE_TCLAPI make_fts3record( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Tcl_Obj **aArg = 0; Tcl_Size nArg = 0; unsigned char *aOut = 0; sqlite3_int64 nOut = 0; sqlite3_int64 nAlloc = 0; int i; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "LIST"); return TCL_ERROR; } if( Tcl_ListObjGetElements(interp, objv[1], &nArg, &aArg) ){ return TCL_ERROR; } for(i=0; i<(int)nArg; i++){ Tcl_WideInt iVal; if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){ if( nOut+10>nAlloc ){ int nNew = nAlloc?nAlloc*2:128; unsigned char *aNew = sqlite3_realloc(aOut, nNew); if( aNew==0 ){ sqlite3_free(aOut); return TCL_ERROR; } aOut = aNew; nAlloc = nNew; } nOut += putFts3Varint((char*)&aOut[nOut], iVal); }else{ Tcl_Size nVal = 0; char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal); while( (nOut + nVal)>nAlloc ){ sqlite3_int64 nNew = nAlloc?nAlloc*2:128; unsigned char *aNew = sqlite3_realloc64(aOut, nNew); if( aNew==0 ){ sqlite3_free(aOut); return TCL_ERROR; } aOut = aNew; nAlloc = nNew; } |
︙ | ︙ |
Changes to src/test_init.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 | ** of those subsystems that were initialized, and ** 3) A subsequent call to sqlite3_initialize() attempts to initialize ** the remaining, uninitialized, subsystems. */ #include "sqliteInt.h" #include <string.h> | < < < | < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ** of those subsystems that were initialized, and ** 3) A subsequent call to sqlite3_initialize() attempts to initialize ** the remaining, uninitialized, subsystems. */ #include "sqliteInt.h" #include <string.h> #include "tclsqlite.h" static struct Wrapped { sqlite3_pcache_methods2 pcache; sqlite3_mem_methods mem; sqlite3_mutex_methods mutex; int mem_init; /* True if mem subsystem is initialized */ |
︙ | ︙ |
Changes to src/test_intarray.c.
︙ | ︙ | |||
275 276 277 278 279 280 281 | } /***************************************************************************** ** Everything below is interface for testing this module. */ #ifdef SQLITE_TEST | < < < | < < < < | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | } /***************************************************************************** ** Everything below is interface for testing this module. */ #ifdef SQLITE_TEST #include "tclsqlite.h" /* ** Routines to encode and decode pointers */ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); extern void *sqlite3TestTextToPtr(const char*); extern int sqlite3TestMakePointerStr(Tcl_Interp*, char *zPtr, void*); |
︙ | ︙ |
Changes to src/test_malloc.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. */ #include "sqliteInt.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> /* ** This structure is used to encapsulate the global state variables used ** by malloc() fault simulation. |
︙ | ︙ | |||
383 384 385 386 387 388 389 | static int SQLITE_TCLAPI test_memset( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *p; | | > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | static int SQLITE_TCLAPI test_memset( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void *p; int size, i; Tcl_Size n; char *zHex; char *zOut; char zBin[100]; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX"); return TCL_ERROR; |
︙ | ︙ | |||
405 406 407 408 409 410 411 | } if( size<=0 ){ Tcl_AppendResult(interp, "size must be positive", (char*)0); return TCL_ERROR; } zHex = Tcl_GetStringFromObj(objv[3], &n); if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2; | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | } if( size<=0 ){ Tcl_AppendResult(interp, "size must be positive", (char*)0); return TCL_ERROR; } zHex = Tcl_GetStringFromObj(objv[3], &n); if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2; n = sqlite3TestHexToBin(zHex, (int)n, zBin); if( n==0 ){ Tcl_AppendResult(interp, "no data", (char*)0); return TCL_ERROR; } zOut = p; for(i=0; i<size; i++){ zOut[i] = zBin[i%n]; |
︙ | ︙ | |||
620 621 622 623 624 625 626 | if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; for(ii=2; ii<objc; ii+=2){ | | | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "COUNTER ?OPTIONS?"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; for(ii=2; ii<objc; ii+=2){ Tcl_Size nOption; char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption); char *zErr = 0; if( nOption>1 && strncmp(zOption, "-repeat", nOption)==0 ){ if( ii==(objc-1) ){ zErr = "option requires an argument: "; }else{ |
︙ | ︙ |
Changes to src/test_md5.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** ** This file contains code to implement an MD5 extension to TCL. */ #include "sqlite3.h" #include <stdlib.h> #include <string.h> #include "sqlite3.h" | < < < | < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This file contains code to implement an MD5 extension to TCL. */ #include "sqlite3.h" #include <stdlib.h> #include <string.h> #include "sqlite3.h" #include "tclsqlite.h" /* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * |
︙ | ︙ |
Changes to src/test_multiplex.c.
︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | sqlite3_vfs_unregister(&gMultiplex.sThisVfs); memset(&gMultiplex, 0, sizeof(gMultiplex)); return rc; } /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST | < < < | < < < < | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | sqlite3_vfs_unregister(&gMultiplex.sThisVfs); memset(&gMultiplex, 0, sizeof(gMultiplex)); return rc; } /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST #include "tclsqlite.h" extern const char *sqlite3ErrName(int); /* ** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT */ static int SQLITE_TCLAPI test_multiplex_initialize( |
︙ | ︙ |
Changes to src/test_mutex.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2008 June 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains test logic for the sqlite3_mutex interfaces. */ | < < < < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2008 June 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains test logic for the sqlite3_mutex interfaces. */ #include "tclsqlite.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> #include <assert.h> #include <string.h> #define MAX_MUTEXES (SQLITE_MUTEX_STATIC_VFS3+1) |
︙ | ︙ |
Changes to src/test_osinst.c.
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 | /************************************************************************** *************************************************************************** ** Tcl interface starts here. */ #if defined(SQLITE_TEST) || defined(TCLSH) | < < < | < < < < | 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | /************************************************************************** *************************************************************************** ** Tcl interface starts here. */ #if defined(SQLITE_TEST) || defined(TCLSH) #include "tclsqlite.h" static int SQLITE_TCLAPI test_vfslog( void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ |
︙ | ︙ |
Changes to src/test_quota.c.
︙ | ︙ | |||
1274 1275 1276 1277 1278 1279 1280 | quotaLeave(); sqlite3_free(zFull); return rc; } /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST | < < < | < < < < | 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 | quotaLeave(); sqlite3_free(zFull); return rc; } /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST #include "tclsqlite.h" /* ** Argument passed to a TCL quota-over-limit callback. */ typedef struct TclQuotaCallback TclQuotaCallback; struct TclQuotaCallback { Tcl_Interp *interp; /* Interpreter in which to run the script */ |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | Tcl_Obj *CONST objv[] ){ const char *zPattern; /* File pattern to configure */ Tcl_WideInt iLimit; /* Initial quota in bytes */ Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */ int rc; /* Value returned by quota_set() */ TclQuotaCallback *p; /* Callback object */ | | | 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | Tcl_Obj *CONST objv[] ){ const char *zPattern; /* File pattern to configure */ Tcl_WideInt iLimit; /* Initial quota in bytes */ Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */ int rc; /* Value returned by quota_set() */ TclQuotaCallback *p; /* Callback object */ Tcl_Size nScript; /* Length of callback script */ void (*xDestroy)(void*); /* Optional destructor for pArg */ void (*xCallback)(const char *, sqlite3_int64 *, sqlite3_int64, void *); /* Process arguments */ if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "PATTERN LIMIT SCRIPT"); return TCL_ERROR; |
︙ | ︙ |
Changes to src/test_rtree.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" | < < < | < | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" #include "tclsqlite.h" /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" #ifdef SQLITE_ENABLE_RTREE /* ** Type used to cache parameter information for the "circle" r-tree geometry |
︙ | ︙ | |||
353 354 355 356 357 358 359 | } /* END of implementation of "circle" geometry callback. ************************************************************************** *************************************************************************/ #include <assert.h> | < < < | < | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | } /* END of implementation of "circle" geometry callback. ************************************************************************** *************************************************************************/ #include <assert.h> #include "tclsqlite.h" typedef struct Cube Cube; struct Cube { double x; double y; double z; double width; |
︙ | ︙ |
Changes to src/test_schema.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | /* If SQLITE_TEST is defined this code is preprocessed for use as part ** of the sqlite test binary "testfixture". Otherwise it is preprocessed ** to be compiled into an sqlite dynamic extension. */ #ifdef SQLITE_TEST # include "sqliteInt.h" | < < < | < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /* If SQLITE_TEST is defined this code is preprocessed for use as part ** of the sqlite test binary "testfixture". Otherwise it is preprocessed ** to be compiled into an sqlite dynamic extension. */ #ifdef SQLITE_TEST # include "sqliteInt.h" # include "tclsqlite.h" #else # include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif #include <stdlib.h> #include <string.h> |
︙ | ︙ |
Changes to src/test_superlock.c.
︙ | ︙ | |||
252 253 254 255 256 257 258 | ************************************************************************** ************************************************************************** *************************************************************************/ #ifdef SQLITE_TEST | < < < | < < < < | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | ************************************************************************** ************************************************************************** *************************************************************************/ #ifdef SQLITE_TEST #include "tclsqlite.h" struct InterpAndScript { Tcl_Interp *interp; Tcl_Obj *pScript; }; typedef struct InterpAndScript InterpAndScript; |
︙ | ︙ |
Changes to src/test_syscall.c.
︙ | ︙ | |||
72 73 74 75 76 77 78 | ** If PGSZ is a power of two greater than 256, install a wrapper around ** OS function getpagesize() that reports the system page size as PGSZ. ** Or, if PGSZ is less than zero, remove any wrapper already installed. */ #include "sqliteInt.h" #include "sqlite3.h" | < < < | < | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | ** If PGSZ is a power of two greater than 256, install a wrapper around ** OS function getpagesize() that reports the system page size as PGSZ. ** Or, if PGSZ is less than zero, remove any wrapper already installed. */ #include "sqliteInt.h" #include "sqlite3.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> #if SQLITE_OS_UNIX /* From main.c */ |
︙ | ︙ | |||
193 194 195 196 197 198 199 | ** ** Usually, the current error-number is the value that errno should be set ** to if the named system call fails. The exception is "fallocate". See ** comments above the implementation of ts_fallocate() for details. */ static int tsErrno(const char *zFunc){ int i; | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | ** ** Usually, the current error-number is the value that errno should be set ** to if the named system call fails. The exception is "fallocate". See ** comments above the implementation of ts_fallocate() for details. */ static int tsErrno(const char *zFunc){ int i; size_t nFunc = strlen(zFunc); for(i=0; aSyscall[i].zName; i++){ if( strlen(aSyscall[i].zName)!=nFunc ) continue; if( memcmp(aSyscall[i].zName, zFunc, nFunc) ) continue; return aSyscall[i].custom_errno; } assert(0); |
︙ | ︙ | |||
425 426 427 428 429 430 431 | static int SQLITE_TCLAPI test_syscall_install( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_vfs *pVfs; | | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | static int SQLITE_TCLAPI test_syscall_install( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_vfs *pVfs; Tcl_Size nElem; int i; Tcl_Obj **apElem; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "SYSCALL-LIST"); return TCL_ERROR; } if( Tcl_ListObjGetElements(interp, objv[2], &nElem, &apElem) ){ return TCL_ERROR; } pVfs = sqlite3_vfs_find(0); for(i=0; i<(int)nElem; i++){ int iCall; int rc = Tcl_GetIndexFromObjStruct(interp, apElem[i], aSyscall, sizeof(aSyscall[0]), "system-call", 0, &iCall ); if( rc ) return rc; if( aSyscall[iCall].xOrig==0 ){ aSyscall[iCall].xOrig = pVfs->xGetSystemCall(pVfs, aSyscall[iCall].zName); |
︙ | ︙ | |||
498 499 500 501 502 503 504 | } pVfs = sqlite3_vfs_find(0); if( objc==2 ){ rc = pVfs->xSetSystemCall(pVfs, 0, 0); for(i=0; aSyscall[i].zName; i++) aSyscall[i].xOrig = 0; }else{ | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | } pVfs = sqlite3_vfs_find(0); if( objc==2 ){ rc = pVfs->xSetSystemCall(pVfs, 0, 0); for(i=0; aSyscall[i].zName; i++) aSyscall[i].xOrig = 0; }else{ Tcl_Size nFunc; char *zFunc = Tcl_GetStringFromObj(objv[2], &nFunc); rc = pVfs->xSetSystemCall(pVfs, Tcl_GetString(objv[2]), 0); for(i=0; rc==SQLITE_OK && aSyscall[i].zName; i++){ if( strlen(aSyscall[i].zName)!=nFunc ) continue; if( memcmp(aSyscall[i].zName, zFunc, nFunc) ) continue; aSyscall[i].xOrig = 0; } |
︙ | ︙ |
Changes to src/test_tclsh.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** "testfixture.exe") using logic encoded by this file. ** ** The code in this file used to be found in tclsqlite3.c, contained within ** #if SQLITE_TEST ... #endif. It is factored out into this separate module ** in an effort to keep the tclsqlite.c file pure. */ #include "sqlite3.h" | < < < | < < < < | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** "testfixture.exe") using logic encoded by this file. ** ** The code in this file used to be found in tclsqlite3.c, contained within ** #if SQLITE_TEST ... #endif. It is factored out into this separate module ** in an effort to keep the tclsqlite.c file pure. */ #include "sqlite3.h" #include "tclsqlite.h" /* Needed for the setrlimit() system call on unix */ #if defined(unix) #include <sys/resource.h> #endif /* Forward declaration */ |
︙ | ︙ |
Changes to src/test_tclvar.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | ** ** For SELECT operations, the "name" and "arrayname" fields will always ** match the "fullname" field. For DELETE, INSERT, and UPDATE, the ** "name" and "arrayname" fields are ignored and the variable is modified ** according to "fullname" and "value" only. */ #include "sqliteInt.h" | < < < | < | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** For SELECT operations, the "name" and "arrayname" fields will always ** match the "fullname" field. For DELETE, INSERT, and UPDATE, the ** "name" and "arrayname" fields are ignored and the variable is modified ** according to "fullname" and "value" only. */ #include "sqliteInt.h" #include "tclsqlite.h" #include <stdlib.h> #include <string.h> #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Characters that make up the idxStr created by xBestIndex for xFilter. |
︙ | ︙ | |||
68 69 70 71 72 73 74 | /* A tclvar cursor object */ struct tclvar_cursor { sqlite3_vtab_cursor base; Tcl_Obj *pList1; /* Result of [info vars ?pattern?] */ Tcl_Obj *pList2; /* Result of [array names [lindex $pList1 $i1]] */ | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* A tclvar cursor object */ struct tclvar_cursor { sqlite3_vtab_cursor base; Tcl_Obj *pList1; /* Result of [info vars ?pattern?] */ Tcl_Obj *pList2; /* Result of [array names [lindex $pList1 $i1]] */ Tcl_Size i1; /* Current item in pList1 */ Tcl_Size i2; /* Current item (if any) in pList2 */ }; /* Methods for the tclvar module */ static int tclvarConnect( sqlite3 *db, void *pAux, int argc, const char *const*argv, |
︙ | ︙ | |||
146 147 148 149 150 151 152 | Tcl_ListObjAppendElement(0, p, pObj); Tcl_EvalObjEx(interp, p, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(p); pCur->pList2 = Tcl_GetObjResult(interp); Tcl_IncrRefCount(pCur->pList2); assert( pCur->i2==0 ); }else{ | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | Tcl_ListObjAppendElement(0, p, pObj); Tcl_EvalObjEx(interp, p, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(p); pCur->pList2 = Tcl_GetObjResult(interp); Tcl_IncrRefCount(pCur->pList2); assert( pCur->i2==0 ); }else{ Tcl_Size n = 0; pCur->i2++; Tcl_ListObjLength(0, pCur->pList2, &n); if( pCur->i2>=n ){ Tcl_DecrRefCount(pCur->pList2); pCur->pList2 = 0; pCur->i2 = 0; return 0; } } } return 1; } static int tclvarNext(sqlite3_vtab_cursor *cur){ Tcl_Obj *pObj; Tcl_Size n = 0; int ok = 0; tclvar_cursor *pCur = (tclvar_cursor *)cur; Tcl_Interp *interp = ((tclvar_vtab *)(cur->pVtab))->interp; Tcl_ListObjLength(0, pCur->pList1, &n); while( !ok && pCur->i1<n ){ |
︙ | ︙ |
Changes to src/test_thread.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** ** This file contains the implementation of some Tcl commands used to ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. */ #include "sqliteInt.h" | < < < | < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** ** This file contains the implementation of some Tcl commands used to ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. */ #include "sqliteInt.h" #include "tclsqlite.h" #if SQLITE_THREADSAFE #include <errno.h> #if !defined(_MSC_VER) #include <unistd.h> |
︙ | ︙ | |||
90 91 92 93 94 95 96 | /* ** Register an EvalEvent to evaluate the script pScript in the ** parent interpreter/thread of SqlThread p. */ static void postToParent(SqlThread *p, Tcl_Obj *pScript){ EvalEvent *pEvent; char *zMsg; | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | /* ** Register an EvalEvent to evaluate the script pScript in the ** parent interpreter/thread of SqlThread p. */ static void postToParent(SqlThread *p, Tcl_Obj *pScript){ EvalEvent *pEvent; char *zMsg; Tcl_Size nMsg; zMsg = Tcl_GetStringFromObj(pScript, &nMsg); pEvent = (EvalEvent *)ckalloc(sizeof(EvalEvent)+nMsg+1); pEvent->base.nextPtr = 0; pEvent->base.proc = tclScriptEvent; pEvent->zScript = (char *)&pEvent[1]; memcpy(pEvent->zScript, zMsg, nMsg+1); |
︙ | ︙ | |||
177 178 179 180 181 182 183 | int objc, Tcl_Obj *CONST objv[] ){ Tcl_ThreadId x; SqlThread *pNew; int rc; | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | int objc, Tcl_Obj *CONST objv[] ){ Tcl_ThreadId x; SqlThread *pNew; int rc; Tcl_Size nVarname; char *zVarname; Tcl_Size nScript; char *zScript; /* Parameters for thread creation */ const int nStack = TCL_THREAD_STACK_DEFAULT; const int flags = TCL_THREAD_NOFLAGS; assert(objc==4); UNUSED_PARAMETER(clientData); |
︙ | ︙ | |||
228 229 230 231 232 233 234 | ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ EvalEvent *pEvent; char *zMsg; | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ EvalEvent *pEvent; char *zMsg; Tcl_Size nMsg; SqlThread *p = (SqlThread *)clientData; assert(objc==3); UNUSED_PARAMETER(objc); if( p==0 ){ Tcl_AppendResult(interp, "no parent thread", 0); |
︙ | ︙ |
Changes to src/test_vdbecov.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ****************************************************************************** ** */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqlite3.h" #include "sqliteInt.h" | < < < | < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ****************************************************************************** ** */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqlite3.h" #include "sqliteInt.h" #include "tclsqlite.h" #ifdef SQLITE_VDBE_COVERAGE static u8 aBranchArray[200000]; static void test_vdbe_branch( void *pCtx, |
︙ | ︙ |
Changes to src/test_vfs.c.
︙ | ︙ | |||
24 25 26 27 28 29 30 | ** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname) ** -iversion INTEGER (Value for sqlite3_vfs.iVersion) */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqlite3.h" #include "sqliteInt.h" | < < < | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | ** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname) ** -iversion INTEGER (Value for sqlite3_vfs.iVersion) */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqlite3.h" #include "sqliteInt.h" #include "tclsqlite.h" typedef struct Testvfs Testvfs; typedef struct TestvfsShm TestvfsShm; typedef struct TestvfsBuffer TestvfsBuffer; typedef struct TestvfsFile TestvfsFile; typedef struct TestvfsFd TestvfsFd; |
︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 | } ckfree(zName); if( !pBuffer ){ Tcl_AppendResult(interp, "no such file: ", Tcl_GetString(objv[2]), 0); return TCL_ERROR; } if( objc==4 ){ | | | | | 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 | } ckfree(zName); if( !pBuffer ){ Tcl_AppendResult(interp, "no such file: ", Tcl_GetString(objv[2]), 0); return TCL_ERROR; } if( objc==4 ){ Tcl_Size n; u8 *a = Tcl_GetByteArrayFromObj(objv[3], &n); int pgsz = pBuffer->pgsz; if( pgsz==0 ) pgsz = 65536; for(i=0; i*pgsz<(int)n; i++){ int nByte = pgsz; tvfsAllocPage(pBuffer, i, pgsz); if( n-i*pgsz<pgsz ){ nByte = (int)n; } memcpy(pBuffer->aPage[i], &a[i*pgsz], nByte); } } pObj = Tcl_NewObj(); for(i=0; pBuffer->aPage[i]; i++){ |
︙ | ︙ | |||
1199 1200 1201 1202 1203 1204 1205 | { "xFullPathname", TESTVFS_FULLPATHNAME_MASK }, { "xUnlock", TESTVFS_UNLOCK_MASK }, { "xLock", TESTVFS_LOCK_MASK }, { "xCheckReservedLock", TESTVFS_CKLOCK_MASK }, { "xFileControl", TESTVFS_FCNTL_MASK }, }; Tcl_Obj **apElem = 0; | | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 | { "xFullPathname", TESTVFS_FULLPATHNAME_MASK }, { "xUnlock", TESTVFS_UNLOCK_MASK }, { "xLock", TESTVFS_LOCK_MASK }, { "xCheckReservedLock", TESTVFS_CKLOCK_MASK }, { "xFileControl", TESTVFS_FCNTL_MASK }, }; Tcl_Obj **apElem = 0; Tcl_Size nElem = 0; int mask = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "LIST"); return TCL_ERROR; } if( Tcl_ListObjGetElements(interp, objv[2], &nElem, &apElem) ){ return TCL_ERROR; } Tcl_ResetResult(interp); for(i=0; i<(int)nElem; i++){ int iMethod; char *zElem = Tcl_GetString(apElem[i]); for(iMethod=0; iMethod<ArraySize(vfsmethod); iMethod++){ if( strcmp(zElem, vfsmethod[iMethod].zName)==0 ){ mask |= vfsmethod[iMethod].mask; break; } |
︙ | ︙ | |||
1235 1236 1237 1238 1239 1240 1241 | ** TESTVFS script ?SCRIPT? ** ** Query or set the script to be run when filtered VFS events ** occur. */ case CMD_SCRIPT: { if( objc==3 ){ | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | ** TESTVFS script ?SCRIPT? ** ** Query or set the script to be run when filtered VFS events ** occur. */ case CMD_SCRIPT: { if( objc==3 ){ Tcl_Size nByte; if( p->pScript ){ Tcl_DecrRefCount(p->pScript); p->pScript = 0; } Tcl_GetStringFromObj(objv[2], &nByte); if( nByte>0 ){ p->pScript = Tcl_DuplicateObj(objv[2]); |
︙ | ︙ | |||
1333 1334 1335 1336 1337 1338 1339 | Tcl_WrongNumArgs(interp, 2, objv, "?ATTR-LIST?"); return TCL_ERROR; } if( objc==3 ){ int j; int iNew = 0; Tcl_Obj **flags = 0; | | | | 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 | Tcl_WrongNumArgs(interp, 2, objv, "?ATTR-LIST?"); return TCL_ERROR; } if( objc==3 ){ int j; int iNew = 0; Tcl_Obj **flags = 0; Tcl_Size nFlags = 0; if( Tcl_ListObjGetElements(interp, objv[2], &nFlags, &flags) ){ return TCL_ERROR; } for(j=0; j<(int)nFlags; j++){ int idx = 0; if( Tcl_GetIndexFromObjStruct(interp, flags[j], aFlag, sizeof(aFlag[0]), "flag", 0, &idx) ){ return TCL_ERROR; } if( aFlag[idx].iValue<0 && nFlags>1 ){ |
︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 | int isDefault = 0; /* True if -default is passed */ int szOsFile = 0; /* Value passed to -szosfile */ int mxPathname = -1; /* Value passed to -mxpathname */ int iVersion = 3; /* Value passed to -iversion */ if( objc<2 || 0!=(objc%2) ) goto bad_args; for(i=2; i<objc; i += 2){ | | | 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 | int isDefault = 0; /* True if -default is passed */ int szOsFile = 0; /* Value passed to -szosfile */ int mxPathname = -1; /* Value passed to -mxpathname */ int iVersion = 3; /* Value passed to -iversion */ if( objc<2 || 0!=(objc%2) ) goto bad_args; for(i=2; i<objc; i += 2){ Tcl_Size nSwitch; char *zSwitch; zSwitch = Tcl_GetStringFromObj(objv[i], &nSwitch); if( nSwitch>2 && 0==strncmp("-noshm", zSwitch, nSwitch) ){ if( Tcl_GetBooleanFromObj(interp, objv[i+1], &isNoshm) ){ return TCL_ERROR; } |
︙ | ︙ |
Changes to src/test_window.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | */ #include "sqlite3.h" #ifdef SQLITE_TEST #include "sqliteInt.h" | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | */ #include "sqlite3.h" #ifdef SQLITE_TEST #include "sqliteInt.h" #include "tclsqlite.h" extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); extern const char *sqlite3ErrName(int); typedef struct TestWindow TestWindow; struct TestWindow { Tcl_Obj *xStep; |
︙ | ︙ |
Changes to src/vdbesort.c.
︙ | ︙ | |||
552 553 554 555 556 557 558 | nRem = nByte - nAvail; /* The following loop copies up to p->nBuffer bytes per iteration into ** the p->aAlloc[] buffer. */ while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ | | > | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | nRem = nByte - nAvail; /* The following loop copies up to p->nBuffer bytes per iteration into ** the p->aAlloc[] buffer. */ while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ 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; } *ppOut = p->aAlloc; } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 | pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; for(p=pWC, i=j=0; p; p=p->pOuter){ int nLast = i+p->nTerm;; for(pTerm=p->a; i<nLast; i++, pTerm++){ | > > > > > > > > > > > > > | 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; 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; i<pPk->nKeyCol; i++){ int iCol = pPk->aiColumn[i]; assert( iCol>=0 ); if( iCol>=BMS-1 ) iCol = BMS-1; pIdxInfo->colUsed |= MASKBIT(iCol); } } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; for(p=pWC, i=j=0; p; p=p->pOuter){ int nLast = i+p->nTerm;; for(pTerm=p->a; i<nLast; i++, pTerm++){ |
︙ | ︙ | |||
4030 4031 4032 4033 4034 4035 4036 | }else{ assert( isCov==WHERE_EXPRIDX ); WHERETRACE(0x200, ("-> %s might be a covering expression index" " according to whereIsCoveringIndex()\n", pProbe->zName)); } } | | > > | 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 | }else{ assert( isCov==WHERE_EXPRIDX ); WHERETRACE(0x200, ("-> %s might be a covering expression index" " according to whereIsCoveringIndex()\n", pProbe->zName)); } } }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")); pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; } } |
︙ | ︙ | |||
4212 4213 4214 4215 4216 4217 4218 | assert( pIdxInfo->needToFreeIdxStr==0 ); pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; | < | 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 | assert( pIdxInfo->needToFreeIdxStr==0 ); pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); if( rc ){ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means |
︙ | ︙ | |||
7062 7063 7064 7065 7066 7067 7068 | VdbeOp *pOp ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); } #endif | < < < < < < < < < < < < < < < < < < < < | 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 | VdbeOp *pOp ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); } #endif /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. */ void sqlite3WhereEnd(WhereInfo *pWInfo){ Parse *pParse = pWInfo->pParse; Vdbe *v = pParse->pVdbe; |
︙ | ︙ | |||
7381 7382 7383 7384 7385 7386 7387 | pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); }else{ /* Unable to translate the table reference into an index ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ | < | < < < > | < < < < > | 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 | pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); }else{ /* Unable to translate the table reference into an index ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ 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; pOp->opcode = OP_IdxRowid; OpcodeRewriteTrace(db, k, pOp); }else if( pOp->opcode==OP_IfNullRow ){ pOp->p1 = pLevel->iIdxCur; |
︙ | ︙ |
Changes to test/backcompat.test.
︙ | ︙ | |||
108 109 110 111 112 113 114 | } } proc read_file {zFile} { set zData {} if {[file exists $zFile]} { set fd [open $zFile] | | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | } } proc read_file {zFile} { set zData {} if {[file exists $zFile]} { set fd [open $zFile] fconfigure $fd -translation binary if {[file size $zFile]<=$::sqlite_pending_byte || $zFile != "test.db"} { set zData [read $fd] } else { set zData [read $fd $::sqlite_pending_byte] append zData [string repeat x 512] seek $fd [expr $::sqlite_pending_byte+512] start append zData [read $fd] } close $fd } return $zData } proc write_file {zFile zData} { set fd [open $zFile w] fconfigure $fd -translation binary puts -nonewline $fd $zData close $fd } proc read_file_system {} { set ret [list] foreach f {test.db test.db-journal test.db-wal} { lappend ret [read_file $f] } set ret |
︙ | ︙ |
Added test/bestindexD.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 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 |
Changes to test/cast.test.
︙ | ︙ | |||
230 231 232 233 234 235 236 237 238 239 240 241 242 243 | # do_test cast-3.1 { execsql {SELECT CAST(9223372036854774800 AS integer)} } 9223372036854774800 do_test cast-3.2 { execsql {SELECT CAST(9223372036854774800 AS numeric)} } 9223372036854774800 do_realnum_test cast-3.3 { execsql {SELECT CAST(9223372036854774800 AS real)} } 9.22337203685477e+18 do_test cast-3.4 { execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)} } 9223372036854774784 do_test cast-3.5 { | > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | # do_test cast-3.1 { execsql {SELECT CAST(9223372036854774800 AS integer)} } 9223372036854774800 do_test cast-3.2 { execsql {SELECT CAST(9223372036854774800 AS numeric)} } 9223372036854774800 breakpoint do_realnum_test cast-3.3 { execsql {SELECT CAST(9223372036854774800 AS real)} } 9.22337203685477e+18 do_test cast-3.4 { execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)} } 9223372036854774784 do_test cast-3.5 { |
︙ | ︙ |
Changes to test/corrupt.test.
︙ | ︙ | |||
286 287 288 289 290 291 292 | # to run. After copying the contents of the root page to the new child, # btreeInitPage() is called on the child. This time, it detects corruption # (because the start of the blob associated with the (rowid=10) record # no longer looks like a real cell). At one point the code assumed that # detecting corruption was not possible at that point, and an assert() failed. # set fd [open test.db r+] | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | # to run. After copying the contents of the root page to the new child, # btreeInitPage() is called on the child. This time, it detects corruption # (because the start of the blob associated with the (rowid=10) record # no longer looks like a real cell). At one point the code assumed that # detecting corruption was not possible at that point, and an assert() failed. # set fd [open test.db r+] fconfigure $fd -translation binary seek $fd [expr 1024+8] puts -nonewline $fd "\x03\x14" close $fd sqlite3 db test.db do_test corrupt-7.2 { execsql { |
︙ | ︙ |
Changes to test/corrupt2.test.
︙ | ︙ | |||
65 66 67 68 69 70 71 | db2 close # Corrupt the page-size (bytes 16 and 17 of page 1). forcedelete corrupt.db forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] | | | | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | db2 close # Corrupt the page-size (bytes 16 and 17 of page 1). forcedelete corrupt.db forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] fconfigure $f -translation binary seek $f 16 start puts -nonewline $f "\x00\xFF" close $f sqlite3 db2 corrupt.db catchsql " $::presql SELECT * FROM sqlite_master; " db2 } {1 {file is not a database}} do_test corrupt2-1.4 { db2 close # Corrupt the free-block list on page 1. forcedelete corrupt.db forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] fconfigure $f -translation binary seek $f 101 start puts -nonewline $f "\xFF\xFF" close $f sqlite3 db2 corrupt.db # Note: This test is no longer meaningful due to the deferred computation # of MemPage.nFree catchsql {PRAGMA quick_check} db2 } {0 {{*** in database main *** Tree 1 page 1: free space corruption}}} do_test corrupt2-1.5 { db2 close # Corrupt the free-block list on page 1. forcedelete corrupt.db forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] fconfigure $f -translation binary seek $f 101 start puts -nonewline $f "\x00\xC8" seek $f 200 start puts -nonewline $f "\x00\x00" puts -nonewline $f "\x10\x00" close $f |
︙ | ︙ | |||
175 176 177 178 179 180 181 | # On the root page of table t2 (page 4), set one of the child page-numbers # to 0. This corruption will be detected when SQLite attempts to update # the pointer-map after moving the content of page 4 to page 3 as part # of the DROP TABLE operation below. # set fd [open corrupt.db r+] | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | # On the root page of table t2 (page 4), set one of the child page-numbers # to 0. This corruption will be detected when SQLite attempts to update # the pointer-map after moving the content of page 4 to page 3 as part # of the DROP TABLE operation below. # set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd [expr 1024*3 + 12] set zCelloffset [read $fd 2] binary scan $zCelloffset S iCelloffset seek $fd [expr 1024*3 + $iCelloffset] puts -nonewline $fd "\00\00\00\00" close $fd |
︙ | ︙ | |||
223 224 225 226 227 228 229 | " db2 db2 close # This block links a page from table t2 into the t1 table structure. # set fd [open corrupt.db r+] | | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | " db2 db2 close # This block links a page from table t2 into the t1 table structure. # set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd [expr 1024 + 12] set zCelloffset [read $fd 2] binary scan $zCelloffset S iCelloffset seek $fd [expr 1024 + $iCelloffset] set zChildPage [read $fd 4] seek $fd [expr 2*1024 + 12] set zCelloffset [read $fd 2] |
︙ | ︙ | |||
388 389 390 391 392 393 394 | } corruption_test -sqlprep $sqlprep -corrupt { # Set the page-flags of one of the leaf pages of the index B-Tree to # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree"). # set fd [open corrupt.db r+] | | | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | } corruption_test -sqlprep $sqlprep -corrupt { # Set the page-flags of one of the leaf pages of the index B-Tree to # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree"). # set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd [expr 1024*2 + 8] set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild seek $fd [expr 1024*($iRightChild-1)] puts -nonewline $fd "\x0D" close $fd } -test { do_test corrupt2-7.1 { catchsql " $::presql SELECT b FROM t1 ORDER BY b ASC " } {1 {database disk image is malformed}} } corruption_test -sqlprep $sqlprep -corrupt { # Mess up the page-header of one of the leaf pages of the index B-Tree. # The corruption is detected as part of an OP_Prev opcode. # set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd [expr 1024*2 + 12] set zCellOffset [read $fd 2] binary scan $zCellOffset S iCellOffset seek $fd [expr 1024*2 + $iCellOffset] set zChild [read $fd 4] binary scan $zChild I iChild seek $fd [expr 1024*($iChild-1)+3] puts -nonewline $fd "\xFFFF" close $fd } -test { do_test corrupt2-7.1 { catchsql " $::presql SELECT b FROM t1 ORDER BY b DESC " } {1 {database disk image is malformed}} } corruption_test -sqlprep $sqlprep -corrupt { # Set the page-flags of one of the leaf pages of the table B-Tree to # 0x0A (interpreted by SQLite as "leaf page of an index B-Tree"). # set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd [expr 1024*1 + 8] set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild seek $fd [expr 1024*($iRightChild-1)] puts -nonewline $fd "\x0A" close $fd } -test { |
︙ | ︙ | |||
455 456 457 458 459 460 461 | CREATE TABLE x2(a, b, c); CREATE TABLE x9(a, b, c); CREATE TABLE xF(a, b, c); CREATE TABLE x3(a, b, c); CREATE TABLE xA(a, b, c); CREATE TABLE xG(a, b, c); CREATE TABLE x4(a, b, c); CREATE TABLE xB(a, b, c); CREATE TABLE xH(a, b, c); CREATE TABLE x5(a, b, c); CREATE TABLE xC(a, b, c); CREATE TABLE xI(a, b, c); CREATE TABLE x6(a, b, c); CREATE TABLE xD(a, b, c); CREATE TABLE xJ(a, b, c); } -corrupt { set fd [open corrupt.db r+] | | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | CREATE TABLE x2(a, b, c); CREATE TABLE x9(a, b, c); CREATE TABLE xF(a, b, c); CREATE TABLE x3(a, b, c); CREATE TABLE xA(a, b, c); CREATE TABLE xG(a, b, c); CREATE TABLE x4(a, b, c); CREATE TABLE xB(a, b, c); CREATE TABLE xH(a, b, c); CREATE TABLE x5(a, b, c); CREATE TABLE xC(a, b, c); CREATE TABLE xI(a, b, c); CREATE TABLE x6(a, b, c); CREATE TABLE xD(a, b, c); CREATE TABLE xJ(a, b, c); } -corrupt { set fd [open corrupt.db r+] fconfigure $fd -translation binary seek $fd 108 set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild seek $fd [expr 1024*($iRightChild-1)+3] puts -nonewline $fd "\x00\x00" close $fd } -test { |
︙ | ︙ |
Changes to test/corrupt4.test.
︙ | ︙ | |||
118 119 120 121 122 123 124 | puts -nonewline $fd $bin } # Page 1 is now the grandparent of its leaves. Corrupt the database by setting # the second rightmost child page number of page 1 to 1. # set fd [open test.db r+] | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | puts -nonewline $fd $bin } # Page 1 is now the grandparent of its leaves. Corrupt the database by setting # the second rightmost child page number of page 1 to 1. # set fd [open test.db r+] fconfigure $fd -translation binary set nChild [get2byte $fd 103] set offChild [get2byte $fd [expr 100+12+($nChild-2)*2]] set pgnoChild [get4byte $fd $offChild] put4byte $fd $offChild 1 close $fd if {![info exists ::G(perm:presql)]} { |
︙ | ︙ |
Changes to test/corruptK.test.
︙ | ︙ | |||
56 57 58 59 60 61 62 | do_test 1.2 { db close hexio_write test.db [expr 1024 + 0x360] 21 hexio_write test.db [expr 1024 + 0x363] [format %x [expr 31*2 + 12]] sqlite3 db test.db set fd [db incrblob t1 x 3] | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | do_test 1.2 { db close hexio_write test.db [expr 1024 + 0x360] 21 hexio_write test.db [expr 1024 + 0x363] [format %x [expr 31*2 + 12]] sqlite3 db test.db set fd [db incrblob t1 x 3] fconfigure $fd -translation binary seek $fd 30 puts -nonewline $fd "\x18" close $fd } {} do_execsql_test 1.3 { INSERT INTO t1 VALUES(randomblob(20)); } |
︙ | ︙ | |||
98 99 100 101 102 103 104 | do_test 2.2 { db close hexio_write test.db [expr 1024 + 0x388] 53 hexio_write test.db [expr 1024 + 0x38A] 03812C sqlite3 db test.db set fd [db incrblob t1 x 5] | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | do_test 2.2 { db close hexio_write test.db [expr 1024 + 0x388] 53 hexio_write test.db [expr 1024 + 0x38A] 03812C sqlite3 db test.db set fd [db incrblob t1 x 5] fconfigure $fd -translation binary seek $fd 22 puts -nonewline $fd "\x5d" close $fd } {} do_catchsql_test 2.3 { |
︙ | ︙ |
Changes to test/crash.test.
︙ | ︙ | |||
395 396 397 398 399 400 401 | INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); INSERT INTO abc2 VALUES(randstr(1500,1500), 0, 0); COMMIT; } # Change the checksum value for the master journal name. set f [open test.db-journal a] | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); INSERT INTO abc2 VALUES(randstr(1500,1500), 0, 0); COMMIT; } # Change the checksum value for the master journal name. set f [open test.db-journal a] fconfigure $f -translation binary seek $f [expr [file size test.db-journal] - 12] puts -nonewline $f "\00\00\00\00" close $f } {} do_test crash-7.2 { signature } $sig |
︙ | ︙ |
Changes to test/exclusive2.test.
︙ | ︙ | |||
37 38 39 40 41 42 43 | # moments. So disable the soft-heap-limit. # sqlite3_soft_heap_limit 0 proc pagerChangeCounter {filename new {fd ""}} { if {$fd==""} { set fd [open $filename RDWR] | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # moments. So disable the soft-heap-limit. # sqlite3_soft_heap_limit 0 proc pagerChangeCounter {filename new {fd ""}} { if {$fd==""} { set fd [open $filename RDWR] fconfigure $fd -translation binary set needClose 1 } else { set needClose 0 } if {$new ne ""} { seek $fd 24 set a [expr {($new&0xFF000000)>>24}] |
︙ | ︙ | |||
66 67 68 69 70 71 72 | if {$needClose} {close $fd} return $ret } proc readPagerChangeCounter {filename} { set fd [open $filename RDONLY] | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | if {$needClose} {close $fd} return $ret } proc readPagerChangeCounter {filename} { set fd [open $filename RDONLY] fconfigure $fd -translation binary seek $fd 24 foreach {a b c d} [list 0 0 0 0] {} binary scan [read $fd 4] cccc a b c d set ret [expr ($a&0x000000FF)<<24] incr ret [expr ($b&0x000000FF)<<16] incr ret [expr ($c&0x000000FF)<<8] |
︙ | ︙ |
Changes to test/fts3snippet.test.
︙ | ︙ | |||
557 558 559 560 561 562 563 | do_test 4.3 { llength [db one { SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E' }] } {64} | < | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | do_test 4.3 { llength [db one { SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E' }] } {64} #------------------------------------------------------------------------- # Request a snippet from a query with more than 64 phrases. # do_execsql_test 5.0 { CREATE VIRTUAL TABLE t5 USING fts3(x); INSERT INTO t5 VALUES('a1 a2 a3'); INSERT INTO t5 VALUES('a4 a5 a6'); |
︙ | ︙ | |||
583 584 585 586 587 588 589 590 591 592 | 'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' || 'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70' } { {[a1] [a2] [a3]} {[a4] [a5] [a6]} {[a70] [a71] [a72]} } set sqlite_fts3_enable_parentheses 0 finish_test | > > > > | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | 'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' || 'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70' } { {[a1] [a2] [a3]} {[a4] [a5] [a6]} {[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 |
Changes to test/func6.test.
︙ | ︙ | |||
39 40 41 42 43 44 45 | INSERT INTO t2(x,y) SELECT a, b FROM t1; } # Load the contents of $file from disk and return it encoded as a hex # string. proc loadhex {file} { set fd [open $file] | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | INSERT INTO t2(x,y) SELECT a, b FROM t1; } # Load the contents of $file from disk and return it encoded as a hex # string. proc loadhex {file} { set fd [open $file] fconfigure $fd -translation binary set data [read $fd] close $fd binary encode hex $data } # Each argument is either an integer between 0 and 65535, a text value, or # an empty string representing an SQL NULL. This command builds an SQLite |
︙ | ︙ |
Changes to test/func7.test.
︙ | ︙ | |||
96 97 98 99 100 101 102 | do_execsql_test func7-pg-280 { SELECT trunc(42.8), trunc(-42.8); } {42.0 -42.0} do_execsql_test func7-pg-300 { SELECT acos(1); } {0.0} do_execsql_test func7-pg-301 { | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | do_execsql_test func7-pg-280 { SELECT trunc(42.8), trunc(-42.8); } {42.0 -42.0} do_execsql_test func7-pg-300 { SELECT acos(1); } {0.0} do_execsql_test func7-pg-301 { SELECT format('%f',degrees(acos(0.5))); } {60.0} do_execsql_test func7-pg-310 { SELECT round( asin(1), 7); } {1.5707963} do_execsql_test func7-pg-311 { SELECT format('%f',degrees( asin(0.5) )); } {30.0} do_execsql_test func7-pg-320 { SELECT round( atan(1), 7); } {0.7853982} do_execsql_test func7-pg-321 { SELECT degrees( atan(1) ); } {45.0} |
︙ | ︙ | |||
135 136 137 138 139 140 141 | do_execsql_test func7-pg-411 { SELECT sin( radians(30) ); } {0.5} do_execsql_test func7-pg-420 { SELECT round( tan(1), 7); } {1.5574077} do_execsql_test func7-pg-421 { | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | do_execsql_test func7-pg-411 { SELECT sin( radians(30) ); } {0.5} do_execsql_test func7-pg-420 { SELECT round( tan(1), 7); } {1.5574077} do_execsql_test func7-pg-421 { SELECT round(tan( radians(45) ),10); } {1.0} do_execsql_test func7-pg-500 { SELECT round( sinh(1), 7); } {1.1752012} do_execsql_test func7-pg-510 { SELECT round( cosh(0), 7); } {1.0} |
︙ | ︙ |
Changes to test/fuzz3.test.
︙ | ︙ | |||
79 80 81 82 83 84 85 | # command (assuming that the file is at least ($x>>8) bytes in size). # proc modify_database {iMod} { set blob [binary format c [expr {$iMod&0xFF}]] set offset [expr {$iMod>>8}] set fd [open test.db r+] | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # command (assuming that the file is at least ($x>>8) bytes in size). # proc modify_database {iMod} { set blob [binary format c [expr {$iMod&0xFF}]] set offset [expr {$iMod>>8}] set fd [open test.db r+] fconfigure $fd -translation binary seek $fd $offset set old_blob [read $fd 1] seek $fd $offset puts -nonewline $fd $blob close $fd binary scan $old_blob c iOld |
︙ | ︙ |
Changes to test/fuzzinvariants.c.
︙ | ︙ | |||
33 34 35 36 37 38 39 40 41 42 43 44 45 46 | static void reportInvariantFailed( sqlite3_stmt *pOrig, /* The original query */ sqlite3_stmt *pTest, /* The alternative test query with a missing row */ int iRow, /* Row number in pOrig */ unsigned int dbOpt, /* Optimization flags on pOrig */ int noOpt /* True if opt flags inverted for pTest */ ); /* ** Do an invariant check on pStmt. iCnt determines which invariant check to ** perform. The first check is iCnt==0. ** ** *pbCorrupt is a flag that, if true, indicates that the database file ** is known to be corrupt. A value of non-zero means "yes, the database | > > > > > > > > > > > > > > > > > > > > > > > > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | static void reportInvariantFailed( sqlite3_stmt *pOrig, /* The original query */ sqlite3_stmt *pTest, /* The alternative test query with a missing row */ int iRow, /* Row number in pOrig */ unsigned int dbOpt, /* Optimization flags on pOrig */ int noOpt /* True if opt flags inverted for pTest */ ); /* ** Special parameter binding, for testing and debugging purposes. ** ** $int_NNN -> integer value NNN ** $text_TTTT -> floating point value TTT with destructor */ static void bindDebugParameters(sqlite3_stmt *pStmt){ int nVar = sqlite3_bind_parameter_count(pStmt); int i; for(i=0; i<nVar; i++){ const char *zVar = sqlite3_bind_parameter_name(pStmt, i+1); if( zVar==0 ) continue; if( strncmp(zVar, "$int_", 5)==0 ){ sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5])); }else if( strncmp(zVar, "$text_", 6)==0 ){ char *zBuf = sqlite3_malloc64( strlen(zVar)-5 ); if( zBuf ){ memcpy(zBuf, &zVar[6], strlen(zVar)-5); sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8); } } } } /* ** Do an invariant check on pStmt. iCnt determines which invariant check to ** perform. The first check is iCnt==0. ** ** *pbCorrupt is a flag that, if true, indicates that the database file ** is known to be corrupt. A value of non-zero means "yes, the database |
︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 | sqlite3_errmsg(db), zTest); } sqlite3_free(zTest); sqlite3_finalize(pTestStmt); return rc; } sqlite3_free(zTest); nCol = sqlite3_column_count(pStmt); for(i=0; i<nCol; i++){ rc = sqlite3_bind_value(pTestStmt,i+1+nParam,sqlite3_column_value(pStmt,i)); if( rc!=SQLITE_OK && rc!=SQLITE_RANGE ){ sqlite3_finalize(pTestStmt); return rc; } | > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | sqlite3_errmsg(db), zTest); } sqlite3_free(zTest); sqlite3_finalize(pTestStmt); return rc; } sqlite3_free(zTest); bindDebugParameters(pTestStmt); nCol = sqlite3_column_count(pStmt); for(i=0; i<nCol; i++){ rc = sqlite3_bind_value(pTestStmt,i+1+nParam,sqlite3_column_value(pStmt,i)); if( rc!=SQLITE_OK && rc!=SQLITE_RANGE ){ sqlite3_finalize(pTestStmt); return rc; } |
︙ | ︙ | |||
167 168 169 170 171 172 173 174 175 176 177 178 179 180 | sqlite3_prepare_v2(db, sqlite3_sql(pStmt), -1, &pCk, 0); sqlite3_db_config(db, SQLITE_DBCONFIG_REVERSE_SCANORDER, iOrigRSO, 0); if( eVerbosity>=2 ){ char *zSql = sqlite3_expanded_sql(pCk); printf("invariant-validity-check #2:\n%s\n", zSql); sqlite3_free(zSql); } while( (rc = sqlite3_step(pCk))==SQLITE_ROW ){ for(i=0; i<nCol; i++){ if( !sameValue(pStmt, i, pTestStmt, i, 0) ) break; } if( i>=nCol ) break; } sqlite3_finalize(pCk); | > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | sqlite3_prepare_v2(db, sqlite3_sql(pStmt), -1, &pCk, 0); sqlite3_db_config(db, SQLITE_DBCONFIG_REVERSE_SCANORDER, iOrigRSO, 0); if( eVerbosity>=2 ){ char *zSql = sqlite3_expanded_sql(pCk); printf("invariant-validity-check #2:\n%s\n", zSql); sqlite3_free(zSql); } bindDebugParameters(pCk); while( (rc = sqlite3_step(pCk))==SQLITE_ROW ){ for(i=0; i<nCol; i++){ if( !sameValue(pStmt, i, pTestStmt, i, 0) ) break; } if( i>=nCol ) break; } sqlite3_finalize(pCk); |
︙ | ︙ | |||
195 196 197 198 199 200 201 202 203 204 205 206 207 208 | if( eVerbosity>=2 ){ char *zSql = sqlite3_expanded_sql(pCk); printf("invariant-validity-check #3:\n%s\n", zSql); sqlite3_free(zSql); } sqlite3_reset(pTestStmt); while( (rc = sqlite3_step(pTestStmt))==SQLITE_ROW ){ for(i=0; i<nCol; i++){ if( !sameValue(pStmt, i, pTestStmt, i, pCk) ) break; } if( i>=nCol ){ sqlite3_finalize(pCk); goto not_a_fault; | > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | if( eVerbosity>=2 ){ char *zSql = sqlite3_expanded_sql(pCk); printf("invariant-validity-check #3:\n%s\n", zSql); sqlite3_free(zSql); } sqlite3_reset(pTestStmt); bindDebugParameters(pCk); while( (rc = sqlite3_step(pTestStmt))==SQLITE_ROW ){ for(i=0; i<nCol; i++){ if( !sameValue(pStmt, i, pTestStmt, i, pCk) ) break; } if( i>=nCol ){ sqlite3_finalize(pCk); goto not_a_fault; |
︙ | ︙ | |||
294 295 296 297 298 299 300 301 302 303 304 305 306 307 | sqlite3_str_append(pTest, zIn, (int)nIn); sqlite3_str_append(pTest, ")", 1); rc = sqlite3_prepare_v2(db, sqlite3_str_value(pTest), -1, &pBase, 0); if( rc ){ sqlite3_finalize(pBase); pBase = pStmt; } for(i=0; i<sqlite3_column_count(pStmt); i++){ const char *zColName = sqlite3_column_name(pBase,i); const char *zSuffix = zColName ? strrchr(zColName, ':') : 0; if( zSuffix && isdigit(zSuffix[1]) && (zSuffix[1]>'3' || isdigit(zSuffix[2])) ){ | > | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | sqlite3_str_append(pTest, zIn, (int)nIn); sqlite3_str_append(pTest, ")", 1); rc = sqlite3_prepare_v2(db, sqlite3_str_value(pTest), -1, &pBase, 0); if( rc ){ sqlite3_finalize(pBase); pBase = pStmt; } bindDebugParameters(pBase); for(i=0; i<sqlite3_column_count(pStmt); i++){ const char *zColName = sqlite3_column_name(pBase,i); const char *zSuffix = zColName ? strrchr(zColName, ':') : 0; if( zSuffix && isdigit(zSuffix[1]) && (zSuffix[1]>'3' || isdigit(zSuffix[2])) ){ |
︙ | ︙ |
Changes to test/incrvacuum3.test.
︙ | ︙ | |||
46 47 48 49 50 51 52 | # Now copy the database file itself. Do this using open/read/puts # instead of the [file copy] command in order to avoid attempting # to read the 512 bytes begining at offset $sqlite_pending_byte. # set sz [file size test.db] set fd [open test.db] set fd2 [open test2.db w] | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # Now copy the database file itself. Do this using open/read/puts # instead of the [file copy] command in order to avoid attempting # to read the 512 bytes begining at offset $sqlite_pending_byte. # set sz [file size test.db] set fd [open test.db] set fd2 [open test2.db w] fconfigure $fd -translation binary fconfigure $fd2 -translation binary if {$sz>$::sqlite_pending_byte} { puts -nonewline $fd2 [read $fd $::sqlite_pending_byte] seek $fd [expr $::sqlite_pending_byte+512] seek $fd2 [expr $::sqlite_pending_byte+512] } puts -nonewline $fd2 [read $fd] close $fd2 |
︙ | ︙ |
Changes to test/ioerr.test.
︙ | ︙ | |||
221 222 223 224 225 226 227 | } forcecopy test.db-journal test2.db-journal execsql { COMMIT; } forcecopy test2.db-journal test.db-journal set f [open test.db-journal a] | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | } forcecopy test.db-journal test2.db-journal execsql { COMMIT; } forcecopy test2.db-journal test.db-journal set f [open test.db-journal a] fconfigure $f -translation binary puts -nonewline $f "hello" puts -nonewline $f "\x00\x00\x00\x05\x01\x02\x03\x04" puts -nonewline $f "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" close $f } -sqlbody { SELECT a FROM t1; } |
︙ | ︙ |
Changes to test/ioerr5.test.
︙ | ︙ | |||
113 114 115 116 117 118 119 | set ::sqlite_io_error_hit 0 set ::sqlite_io_error_persist 0 set ::sqlite_io_error_pending 0 # Read the contents of the database file into a Tcl variable. # set fd [open test.db] | | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | set ::sqlite_io_error_hit 0 set ::sqlite_io_error_persist 0 set ::sqlite_io_error_pending 0 # Read the contents of the database file into a Tcl variable. # set fd [open test.db] fconfigure $fd -translation binary set zDatabase [read $fd] close $fd # Set a very low soft-limit and then try to compile an SQL statement # from UTF-16 text. To do this, SQLite will need to reclaim memory # from the pager that is in error state. Including that associated # with the dirty page. # do_test ioerr5-1.$locking_mode-$iFail.3 { sqlite3_soft_heap_limit 1024 compilesql16 "SELECT 10" } {SQLITE_OK} close $channel # Ensure that nothing was written to the database while reclaiming # memory from the pager in error state. # do_test ioerr5-1.$locking_mode-$iFail.4 { set fd [open test.db] fconfigure $fd -translation binary set zDatabase2 [read $fd] close $fd expr {$zDatabase eq $zDatabase2} } {1} if {$rc eq [list 0 {}]} { do_test ioerr5.1-$locking_mode-$iFail.3 { |
︙ | ︙ |
Changes to test/memdb1.test.
︙ | ︙ | |||
241 242 243 244 245 246 247 | CREATE TABLE t1(x, y); INSERT INTO t1 VALUES(1, 2); CREATE TABLE t2(x, y); } {wal} db close set fd [open test.db] | | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | CREATE TABLE t1(x, y); INSERT INTO t1 VALUES(1, 2); CREATE TABLE t2(x, y); } {wal} db close set fd [open test.db] fconfigure $fd -translation binary set data [read $fd [expr 20*1024]] close $fd sqlite3 db "" db deserialize $data do_execsql_test 810 { |
︙ | ︙ |
Changes to test/misc3.test.
︙ | ︙ | |||
84 85 86 87 88 89 90 | do_test misc3-2.3 { execsql {SELECT 000000000002e-0000000025*0.5e25} } 1.0 do_test misc3-2.4 { execsql {SELECT 2e-25*0.5e250} } 1e+225 do_test misc3-2.5 { | | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | do_test misc3-2.3 { execsql {SELECT 000000000002e-0000000025*0.5e25} } 1.0 do_test misc3-2.4 { execsql {SELECT 2e-25*0.5e250} } 1e+225 do_test misc3-2.5 { execsql {SELECT format('%.15e',2.0e-250*0.5e25)} } {1.0000000000000e-225} do_test misc3-2.6 { execsql {SELECT '-2.0e-127' * '-0.5e27'} } 1e-100 do_test misc3-2.7 { execsql {SELECT '+2.0e-127' * '-0.5e27'} } -1e-100 do_test misc3-2.8 { |
︙ | ︙ |
Changes to test/nan.test.
︙ | ︙ | |||
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | -[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT x, typeof(x) FROM t1} } {0.0 real} # These tests test some really, really small floating point numbers. # if {$tcl_platform(platform) != "symbian"} { # These two are not run on symbian because tcl has trouble converting # the very small numbers back to text form (probably due to a difference # in the sprintf() implementation). # do_test nan-4.15 { db eval {DELETE FROM t1} set small \ [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" | > | | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | -[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT x, typeof(x) FROM t1} } {0.0 real} # These tests test some really, really small floating point numbers. # load_static_extension db decimal if {$tcl_platform(platform) != "symbian"} { # These two are not run on symbian because tcl has trouble converting # the very small numbers back to text form (probably due to a difference # in the sprintf() implementation). # do_test nan-4.15 { db eval {DELETE FROM t1} set small \ [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT decimal_exp(x), typeof(x) FROM t1} } {/9\.88131291682493\d*e-324 real/} do_test nan-4.16 { db eval {DELETE FROM t1} set small \ -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT decimal_exp(x), typeof(x) FROM t1} } {/-9\.88131291682493\d*e-324 real/} } do_test nan-4.17 { db eval {DELETE FROM t1} set small [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" db eval {SELECT CAST(x AS text), typeof(x) FROM t1} } {9.88131291682493e-324 real} |
︙ | ︙ |
Changes to test/pendingrace.test.
︙ | ︙ | |||
57 58 59 60 61 62 63 | } db_save db2 close proc my_db_restore {} { forcecopy sv_test.db-journal test.db-journal set fd1 [open sv_test.db r] | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | } db_save db2 close proc my_db_restore {} { forcecopy sv_test.db-journal test.db-journal set fd1 [open sv_test.db r] fconfigure $fd1 -translation binary set data [read $fd1] close $fd1 set fd1 [open test.db w] fconfigure $fd1 -translation binary puts -nonewline $fd1 $data close $fd1 } my_db_restore do_test 1.2 { file exists test.db-journal } {1} |
︙ | ︙ |
Changes to test/readonly.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # # This file contains tests for using databases in read-only mode on # unix. # set testdir [file dirname $argv0] source $testdir/tester.tcl | | > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # # This file contains tests for using databases in read-only mode on # unix. # set testdir [file dirname $argv0] source $testdir/tester.tcl if {$tcl_platform(platform)=="windows"} { finish_test return } source $testdir/lock_common.tcl source $testdir/wal_common.tcl set ::testprefix readonly do_execsql_test 1.0 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6); |
︙ | ︙ |
Changes to test/recover.test.
︙ | ︙ | |||
39 40 41 42 43 44 45 | compare_result $db1 $db2 "SELECT * FROM $tbl" } } proc recover_with_opts {opts} { set cmd ".recover $opts" set fd [open [list |$::CLI test.db $cmd]] | < | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | compare_result $db1 $db2 "SELECT * FROM $tbl" } } proc recover_with_opts {opts} { set cmd ".recover $opts" set fd [open [list |$::CLI test.db $cmd]] fconfigure $fd -translation binary set sql [read $fd] close $fd forcedelete test.db2 sqlite3 db2 test.db2 execsql $sql db2 |
︙ | ︙ |
Changes to test/rollback.test.
︙ | ︙ | |||
107 108 109 110 111 112 113 | foreach i $a { incr cksum $i } set mj_pgno [expr $sqlite_pending_byte / 1024] set zAppend [binary format Ia*IIa8 $mj_pgno $mj [string length $mj] $cksum \ "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" ] set iOffset [expr (([file size testA.db-journal] + 511)/512)*512] set fd [open testA.db-journal a+] | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | foreach i $a { incr cksum $i } set mj_pgno [expr $sqlite_pending_byte / 1024] set zAppend [binary format Ia*IIa8 $mj_pgno $mj [string length $mj] $cksum \ "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" ] set iOffset [expr (([file size testA.db-journal] + 511)/512)*512] set fd [open testA.db-journal a+] fconfigure $fd -translation binary seek $fd $iOffset puts -nonewline $fd $zAppend # Also, fix the first journal-header in the journal-file. Because the # journal file has not yet been synced, the 8-byte magic string at the # start of the first journal-header has not been written by SQLite. # So write it now. |
︙ | ︙ |
Changes to test/scanstatus2.test.
︙ | ︙ | |||
261 262 263 264 265 266 267 | CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN SELECT 1; END; INSERT INTO t1 VALUES(1, 2); } proc trace {stmt sql} { | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN SELECT 1; END; INSERT INTO t1 VALUES(1, 2); } proc trace {stmt sql} { array set A [sqlite3_stmt_scanstatus -flags complex [format %llx $stmt] 0] lappend ::trace_explain $A(zExplain) } db trace_v2 trace set ::trace_explain [list] do_execsql_test 5.1 { DELETE FROM t1 WHERE x=1; |
︙ | ︙ |
Changes to test/select7.test.
︙ | ︙ | |||
150 151 152 153 154 155 156 157 158 159 160 161 162 163 | append sql { UNION ALL SELECT 99999999} do_test select7-6.2 { catchsql $sql } {1 {too many terms in compound SELECT}} } } } # This block of tests verifies that bug aa92c76cd4 is fixed. # do_test select7-7.1 { execsql { CREATE TABLE t3(a REAL); INSERT INTO t3 VALUES(44.0); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | append sql { UNION ALL SELECT 99999999} do_test select7-6.2 { catchsql $sql } {1 {too many terms in compound SELECT}} } } } # https://issues.chromium.org/issues/358174302 # Need to support an unlimited number of terms in a VALUES clause, even # if some of those terms contain double-quoted string literals. # do_execsql_test select7-6.5 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(a,b,c); } sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 10 sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 0 do_catchsql_test select7-6.6 { INSERT INTO t1 VALUES (NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0), (0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""), (0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""), (0,NULL,0), (X'',X'',0.0); } {1 {no such column: "" - should this be a string literal in single-quotes?}} do_execsql_test select7-6.7 { SELECT count(*) FROM t1; } {0} sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1 do_catchsql_test select7-6.8 { INSERT INTO t1 VALUES (NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0), (0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""), (0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""), (0,NULL,0), (X'',X'',0.0); } {0 {}} do_execsql_test select7-6.9 { SELECT count(*) FROM t1; } {16} # This block of tests verifies that bug aa92c76cd4 is fixed. # do_test select7-7.1 { execsql { CREATE TABLE t3(a REAL); INSERT INTO t3 VALUES(44.0); |
︙ | ︙ |
Changes to test/shell1.test.
︙ | ︙ | |||
1055 1056 1057 1058 1059 1060 1061 | # return character (and on Windows, the end-of-file character) # cannot be used here. # if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { continue } # Tcl 8.7 maps 0x80 through 0x9f into valid UTF8. So skip those tests. | | | 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 | # return character (and on Windows, the end-of-file character) # cannot be used here. # if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { continue } # Tcl 8.7 maps 0x80 through 0x9f into valid UTF8. So skip those tests. if {$i>=0x80 && ($i<=0x9F || $tcl_version>=9.0)} continue if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue set hex [format %02X $i] set char [subst \\x$hex]; set oldChar $char set escapes [list] if {$tcl_platform(platform)=="windows"} { # |
︙ | ︙ |
Changes to test/shell5.test.
︙ | ︙ | |||
406 407 408 409 410 411 412 | } {xy\" hello one 2 {} {}} #---------------------------------------------------------------------------- # Tests for the shell "ascii" import/export mode. # do_test shell5-3.1 { set fd [open shell5.csv w] | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | } {xy\" hello one 2 {} {}} #---------------------------------------------------------------------------- # Tests for the shell "ascii" import/export mode. # do_test shell5-3.1 { set fd [open shell5.csv w] fconfigure $fd -translation binary puts -nonewline $fd "\"test 1\"\x1F,test 2\r\n\x1E" puts -nonewline $fd "test 3\x1Ftest 4\n" close $fd catchcmd test.db { .mode ascii CREATE TABLE t5(a, b); .import shell5.csv t5 |
︙ | ︙ |
Changes to test/shell7.test.
︙ | ︙ | |||
29 30 31 32 33 34 35 | INSERT INTO f1 VALUES(2, X'01000304'); INSERT INTO f1 VALUES(3, randomblob(200)); } foreach {tn l x} [db eval { SELECT tn, length(x) AS l, x FROM f1 }] { forcedelete shell7_test.bin set fd [open shell7_test.bin w] | < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | INSERT INTO f1 VALUES(2, X'01000304'); INSERT INTO f1 VALUES(3, randomblob(200)); } foreach {tn l x} [db eval { SELECT tn, length(x) AS l, x FROM f1 }] { forcedelete shell7_test.bin set fd [open shell7_test.bin w] fconfigure $fd -translation binary puts -nonewline $fd $x close $fd do_test 1.$tn.1 { file size shell7_test.bin } $l do_test 1.$tn.2 { catchcmd test.db "INSERT INTO f2 VALUES($tn, readfile('shell7_test.bin'));" |
︙ | ︙ |
Changes to test/superlock.test.
︙ | ︙ | |||
162 163 164 165 166 167 168 | do_test 5.$tn.18 { sql1 { SELECT * FROM t1 } } {1 2 3 4 5 6} do_test 5.$tn.19 { sql2 { SELECT * FROM t1 } } {1 2 3 4 5 6} } proc read_content {file} { if {[file exists $file]==0} {return ""} set fd [open $file] | | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | do_test 5.$tn.18 { sql1 { SELECT * FROM t1 } } {1 2 3 4 5 6} do_test 5.$tn.19 { sql2 { SELECT * FROM t1 } } {1 2 3 4 5 6} } proc read_content {file} { if {[file exists $file]==0} {return ""} set fd [open $file] fconfigure $fd -translation binary set content [read $fd] close $fd return $content } proc write_content {file content} { set fd [open $file w+] fconfigure $fd -translation binary puts -nonewline $fd $content close $fd } # Both $file1 and $file2 are database files. This function takes a # superlock on each, then exchanges the content of the two files (i.e. # overwrites $file1 with the initial contents of $file2, and overwrites |
︙ | ︙ |
Changes to test/syscall.test.
︙ | ︙ | |||
207 208 209 210 211 212 213 | # file. Whereas a file 2 bytes or larger might be considered corrupt. # catch { db close } forcedelete test.db test.db2 proc create_db_file {nByte} { set fd [open test.db w] | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | # file. Whereas a file 2 bytes or larger might be considered corrupt. # catch { db close } forcedelete test.db test.db2 proc create_db_file {nByte} { set fd [open test.db w] fconfigure $fd -translation binary puts -nonewline $fd [string range "xSQLite" 1 $nByte] close $fd } foreach {nByte res} { 1 {0 {}} 2 {1 {file is not a database}} |
︙ | ︙ |
Changes to test/tester.tcl.
︙ | ︙ | |||
306 307 308 309 310 311 312 | } else { file delete $filename } } } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | } else { file delete $filename } } } } proc execpresql {handle args} { trace remove execution $handle enter [list execpresql $handle] if {[info exists ::G(perm:presql)]} { $handle eval $::G(perm:presql) } } |
︙ | ︙ | |||
843 844 845 846 847 848 849 850 851 852 853 854 855 856 | set e [string range $expected 1 end] set ok [expr {![string match $e $result]}] } else { set ok [string match $expected $result] } } else { set ok [expr {[string compare $result $expected]==0}] } if {!$ok} { # if {![info exists ::testprefix] || $::testprefix eq ""} { # error "no test prefix" # } output1 "" output2 "! $name expected: \[$expected\]\n! $name got: \[$result\]" | > > > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | set e [string range $expected 1 end] set ok [expr {![string match $e $result]}] } else { set ok [string match $expected $result] } } else { set ok [expr {[string compare $result $expected]==0}] if {!$ok} { set ok [fpnum_compare $result $expected] } } if {!$ok} { # if {![info exists ::testprefix] || $::testprefix eq ""} { # error "no test prefix" # } output1 "" output2 "! $name expected: \[$expected\]\n! $name got: \[$result\]" |
︙ | ︙ | |||
893 894 895 896 897 898 899 | set rc [catch { eval $line } msg] list $rc $msg } proc catchcmdex {db {cmd ""}} { global CLI set out [open cmds.txt w] | | | | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | set rc [catch { eval $line } msg] list $rc $msg } proc catchcmdex {db {cmd ""}} { global CLI set out [open cmds.txt w] fconfigure $out -translation binary puts -nonewline $out $cmd close $out set line "exec -keepnewline -- $CLI $db < cmds.txt" set chans [list stdin stdout stderr] foreach chan $chans { catch { set modes($chan) [fconfigure $chan] fconfigure $chan -translation binary -buffering none } } set rc [catch { eval $line } msg] foreach chan $chans { catch { eval fconfigure [list $chan] $modes($chan) } |
︙ | ︙ |
Changes to test/testrunner.tcl.
︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 | proc usage {} { set a0 [file tail $::argv0] puts stderr [string trim [subst -nocommands { Usage: $a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS? $a0 PERMUTATION FILE $a0 help $a0 njob ?NJOB? $a0 script ?-msvc? CONFIG | > | > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | proc usage {} { set a0 [file tail $::argv0] puts stderr [string trim [subst -nocommands { Usage: $a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS? $a0 PERMUTATION FILE $a0 errors ?-v|--verbose? $a0 help $a0 njob ?NJOB? $a0 script ?-msvc? CONFIG $a0 status ?-d SECS? ?--cls? where SWITCHES are: --buildonly Build test exes but do not run tests --config CONFIGS Only use configs on comma-separate list CONFIGS --dryrun Write what would have happened to testrunner.log --explain Write summary to stdout --jobs NUM Run tests using NUM separate processes --omit CONFIGS Omit configs on comma-separated list CONFIGS --status Show the full "status" report while running --stop-on-coredump Stop running if any test segfaults --stop-on-error Stop running after any reported error --zipvfs ZIPVFSDIR ZIPVFS source directory Special values for PERMUTATION that work with plain tclsh: list - show all allowed PERMUTATION arguments. |
︙ | ︙ | |||
96 97 98 99 100 101 102 | If a PERMUTATION is specified and is followed by the path to a Tcl script instead of a list of patterns, then that single Tcl test script is run with the specified permutation. The "status" and "njob" commands are designed to be run from the same directory as a running testrunner.tcl script that is running tests. The "status" command prints a report describing the current state and progress | > | | > > > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | If a PERMUTATION is specified and is followed by the path to a Tcl script instead of a list of patterns, then that single Tcl test script is run with the specified permutation. The "status" and "njob" commands are designed to be run from the same directory as a running testrunner.tcl script that is running tests. The "status" command prints a report describing the current state and progress of the tests. Use the "-d N" option to have the status display clear the screen and repeat every N seconds. The "njob" command may be used to query or modify the number of sub-processes the test script uses to run tests. The "script" command outputs the script used to build a configuration. Add the "-msvc" option for a Windows-compatible script. For a list of available configurations enter "$a0 script help". The "errors" commands shows the output of all tests that failed in the most recent run. Complete output is shown if the -v or --verbose options are used. Otherwise, an attempt is made to minimize the output to show only the parts that contain the error messages. Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md }]] exit 1 } #------------------------------------------------------------------------- |
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 | set TRG(buildonly) 0 ;# True if --buildonly option set TRG(config) {} ;# Only build the named configurations set TRG(omitconfig) {} ;# Do not build these configurations set TRG(dryrun) 0 ;# True if --dryrun option set TRG(explain) 0 ;# True for the --explain option set TRG(stopOnError) 0 ;# Stop running at first failure set TRG(stopOnCore) 0 ;# Stop on a core-dump switch -nocase -glob -- $tcl_platform(os) { *darwin* { set TRG(platform) osx set TRG(make) make.sh set TRG(makecmd) "bash make.sh" set TRG(testfixture) testfixture | > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | set TRG(buildonly) 0 ;# True if --buildonly option set TRG(config) {} ;# Only build the named configurations set TRG(omitconfig) {} ;# Do not build these configurations set TRG(dryrun) 0 ;# True if --dryrun option set TRG(explain) 0 ;# True for the --explain option set TRG(stopOnError) 0 ;# Stop running at first failure set TRG(stopOnCore) 0 ;# Stop on a core-dump set TRG(fullstatus) 0 ;# Full "status" report while running switch -nocase -glob -- $tcl_platform(os) { *darwin* { set TRG(platform) osx set TRG(make) make.sh set TRG(makecmd) "bash make.sh" set TRG(testfixture) testfixture |
︙ | ︙ | |||
375 376 377 378 379 380 381 | set bMsvc [expr ([llength $argv]==3)] set config [lindex $argv [expr [llength $argv]-1]] puts [trd_buildscript $config [file dirname $testdir] $bMsvc] exit } | | | < < < < < < | | < | < | > | > | | > > > > > | < | | | | > > > > | | | > > > > > > > > > | | | > | | | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | set bMsvc [expr ([llength $argv]==3)] set config [lindex $argv [expr [llength $argv]-1]] puts [trd_buildscript $config [file dirname $testdir] $bMsvc] exit } # Helper routine for show_status # proc display_job {jobdict {tm ""}} { array set job $jobdict set dfname [format %-60s $job(displayname)] set dtm "" if {$tm!=""} { set dtm [format %-10s "\[[expr {$tm-$job(starttime)}]ms\]"] } puts " $dfname $dtm" } # This procedure shows the "status" page. It uses the database # connect passed in as the "db" parameter. If the "cls" parameter # is true, then VT100 escape codes are used to format the display. # proc show_status {db cls} { global TRG $db eval BEGIN if {[catch { set cmdline [$db one { SELECT value FROM config WHERE name='cmdline' }] set nJob [$db one { SELECT value FROM config WHERE name='njob' }] } msg]} { if {$cls} {puts "\033\[H\033\[2J"} puts "Cannot read database: $TRG(dbname)" return } set now [clock_milliseconds] set tm [$db one { SELECT COALESCE((SELECT value FROM config WHERE name='end'), $now) - (SELECT value FROM config WHERE name='start') }] set total 0 foreach s {"" ready running done failed} { set S($s) 0 } $db eval { SELECT state, count(*) AS cnt FROM jobs GROUP BY 1 } { incr S($state) $cnt incr total $cnt } set fin [expr $S(done)+$S(failed)] if {$cmdline!=""} {set cmdline " $cmdline"} if {$cls} { # Move the cursor to the top-left corner. Each iteration will simply # overwrite. puts -nonewline "\033\[H" flush stdout set clreol "\033\[K" } else { set clreol "" } set f "" if {$S(failed)>0} { set f "$S(failed) FAILED, " } 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: " $db eval { SELECT * FROM jobs WHERE state='running' ORDER BY starttime } job { display_job [array get job] $now } } if {$S(failed)>0} { puts "Failures: " $db eval { SELECT * FROM jobs WHERE state='failed' ORDER BY starttime } job { display_job [array get job] } set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}] if {$nOmit} { 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. # for {set ii 0} {$ii < [llength $argv]} {incr ii} { |
︙ | ︙ | |||
486 487 488 489 490 491 492 493 494 495 496 497 498 499 | } elseif {($n>2 && [string match "$a*" --omit]) || $a=="-c"} { incr ii set TRG(omitconfig) [lindex $argv $ii] } elseif {[string match "$a*" --stop-on-error]} { set TRG(stopOnError) 1 } elseif {[string match "$a*" --stop-on-coredump]} { set TRG(stopOnCore) 1 } else { usage } } else { lappend TRG(patternlist) [string map {% *} $a] } } | > > > > > > > > > > | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 | } elseif {($n>2 && [string match "$a*" --omit]) || $a=="-c"} { incr ii set TRG(omitconfig) [lindex $argv $ii] } elseif {[string match "$a*" --stop-on-error]} { 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 } } else { lappend TRG(patternlist) [string map {% *} $a] } } |
︙ | ︙ | |||
599 600 601 602 603 604 605 | set ret [array get job] } } return $ret } | < < < < < < | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | set ret [array get job] } } return $ret } # Usage: # # add_job OPTION ARG OPTION ARG... # # where available OPTIONS are: # # -displaytype |
︙ | ︙ | |||
959 960 961 962 963 964 965 966 967 968 969 970 971 972 | } } } proc make_new_testset {} { global TRG r_write_db { trdb eval $TRG(schema) set nJob $TRG(nJob) set cmdline $TRG(cmdline) set tm [clock_milliseconds] trdb eval { REPLACE INTO config VALUES('njob', $nJob ); } trdb eval { REPLACE INTO config VALUES('cmdline', $cmdline ); } | > | 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 | } } } proc make_new_testset {} { global TRG trdb eval {PRAGMA journal_mode=WAL;} r_write_db { trdb eval $TRG(schema) set nJob $TRG(nJob) set cmdline $TRG(cmdline) set tm [clock_milliseconds] trdb eval { REPLACE INTO config VALUES('njob', $nJob ); } trdb eval { REPLACE INTO config VALUES('cmdline', $cmdline ); } |
︙ | ︙ | |||
1113 1114 1115 1116 1117 1118 1119 | set fd [open $TRG(run) w] puts $fd $set_tmp_dir puts $fd $job(cmd) close $fd set fd [open "|$TRG(runcmd) 2>@1" r] cd $pwd | | > > | > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 | set fd [open $TRG(run) w] puts $fd $set_tmp_dir puts $fd $job(cmd) close $fd set fd [open "|$TRG(runcmd) 2>@1" r] cd $pwd fconfigure $fd -blocking false -translation binary fileevent $fd readable [list script_input_ready $fd $iJob $job(jobid)] } return 1 } # Show the testing progress report # proc progress_report {} { global TRG if {$TRG(fullstatus)} { if {$::tcl_platform(platform)=="windows"} { exec [info nameofexe] $::argv0 status --cls } else { show_status trdb 1 } } else { 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) progress_report } proc launch_some_jobs {} { global TRG set nJob [trdb one { SELECT value FROM config WHERE name='njob' }] while {[dirs_nHelper]<$nJob} { |
︙ | ︙ | |||
1187 1188 1189 1190 1191 1192 1193 | set ii 0 set TRG(starttime) [clock_milliseconds] set TRG(log) [open $TRG(logname) w] launch_some_jobs | > | | | 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 | set ii 0 set TRG(starttime) [clock_milliseconds] set TRG(log) [open $TRG(logname) w] launch_some_jobs if {$TRG(fullstatus)} {puts "\033\[2J"} progress_report while {[dirs_nHelper]>0} { after 500 {incr ::wakeup} vwait ::wakeup } close $TRG(log) progress_report r_write_db { set tm [clock_milliseconds] trdb eval { REPLACE INTO config VALUES('end', $tm ); } set nErr [trdb one {SELECT count(*) FROM jobs WHERE state='failed'}] if {$nErr>0} { puts "$nErr failures:" |
︙ | ︙ |
Changes to test/testrunner_data.tcl.
︙ | ︙ | |||
482 483 484 485 486 487 488 | exit -1 fi SRCDIR="$srcdir" TCLDIR="$tcldir" if [ ! -f Makefile ] ; then | | | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | exit -1 fi SRCDIR="$srcdir" TCLDIR="$tcldir" if [ ! -f Makefile ] ; then \$SRCDIR/configure --with-tcl=\$TCLDIR $configOpts fi $myopts CFLAGS="$cflags" make \$1 "CFLAGS=\$CFLAGS" "OPTS=\$OPTS" $makeOpts }]] |
︙ | ︙ |
Changes to test/tkt-2d1a5c67d.test.
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | INSERT INTO t4 VALUES('xyz'); } do_test 3.4 { set blobs [list] for {set i 1} {$i<100} {incr i} { set b [db incrblob -readonly t3 b $i] read $b lappend blobs $b } execsql COMMIT execsql { SELECT * FROM t4 WHERE a = 'xyz' } } {xyz} | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | INSERT INTO t4 VALUES('xyz'); } do_test 3.4 { set blobs [list] for {set i 1} {$i<100} {incr i} { set b [db incrblob -readonly t3 b $i] fconfigure $b -translation binary read $b lappend blobs $b } execsql COMMIT execsql { SELECT * FROM t4 WHERE a = 'xyz' } } {xyz} |
︙ | ︙ |
Changes to test/tkt3457.test.
︙ | ︙ | |||
54 55 56 57 58 59 60 | forcecopy test.db-journal bak.db-journal # Fix the first journal-header in the journal-file. Because the # journal file has not yet been synced, the 8-byte magic string at the # start of the first journal-header has not been written by SQLite. # So write it now. set fd [open bak.db-journal a+] | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | forcecopy test.db-journal bak.db-journal # Fix the first journal-header in the journal-file. Because the # journal file has not yet been synced, the 8-byte magic string at the # start of the first journal-header has not been written by SQLite. # So write it now. set fd [open bak.db-journal a+] fconfigure $fd -translation binary seek $fd 0 puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" close $fd execsql COMMIT } {} |
︙ | ︙ |
Changes to test/types3.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # set testdir [file dirname $argv0] source $testdir/tester.tcl # A variable with only a string representation comes in as TEXT do_test types3-1.1 { | | < | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # set testdir [file dirname $argv0] source $testdir/tester.tcl # A variable with only a string representation comes in as TEXT do_test types3-1.1 { set V [format %s xxxxx] concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] } {text} # A variable with an integer representation comes in as INTEGER do_test types3-1.2 { set V [expr {int(1+2)}] concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] } {int integer} set V [expr {1+12345678012345}] |
︙ | ︙ |
Changes to test/vtabH.test.
︙ | ︙ | |||
124 125 126 127 128 129 130 | #------------------------------------------------------------------------- # if {$tcl_platform(platform)=="windows"} { set drive [string range [pwd] 0 1] set ::env(fstreeDrive) $drive } | < < | | > > | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #------------------------------------------------------------------------- # if {$tcl_platform(platform)=="windows"} { set drive [string range [pwd] 0 1] set ::env(fstreeDrive) $drive } reset_db register_fs_module db if {$tcl_platform(platform)!="windows" || \ [regexp -nocase -- {^[A-Z]:} $drive]} { do_execsql_test 3.0 { SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db'; SELECT name FROM fsdir WHERE dir = '.' AND name = '.' } {test.db .} proc sort_files { names {nocase false} } { if {$nocase && $::tcl_platform(platform) eq "windows"} { |
︙ | ︙ |
Changes to test/wal.test.
︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | append walhdr [binary format II $c1 $c2] logcksum c1 c2 [string range $framehdr 0 7] logcksum c1 c2 $framebody set framehdr [binary format IIIIII $pg 5 22 23 $c1 $c2] set fd [open test.db-wal w] | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | append walhdr [binary format II $c1 $c2] logcksum c1 c2 [string range $framehdr 0 7] logcksum c1 c2 $framebody set framehdr [binary format IIIIII $pg 5 22 23 $c1 $c2] set fd [open test.db-wal w] fconfigure $fd -translation binary puts -nonewline $fd $walhdr puts -nonewline $fd $framehdr puts -nonewline $fd $framebody close $fd file size test.db-wal } [wal_file_size 1 $pgsz] |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
1094 1095 1096 1097 1098 1099 1100 | foreach {tn permissions} { 1 00644 2 00666 3 00600 4 00755 } { | > > > | > | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 | foreach {tn permissions} { 1 00644 2 00666 3 00600 4 00755 } { if {$tcl_version>=9.0} { set effective [format %.5d [expr $permissions & ~$umask]] } else { set effective [format %.5o [expr $permissions & ~$umask]] } do_test wal2-12.2.$tn.1 { file attributes test.db -permissions $permissions string map {o 0} [file attributes test.db -permissions] } $permissions do_test wal2-12.2.$tn.2 { list [file exists test.db-wal] [file exists test.db-shm] } {0 0} |
︙ | ︙ |
Changes to test/wal_common.tcl.
︙ | ︙ | |||
61 62 63 64 65 66 67 | set c1 0 set c2 0 wal_cksum $endian c1 c2 $blob append blob [binary format II $c1 $c2] set fd [open $filename r+] fconfigure $fd -translation binary | < < < < | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | set c1 0 set c2 0 wal_cksum $endian c1 c2 $blob append blob [binary format II $c1 $c2] set fd [open $filename r+] fconfigure $fd -translation binary seek $fd 0 puts -nonewline $fd $blob close $fd } set fd [open $filename] fconfigure $fd -translation binary set blob [read $fd 24] close $fd binary scan $blob I6 ints set ints } proc wal_fix_walindex_cksum {hdrvar} { upvar $hdrvar hdr set c1 0 set c2 0 wal_cksum_intlist c1 c2 [lrange $hdr 0 9] lset hdr 10 $c1 lset hdr 11 $c2 } |
Changes to test/walcksum.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ifcapable !wal {finish_test ; return } # Read and return the contents of file $filename. Treat the content as # binary data. # proc readfile {filename} { set fd [open $filename] | < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ifcapable !wal {finish_test ; return } # Read and return the contents of file $filename. Treat the content as # binary data. # proc readfile {filename} { set fd [open $filename] fconfigure $fd -translation binary set data [read $fd] close $fd return $data } # |
︙ | ︙ | |||
55 56 57 58 59 60 61 | proc log_checksum_write {filename iFrame endian} { set data [readfile $filename] foreach {offset c1 c2} [log_checksum_calc $data $iFrame $endian] {} set bin [binary format II $c1 $c2] set fd [open $filename r+] | < | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | proc log_checksum_write {filename iFrame endian} { set data [readfile $filename] foreach {offset c1 c2} [log_checksum_calc $data $iFrame $endian] {} set bin [binary format II $c1 $c2] set fd [open $filename r+] fconfigure $fd -translation binary seek $fd $offset puts -nonewline $fd $bin close $fd } # Calculate and return the checksum for a particular frame in a WAL. |
︙ | ︙ | |||
110 111 112 113 114 115 116 | # Also update the wal header checksum (since the wal header contents may # have changed). # proc log_checksum_writemagic {filename endian} { set val [expr {0x377f0682 | ($endian == "big" ? 1 : 0)}] set bin [binary format I $val] set fd [open $filename r+] | < | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # Also update the wal header checksum (since the wal header contents may # have changed). # proc log_checksum_writemagic {filename endian} { set val [expr {0x377f0682 | ($endian == "big" ? 1 : 0)}] set bin [binary format I $val] set fd [open $filename r+] fconfigure $fd -translation binary puts -nonewline $fd $bin seek $fd 0 set blob [read $fd 24] set c1 0 set c2 0 |
︙ | ︙ |
Changes to test/walslow.test.
︙ | ︙ | |||
105 106 107 108 109 110 111 | foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { do_test 3.3.$incr { set FAIL 0 for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { forcecopy test.db-wal test2.db-wal set fd [open test2.db-wal r+] | < | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { do_test 3.3.$incr { set FAIL 0 for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { forcecopy test.db-wal test2.db-wal set fd [open test2.db-wal r+] fconfigure $fd -translation binary seek $fd $iOff binary scan [read $fd 1] c x seek $fd $iOff puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]] close $fd |
︙ | ︙ |
Changes to test/win32longpath.test.
︙ | ︙ | |||
45 46 47 48 49 50 51 | } } {1 2 3 4} set longPath(1) \\\\?\\$path\\[pid] set uriPath(1a) %5C%5C%3F%5C$path\\[pid] set uriPath(1b) %5C%5C%3F%5C$rawPath/[pid] | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | } } {1 2 3 4} set longPath(1) \\\\?\\$path\\[pid] set uriPath(1a) %5C%5C%3F%5C$path\\[pid] set uriPath(1b) %5C%5C%3F%5C$rawPath/[pid] file mkdir $longPath(1) set longPath(2) $longPath(1)\\[string repeat X 255] set uriPath(2a) $uriPath(1a)\\[string repeat X 255] set uriPath(2b) $uriPath(1b)/[string repeat X 255] file mkdir $longPath(2) set longPath(3) $longPath(2)\\[string repeat Y 255] set uriPath(3a) $uriPath(2a)\\[string repeat Y 255] set uriPath(3b) $uriPath(2b)/[string repeat Y 255] file mkdir $longPath(3) set fileName $longPath(3)\\test.db set uri(1a) file:$uriPath(3a)\\test.db set uri(1b) file:$uriPath(3b)/test.db set uri(1c) file:///$uriPath(3a)\\test.db set uri(1d) file:///$uriPath(3b)/test.db |
︙ | ︙ | |||
88 89 90 91 92 93 94 | INSERT INTO t1 VALUES(8); SELECT x FROM t1 ORDER BY x; COMMIT; } } {5 6 7 8} db3 close | < | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | INSERT INTO t1 VALUES(8); SELECT x FROM t1 ORDER BY x; COMMIT; } } {5 6 7 8} db3 close sqlite3 db3 $fileName -vfs win32-longpath do_test 1.5 { db3 eval { PRAGMA journal_mode = WAL; } |
︙ | ︙ | |||
111 112 113 114 115 116 117 | INSERT INTO t1 VALUES(12); SELECT x FROM t1 ORDER BY x; COMMIT; } } {5 6 7 8 9 10 11 12} db3 close | < < < | | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | INSERT INTO t1 VALUES(12); SELECT x FROM t1 ORDER BY x; COMMIT; } } {5 6 7 8 9 10 11 12} db3 close foreach tn {1a 1b 1c 1d 1e 1f} { sqlite3 db3 $uri($tn) -vfs win32-longpath -uri 1 -translatefilename 0 do_test 1.7.$tn { db3 eval { SELECT x FROM t1 ORDER BY x; } } {5 6 7 8 9 10 11 12} db3 close } file delete -force $fileName file delete -force $longPath(3) file delete -force $longPath(2) file delete -force $longPath(1) finish_test |
Changes to test/zipfile.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2017 December 9 # # 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. # #*********************************************************************** # | > | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # 2017 December 9 # # 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. # #*********************************************************************** # if {$tcl_version<8.6} { puts "Requires TCL 8.6 or later" return } set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix zipfile ifcapable !vtab { finish_test; return } if {[catch {load_static_extension db zipfile} error]} { puts "Skipping zipfile tests, hit load error: $error" finish_test; return } if {[catch {load_static_extension db fileio} error]} { puts "Skipping zipfile tests, hit load error: $error" finish_test; return } proc readfile {f} { set fd [open $f] fconfigure $fd -translation binary set data [read $fd] close $fd set data } unset -nocomplain ::UNZIP |
︙ | ︙ |
Changes to test/zipfile2.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2018 January 30 # # 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. # #*********************************************************************** # | > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # 2018 January 30 # # 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. # #*********************************************************************** # if {$tcl_version<8.6} { puts "Requires TCL 8.6 or later" return } set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix zipfile2 ifcapable !vtab { finish_test; return |
︙ | ︙ |
Added tool/buildtclext.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 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 } |
Added tool/find_tclconfig.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 |
Changes to tool/mkmsvcmin.tcl.
︙ | ︙ | |||
19 20 21 22 23 24 25 | if {[file exists $toFileName]} { error "output file \"$toFileName\" already exists" } } proc readFile { fileName } { set file_id [open $fileName RDONLY] | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | if {[file exists $toFileName]} { error "output file \"$toFileName\" already exists" } } proc readFile { fileName } { set file_id [open $fileName RDONLY] fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result } proc writeFile { fileName data } { set file_id [open $fileName {WRONLY CREAT TRUNC}] fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" } proc escapeSubSpec { data } { regsub -all -- {&} $data {\\\&} data |
︙ | ︙ |
Changes to tool/mkvsix.tcl.
︙ | ︙ | |||
152 153 154 155 156 157 158 | proc readFile { fileName } { # # NOTE: Reads and returns the entire contents of the specified file, which # may contain binary data. # set file_id [open $fileName RDONLY] | | | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | proc readFile { fileName } { # # NOTE: Reads and returns the entire contents of the specified file, which # may contain binary data. # set file_id [open $fileName RDONLY] fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result } proc writeFile { fileName data } { # # NOTE: Writes the entire contents of the specified file, which may contain # binary data. # set file_id [open $fileName {WRONLY CREAT TRUNC}] fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" } # # TODO: Modify this procedure when a new version of Visual Studio is released. |
︙ | ︙ |
Changes to tool/replace.tcl.
1 2 3 4 5 6 | #!/usr/bin/tcl # # Replace string with another string -OR- include # only lines successfully modified with a regular # expression. # | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/tcl # # Replace string with another string -OR- include # only lines successfully modified with a regular # expression. # fconfigure stdout -translation binary fconfigure stderr -translation binary set mode [string tolower [lindex $argv 0]] set from [lindex $argv 1] set to [lindex $argv 2] if {-1 == [lsearch -exact [list exact regsub include] $mode]} {exit 1} if {[string length $from]==0} {exit 2} while {![eof stdin]} { set line [gets stdin] |
︙ | ︙ |
Changes to tool/restore_jrnl.tcl.
︙ | ︙ | |||
119 120 121 122 123 124 125 | $jrnl_pgno $db_pgno] puts [ format {nonce: %08x chksum: %08x} \ $nonce $chksum] # now hex dump the data # This is derived from the Tcler's WIKI set fid [open $jrnl_name r] | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | $jrnl_pgno $db_pgno] puts [ format {nonce: %08x chksum: %08x} \ $nonce $chksum] # now hex dump the data # This is derived from the Tcler's WIKI set fid [open $jrnl_name r] fconfigure $fid -translation binary seek $fid [expr $jrnl_pg_offset+4] set data [read $fid $db_pgsz] close $fid for {set addr 0} {$addr<$db_pgsz} {set addr [expr $addr+16]} { # get 16 bytes of data set s [string range $data $addr [expr $addr+16]] |
︙ | ︙ | |||
226 227 228 229 230 231 232 | # check the integrity of the database with the patched journal sqlite3 db $db_name do_test restore_jrnl-1.0 { catchsql {PRAGMA integrity_check} } {0 ok} db close | < | 226 227 228 229 230 231 232 | # check the integrity of the database with the patched journal sqlite3 db $db_name do_test restore_jrnl-1.0 { catchsql {PRAGMA integrity_check} } {0 ok} db close |
Changes to vsixtest/vsixtest.tcl.
︙ | ︙ | |||
128 129 130 131 132 133 134 | proc readFile { fileName } { # # NOTE: Reads and returns the entire contents of the specified file, which # may contain binary data. # set file_id [open $fileName RDONLY] | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | proc readFile { fileName } { # # NOTE: Reads and returns the entire contents of the specified file, which # may contain binary data. # set file_id [open $fileName RDONLY] fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result } proc writeFile { fileName data } { # # NOTE: Writes the entire contents of the specified file, which may contain # binary data. # set file_id [open $fileName {WRONLY CREAT TRUNC}] fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" } proc putsAndEval { command } { # |
︙ | ︙ |