Merge trunk into this branch.
FossilOrigin-Name: 9c3bb3dc4f5b5cd7db6cd50d22dbe8f933cccf5f2fd253467bb50f36b3207a93
This commit is contained in:
+61
-11
@@ -66,6 +66,14 @@ USE_STDCALL = 0
|
||||
USE_SEH = 1
|
||||
!ENDIF
|
||||
|
||||
# Use STATICALLY_LINK_TCL=1 to statically link against TCL
|
||||
#
|
||||
!IFNDEF STATICALLY_LINK_TCL
|
||||
STATICALLY_LINK_TCL = 0
|
||||
!ELSEIF $(STATICALLY_LINK_TCL)!=0
|
||||
CCOPTS = $(CCOPTS) -DSTATIC_BUILD
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to have the shell executable link against the core dynamic
|
||||
# link library.
|
||||
#
|
||||
@@ -929,10 +937,9 @@ TCC = $(TCC) /fsanitize=address
|
||||
# prior to running nmake in order to match the actual installed location and
|
||||
# version on this machine.
|
||||
#
|
||||
!IFNDEF TCLVERSION
|
||||
TCLVERSION = 86
|
||||
!IF $(STATICALLY_LINK_TCL)!=0
|
||||
TCLSUFFIX = s
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLSUFFIX
|
||||
TCLSUFFIX =
|
||||
!ENDIF
|
||||
@@ -941,6 +948,19 @@ TCLSUFFIX =
|
||||
TCLDIR = C:\Tcl
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLVERSION
|
||||
!IF EXISTS("$(TCLDIR)\lib\tcl90$(TCLSUFFIX).lib")
|
||||
TCLVERSION = 90
|
||||
!ELSEIF EXISTS("$(TCLDIR)\lib\tcl86$(TCLSUFFIX).lib")
|
||||
TCLVERSION = 86
|
||||
!ELSEIF EXISTS("$(TCLDIR)\lib\tcl86t.lib")
|
||||
TCLSUFFIX = t
|
||||
TCLVERSION = 86
|
||||
!ELSE
|
||||
TCLVERSION = 90
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLINCDIR
|
||||
TCLINCDIR = $(TCLDIR)\include
|
||||
!ENDIF
|
||||
@@ -953,9 +973,21 @@ TCLLIBDIR = $(TCLDIR)\lib
|
||||
LIBTCL = tcl$(TCLVERSION)$(TCLSUFFIX).lib
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF TCLLIBS
|
||||
!IF $(STATICALLY_LINK_TCL)!=0
|
||||
TCLLIBS = /NODEFAULTLIB:libucrt.lib netapi32.lib user32.lib ucrt.lib
|
||||
!ELSE
|
||||
TCLLIBS =
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLSTUB
|
||||
!IF EXISTS("$(TCLLIBDIR)\tclstub$(TCLSUFFIX).lib")
|
||||
LIBTCLSTUB = tclstub$(TCLSUFFIX).lib
|
||||
!ELSE
|
||||
LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBTCLPATH
|
||||
LIBTCLPATH = $(TCLDIR)\bin
|
||||
@@ -1013,10 +1045,18 @@ LIBICU = icuuc.lib icuin.lib
|
||||
# specific Tcl shell to use.
|
||||
#
|
||||
!IFNDEF TCLSH_CMD
|
||||
!IF $(USE_TCLSH_IN_PATH)!=0 || !EXIST("$(TCLDIR)\bin\tclsh.exe")
|
||||
TCLSH_CMD = tclsh
|
||||
!ELSE
|
||||
!IF EXISTS("$(TCLDIR)\bin\tclsh$(TCLVERSION).exe")
|
||||
TCLSH_CMD = $(TCLDIR)\bin\tclsh$(TCLVERSION).exe
|
||||
!ELSEIF EXISTS("$(TCLDIR)\bin\tclsh90.exe")
|
||||
TCLSH_CMD = $(TCLDIR)\bin\tclsh90.exe
|
||||
!ELSEIF EXISTS("$(TCLDIR)\bin\tclsh86.exe")
|
||||
TCLSH_CMD = $(TCLDIR)\bin\tclsh86.exe
|
||||
!ELSEIF EXISTS("$(TCLDIR)\bin\tclsh86t.exe")
|
||||
TCLSH_CMD = $(TCLDIR)\bin\tclsh86t.exe
|
||||
!ELSEIF EXISTS("$(TCLDIR)\bin\tclsh.exe")
|
||||
TCLSH_CMD = $(TCLDIR)\bin\tclsh.exe
|
||||
!ELSE
|
||||
TCLSH_CMD = tclsh
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
# <</mark>>
|
||||
@@ -1824,7 +1864,7 @@ tclsqlite3.def: tclsqlite.lo
|
||||
|
||||
pkgIndex.tcl: $(TOP)\VERSION
|
||||
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
|
||||
echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \
|
||||
echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] Sqlite3] \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \
|
||||
)
|
||||
|
||||
@@ -1868,7 +1908,7 @@ dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
RSYNC_SRC = \
|
||||
$(TOP)\tool\sqlite3-rsync.c \
|
||||
$(TOP)\tool\sqlite3_rsync.c \
|
||||
$(SQLITE3C)
|
||||
|
||||
RSYNC_OPT = \
|
||||
@@ -1877,7 +1917,7 @@ RSYNC_OPT = \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_OMIT_DEPRECATED
|
||||
|
||||
sqlite3-rsync.exe: $(RSYNC_SRC) $(LIBRESOBJS)
|
||||
sqlite3_rsync.exe: $(RSYNC_SRC) $(LIBRESOBJS)
|
||||
$(LTLINK) $(RSYNC_OPT) $(NO_WARN) $(RSYNC_SRC) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS)
|
||||
|
||||
scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
|
||||
@@ -2537,7 +2577,7 @@ extensiontest: testfixture.exe testloadext.dll
|
||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
|
||||
|
||||
tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe $(TOP)\tool\mktoolzip.tcl
|
||||
tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe sqlite3_rsync.exe $(TOP)\tool\mktoolzip.tcl
|
||||
.\testfixture.exe $(TOP)\tool\mktoolzip.tcl
|
||||
|
||||
coretestprogs: testfixture.exe sqlite3.exe
|
||||
@@ -2746,6 +2786,16 @@ THREADTEST3_SRC = \
|
||||
threadtest3.exe: $(THREADTEST3_SRC) $(TOP)\src\test_multiplex.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\test\threadtest3.c $(TOP)\src\test_multiplex.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
# Display key variables that control which version of TCL is to be used.
|
||||
#
|
||||
tcl-env:
|
||||
@echo TCLDIR = $(TCLDIR)
|
||||
@echo TCLVERSION = $(TCLVERSION)
|
||||
@echo TCLSUFFIX = $(TCLSUFFIX)
|
||||
@echo LIBTCL = $(LIBTCL)
|
||||
@echo LIBTCLSTUB = $(LIBTCLSTUB)
|
||||
@echo TCLSH_CMD = $(TCLSH_CMD)
|
||||
|
||||
LSMDIR=$(TOP)\ext\lsm1
|
||||
!INCLUDE $(LSMDIR)\Makefile.msc
|
||||
|
||||
@@ -2779,7 +2829,7 @@ clean:
|
||||
del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL
|
||||
del /Q sqlite3rc.h 2>NUL
|
||||
del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c sqlite3-rsync.exe 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c sqlite3_rsync.exe 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
|
||||
del /Q sqltclsh.* 2>NUL
|
||||
|
||||
@@ -66,6 +66,14 @@ USE_STDCALL = 0
|
||||
USE_SEH = 1
|
||||
!ENDIF
|
||||
|
||||
# Use STATICALLY_LINK_TCL=1 to statically link against TCL
|
||||
#
|
||||
!IFNDEF STATICALLY_LINK_TCL
|
||||
STATICALLY_LINK_TCL = 0
|
||||
!ELSEIF $(STATICALLY_LINK_TCL)!=0
|
||||
CCOPTS = $(CCOPTS) -DSTATIC_BUILD
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to have the shell executable link against the core dynamic
|
||||
# link library.
|
||||
#
|
||||
|
||||
@@ -3,6 +3,27 @@ Architecture (TEA). For additional information on SQLite see
|
||||
|
||||
http://www.sqlite.org/
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Update 2024-10-11:
|
||||
|
||||
A better way to build the TCL extension for SQLite is to use the
|
||||
canonical source code tarball. For Unix:
|
||||
|
||||
./configure --with-tclsh=$(TCLSH)
|
||||
make tclextension-install
|
||||
|
||||
For Windows:
|
||||
|
||||
nmake /f Makefile.msc tclextension-install TCLSH_CMD=$(TCLSH)
|
||||
|
||||
In both of the above, replace $(TCLSH) with the full pathname of
|
||||
of the tclsh that you want the SQLite extension to work with.
|
||||
|
||||
This TEA builder is antiquated. It does not work for TCL9. The
|
||||
SQLite devs don't know how to fix it. If you would like to help
|
||||
fix it, contact us.
|
||||
------------------------------------------------------------------
|
||||
|
||||
|
||||
UNIX BUILD
|
||||
==========
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
if {[package vsatisfies [package provide Tcl] 9.0-]} {
|
||||
package ifneeded sqlite3 @PACKAGE_VERSION@ \
|
||||
[list load [file join $dir @PKG_LIB_FILE9@] sqlite3]
|
||||
[list load [file join $dir @PKG_LIB_FILE9@] Sqlite3]
|
||||
} else {
|
||||
package ifneeded sqlite3 @PACKAGE_VERSION@ \
|
||||
[list load [file join $dir @PKG_LIB_FILE8@] sqlite3]
|
||||
[list load [file join $dir @PKG_LIB_FILE8@] Sqlite3]
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ install-libraries:
|
||||
@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
|
||||
@type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
|
||||
package ifneeded $(PROJECT) $(DOTVERSION) \
|
||||
[list load [file join $$dir $(PRJLIBNAME)] sqlite3]
|
||||
[list load [file join $$dir $(PRJLIBNAME)] Sqlite3]
|
||||
<<
|
||||
|
||||
install-docs:
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ AC_ARG_ENABLE(tcl,
|
||||
[use_tcl=$enableval],[use_tcl=yes])
|
||||
original_use_tcl=${use_tcl}
|
||||
if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then
|
||||
AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh tclsh9.0],none)
|
||||
AC_CHECK_PROGS(TCLSH_CMD, [tclsh9.0 tclsh8.6 tclsh],none)
|
||||
with_tclsh=${TCLSH_CMD}
|
||||
fi
|
||||
if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Notes On Compiling SQLite On All Kinds Of Unix
|
||||
|
||||
Here are step-by-step instructions on how to build SQLite from
|
||||
canonical source on any modern machine that isn't Windows. These
|
||||
notes are tested (on 2024-10-11) on Ubuntu and on MacOS, but they
|
||||
are general and should work on most any modern unix platform.
|
||||
|
||||
1. Install a C-compiler. GCC or Clang both work fine. If you are
|
||||
reading this document, you've probably already done that.
|
||||
|
||||
2. Install TCL9 development libraries. In this note, we'll do a
|
||||
private install in the $HOME/local directory, but you can make
|
||||
adjustments to install TCL9 wherever you like.
|
||||
install the TCL development libraries in the "`c:\Tcl`" directory.
|
||||
<p>
|
||||
This document assumes you are working with <b>TCL version 9.0</b>.
|
||||
<ol type="a">
|
||||
<li>Get the TCL source archive, perhaps from
|
||||
[https://www.tcl.tk/software/tcltk/download.html](https://www.tcl.tk/software/tcltk/download.html)
|
||||
or [https://sqlite.org/tmp/tcl9.0.0.tar.gz](https://sqlite.org/tmp/tcl9.0.0.tar.gz)
|
||||
<li>Untar the source archive. CD into the "unix/" subfolder
|
||||
of the source tree.
|
||||
<li>Run: `mkdir $HOME/local`
|
||||
<li>Run: `./configure --prefix=$HOME/local`
|
||||
<li>Run: `make install`
|
||||
</ol>
|
||||
|
||||
4. Download the SQLite source tree and unpack it. CD into the
|
||||
toplevel directory of the source tree.
|
||||
|
||||
5. Run: `./configure --enable-all --with-tclsh=$HOME/local/bin/tclsh9.0`
|
||||
|
||||
You do not need to use --with-tclsh if the tclsh you want to use is the
|
||||
first one on your PATH.
|
||||
|
||||
6. Run the "`Makefile`" makefile with an appropriate target.
|
||||
Examples:
|
||||
<ul>
|
||||
<li> `make sqlite3.c`
|
||||
<li> `make sqlite3`
|
||||
<li> `make sqldiff`
|
||||
<li> `make sqlite3_rsync`
|
||||
<li> `make tclextension-install`
|
||||
<li> `make devtest`
|
||||
<li> `make releasetest`
|
||||
<li> `make sqlite3_analyzer`
|
||||
</ul>
|
||||
|
||||
It is not required that you run the "tclextension-install" target prior to
|
||||
running tests. However, the tests will run more smoothly if you do.
|
||||
The version of SQLite used for the TCL extension does *not* need to
|
||||
correspond to the version of SQLite under test. So you can install the
|
||||
SQLite TCL extension once, and then use it to test many different versions
|
||||
of SQLite.
|
||||
|
||||
|
||||
7. For a debugging build of the CLI, where the ".treetrace" and ".wheretrace"
|
||||
commands work, add the the --enable-debug argument to configure.
|
||||
+18
-19
@@ -1,7 +1,7 @@
|
||||
# Notes On Compiling SQLite On Windows 11
|
||||
|
||||
Here are step-by-step instructions on how to build SQLite from
|
||||
canonical source on a new Windows 11 PC, as of 2023-11-01:
|
||||
canonical source on a new Windows 11 PC, as of 2024-10-09:
|
||||
|
||||
1. Install Microsoft Visual Studio. The free "community edition"
|
||||
will work fine. Do a standard install for C++ development.
|
||||
@@ -20,9 +20,11 @@ canonical source on a new Windows 11 PC, as of 2023-11-01:
|
||||
install the TCL development libraries in the "`c:\Tcl`" directory.
|
||||
Make adjustments
|
||||
if you want TCL installed somewhere else. SQLite needs both the
|
||||
"tclsh.exe" command-line tool as part of the build process, and
|
||||
the "tcl86.lib" library in order to run tests. You will need
|
||||
TCL version 8.6 or later.
|
||||
"tclsh90.exe" command-line tool as part of the build process, and
|
||||
the "tcl90.lib" and "tclstub.lib" libraries in order to run tests.
|
||||
This document assumes you are working with <b>TCL version 9.0</b>.
|
||||
See versions of this document from prior to 2024-10-10 for
|
||||
instructions on how to build using TCL version 8.6.
|
||||
<ol type="a">
|
||||
<li>Get the TCL source archive, perhaps from
|
||||
[https://www.tcl.tk/software/tcltk/download.html](https://www.tcl.tk/software/tcltk/download.html).
|
||||
@@ -30,13 +32,10 @@ canonical source on a new Windows 11 PC, as of 2023-11-01:
|
||||
of the source tree.
|
||||
<li>Run: `nmake /f makefile.vc release`
|
||||
<li>Run: `nmake /f makefile.vc INSTALLDIR=c:\Tcl install`
|
||||
<li>CD to `c:\Tcl\lib`. In that subfolder make a copy of the
|
||||
"`tcl86t.lib`" file to the alternative name "`tcl86.lib`"
|
||||
(omitting the second 't'). Leave the copy in the same directory
|
||||
as the original.
|
||||
<li>CD to `c:\Tcl\bin`. Make a copy of the "`tclsh86t.exe`"
|
||||
file into "`tclsh.exe`" (without the "86t") in the same directory.
|
||||
<li>Add `c:\Tcl\bin` to your %PATH%. To do this, go to Settings
|
||||
<li><i>Optional:</i> CD to `c:\Tcl\bin` and make a copy of
|
||||
`tclsh90.exe` over into just `tclsh.exe`.
|
||||
<li><i>Optional:</i>
|
||||
Add `c:\Tcl\bin` to your %PATH%. To do this, go to Settings
|
||||
and search for "path". Select "edit environment variables for
|
||||
your account" and modify your default PATH accordingly.
|
||||
You will need to close and reopen your command prompts after
|
||||
@@ -59,6 +58,7 @@ canonical source on a new Windows 11 PC, as of 2023-11-01:
|
||||
<li> `nmake /f makefile.msc sqlite3.c`
|
||||
<li> `nmake /f makefile.msc sqlite3.exe`
|
||||
<li> `nmake /f makefile.msc sqldiff.exe`
|
||||
<li> `nmake /f makefile.msc sqlite3_rsync.exe`
|
||||
<li> `nmake /f makefile.msc tclextension-install`
|
||||
<li> `nmake /f makefile.msc devtest`
|
||||
<li> `nmake /f makefile.msc releasetest`
|
||||
@@ -127,7 +127,7 @@ nmake /f Makefile.msc sqlite3_analyzer.exe
|
||||
~~~~
|
||||
|
||||
And you will end up with a working executable. However, that executable
|
||||
will depend on having the "tcl86.dll" library somewhere on your %PATH%.
|
||||
will depend on having the "tcl98.dll" library somewhere on your %PATH%.
|
||||
Use the following steps to build an executable that has the TCL library
|
||||
statically linked so that it does not depend on separate DLL:
|
||||
|
||||
@@ -137,27 +137,26 @@ statically linked so that it does not depend on separate DLL:
|
||||
2. Untar the TCL source tarball into a fresh directory. CD into
|
||||
the "win/" subfolder.
|
||||
|
||||
3. Run: `nmake /f makefile.vc OPTS=nothreads,static shell`
|
||||
|
||||
3. Run: `nmake /f makefile.vc OPTS=static shell`
|
||||
|
||||
4. CD into the "Release*" subfolder that is created (note the
|
||||
wildcard - the full name of the directory might vary). There
|
||||
you will find the "tcl86s.lib" file. Copy this file into the
|
||||
same directory that you put the "tcl86.lib" on your initial
|
||||
you will find the "tcl90s.lib" file. Copy this file into the
|
||||
same directory that you put the "tcl90.lib" on your initial
|
||||
installation. (In this document, that directory is
|
||||
"`C:\Tcl32\lib`" for 32-bit builds and
|
||||
"`C:\Tcl\lib`" for 64-bit builds.)
|
||||
|
||||
5. CD into your SQLite source code directory and build the desired
|
||||
utility program, but add the following extra arguments to the
|
||||
utility program, but add the following extra argument to the
|
||||
nmake command line:
|
||||
<blockquote><pre>
|
||||
CCOPTS="-DSTATIC_BUILD" LIBTCL="tcl86s.lib netapi32.lib user32.lib"
|
||||
STATICALLY_LINK_TCL=1
|
||||
</pre></blockquote>
|
||||
<p>So, for example, to build a statically linked version of
|
||||
sqlite3_analyzer.exe, you might type:
|
||||
<blockquote><pre>
|
||||
nmake /f Makefile.msc CCOPTS="-DSTATIC_BUILD" LIBTCL="tcl86s.lib netapi32.lib user32.lib" sqlite3_analyzer.exe
|
||||
nmake /f Makefile.msc STATICALLY_LINK_TCL=1 sqlite3_analyzer.exe
|
||||
</pre></blockquote>
|
||||
|
||||
6. After your executable is built, you can verify that it does not
|
||||
|
||||
@@ -402,6 +402,19 @@ do_setup_rec_test $tn.19.0 {
|
||||
SCAN t1 USING COVERING INDEX t1_idx_01a7214e
|
||||
}
|
||||
|
||||
ifcapable fts5 {
|
||||
do_setup_rec_test $tn.20.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(a);
|
||||
CREATE TABLE t1(x, y);
|
||||
} {
|
||||
SELECT * FROM ft, t1 WHERE a=x
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000078 ON t1(x);
|
||||
SCAN ft VIRTUAL TABLE INDEX 0:
|
||||
SEARCH t1 USING INDEX t1_idx_00000078 (x=?)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proc do_candidates_test {tn sql res} {
|
||||
@@ -507,4 +520,65 @@ do_candidates_test 6.1 {
|
||||
CREATE INDEX x1_idx_00000062 ON x1(b);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
ifcapable fts5 {
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(a);
|
||||
CREATE TABLE t1(x, y);
|
||||
}
|
||||
|
||||
do_candidates_test 7.1 {
|
||||
SELECT * FROM ft, t1 WHERE a=x
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000078 ON t1(x);
|
||||
}
|
||||
|
||||
register_tcl_module db
|
||||
proc vtab_command {method args} {
|
||||
global G
|
||||
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE t1(a, b, c);"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
return [list]
|
||||
}
|
||||
|
||||
xFilter {
|
||||
return [list sql "SELECT rowid, * FROM t0"]
|
||||
}
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
do_execsql_test 7.2 {
|
||||
CREATE TABLE t0(a, b, c);
|
||||
INSERT INTO t0 VALUES(1, 2, 3), (11, 22, 33);
|
||||
CREATE VIRTUAL TABLE t2 USING tcl(vtab_command);
|
||||
}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
SELECT * FROM t2
|
||||
} {
|
||||
1 2 3
|
||||
11 22 33
|
||||
}
|
||||
|
||||
do_candidates_test 7.4 {
|
||||
SELECT * FROM ft, t1 WHERE a=x
|
||||
} {
|
||||
CREATE INDEX t1_idx_00000078 ON t1(x);
|
||||
}
|
||||
|
||||
do_test 7.5 {
|
||||
set expert [sqlite3_expert_new db]
|
||||
list [catch { $expert sql "SELECT * FROM ft, t2 WHERE b=1" } msg] $msg
|
||||
} {1 {no such table: t2}}
|
||||
$expert destroy
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1392,6 +1392,66 @@ static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function tests if the schema of the main database of database handle
|
||||
** db contains an object named zTab. Assuming no error occurs, output parameter
|
||||
** (*pbContains) is set to true if zTab exists, or false if it does not.
|
||||
**
|
||||
** Or, if an error occurs, an SQLite error code is returned. The final value
|
||||
** of (*pbContains) is undefined in this case.
|
||||
*/
|
||||
static int expertDbContainsObject(
|
||||
sqlite3 *db,
|
||||
const char *zTab,
|
||||
int *pbContains /* OUT: True if object exists */
|
||||
){
|
||||
const char *zSql = "SELECT 1 FROM sqlite_schema WHERE name = ?";
|
||||
sqlite3_stmt *pSql = 0;
|
||||
int rc = SQLITE_OK;
|
||||
int ret = 0;
|
||||
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_text(pSql, 1, zTab, -1, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(pSql) ){
|
||||
ret = 1;
|
||||
}
|
||||
rc = sqlite3_finalize(pSql);
|
||||
}
|
||||
|
||||
*pbContains = ret;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Execute SQL command zSql using database handle db. If no error occurs,
|
||||
** set (*pzErr) to NULL and return SQLITE_OK.
|
||||
**
|
||||
** If an error does occur, return an SQLite error code and set (*pzErr) to
|
||||
** point to a buffer containing an English language error message. Except,
|
||||
** if the error message begins with "no such module:", then ignore the
|
||||
** error and return as if the SQL statement had succeeded.
|
||||
**
|
||||
** This is used to copy as much of the database schema as possible while
|
||||
** ignoring any errors related to missing virtual table modules.
|
||||
*/
|
||||
static int expertSchemaSql(sqlite3 *db, const char *zSql, char **pzErr){
|
||||
int rc = SQLITE_OK;
|
||||
char *zErr = 0;
|
||||
|
||||
rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
|
||||
if( rc!=SQLITE_OK && zErr ){
|
||||
int nErr = STRLEN(zErr);
|
||||
if( nErr>=15 && memcmp(zErr, "no such module:", 15)==0 ){
|
||||
sqlite3_free(zErr);
|
||||
rc = SQLITE_OK;
|
||||
zErr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*pzErr = zErr;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
|
||||
int rc = idxRegisterVtab(p);
|
||||
@@ -1403,22 +1463,29 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
|
||||
** 2) Create the equivalent virtual table in dbv.
|
||||
*/
|
||||
rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
|
||||
"SELECT type, name, sql, 1 FROM sqlite_schema "
|
||||
"SELECT type, name, sql, 1, sql LIKE 'create virtual%' "
|
||||
"FROM sqlite_schema "
|
||||
"WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
|
||||
" UNION ALL "
|
||||
"SELECT type, name, sql, 2 FROM sqlite_schema "
|
||||
"SELECT type, name, sql, 2, 0 FROM sqlite_schema "
|
||||
"WHERE type = 'trigger'"
|
||||
" AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') "
|
||||
"ORDER BY 4, 1"
|
||||
"ORDER BY 4, 5 DESC, 1"
|
||||
);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
|
||||
const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
|
||||
const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
|
||||
const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
|
||||
int bVirtual = sqlite3_column_int(pSchema, 4);
|
||||
int bExists = 0;
|
||||
|
||||
if( zType==0 || zName==0 ) continue;
|
||||
if( zType[0]=='v' || zType[1]=='r' ){
|
||||
if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
|
||||
rc = expertDbContainsObject(p->dbv, zName, &bExists);
|
||||
if( rc || bExists ) continue;
|
||||
|
||||
if( zType[0]=='v' || zType[1]=='r' || bVirtual ){
|
||||
/* A view. Or a trigger on a view. */
|
||||
if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg);
|
||||
}else{
|
||||
IdxTable *pTab;
|
||||
rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
|
||||
@@ -1957,12 +2024,18 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pSql = 0;
|
||||
rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
|
||||
"SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
|
||||
" AND sql NOT LIKE 'CREATE VIRTUAL %%' ORDER BY rowid"
|
||||
"SELECT sql, name "
|
||||
" FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
|
||||
" ORDER BY rowid"
|
||||
);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
|
||||
const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
|
||||
if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
|
||||
const char *zName = (const char*)sqlite3_column_text(pSql, 1);
|
||||
int bExists = 0;
|
||||
rc = expertDbContainsObject(pNew->dbm, zName, &bExists);
|
||||
if( rc==SQLITE_OK && zSql && bExists==0 ){
|
||||
rc = expertSchemaSql(pNew->dbm, zSql, pzErrmsg);
|
||||
}
|
||||
}
|
||||
idxFinalize(&rc, pSql);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
|
||||
c = *(zIn++); \
|
||||
if( c>=0xc0 ){ \
|
||||
c = sqlite3Utf8Trans1[c-0xc0]; \
|
||||
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
|
||||
while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \
|
||||
c = (c<<6) + (0x3f & *(zIn++)); \
|
||||
} \
|
||||
if( c<0x80 \
|
||||
|
||||
+42
-40
@@ -658,46 +658,48 @@ static int seriesBestIndex(
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( pConstraint->iColumn==SERIES_COLUMN_VALUE ){
|
||||
switch( op ){
|
||||
case SQLITE_INDEX_CONSTRAINT_EQ:
|
||||
case SQLITE_INDEX_CONSTRAINT_IS: {
|
||||
idxNum |= 0x0080;
|
||||
idxNum &= ~0x3300;
|
||||
aIdx[5] = i;
|
||||
aIdx[6] = -1;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0100;
|
||||
idxNum &= ~0x0200;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0200;
|
||||
idxNum &= ~0x0100;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x1000;
|
||||
idxNum &= ~0x2000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x2000;
|
||||
idxNum &= ~0x1000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
if( pConstraint->iColumn<SERIES_COLUMN_START ){
|
||||
if( pConstraint->iColumn==SERIES_COLUMN_VALUE ){
|
||||
switch( op ){
|
||||
case SQLITE_INDEX_CONSTRAINT_EQ:
|
||||
case SQLITE_INDEX_CONSTRAINT_IS: {
|
||||
idxNum |= 0x0080;
|
||||
idxNum &= ~0x3300;
|
||||
aIdx[5] = i;
|
||||
aIdx[6] = -1;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0100;
|
||||
idxNum &= ~0x0200;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0200;
|
||||
idxNum &= ~0x0100;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x1000;
|
||||
idxNum &= ~0x2000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x2000;
|
||||
idxNum &= ~0x1000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
+90
-26
@@ -31,27 +31,21 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
** If the SQLITE_U8TEXT_ONLY option is defined, then only use
|
||||
** _O_U8TEXT, _O_WTEXT, and similar together with the UTF-16
|
||||
** interfaces to the Windows CRT. The use of ANSI-only routines
|
||||
** like fputs() and ANSI modes like _O_TEXT and _O_BINARY is
|
||||
** avoided.
|
||||
** If the SQLITE_U8TEXT_ONLY option is defined, then use O_U8TEXT
|
||||
** when appropriate on all output. (Sometimes use O_BINARY when
|
||||
** rendering ASCII text in cases where NL-to-CRLF expansion would
|
||||
** not be correct.)
|
||||
**
|
||||
** The downside of using SQLITE_U8TEXT_ONLY is that it becomes
|
||||
** impossible to output a bare newline character (0x0a) - that is,
|
||||
** a newline that is not preceded by a carriage return (0x0d).
|
||||
** And without that capability, sometimes the output will be slightly
|
||||
** incorrect, as extra 0x0d characters will have been inserted where
|
||||
** they do not belong.
|
||||
** If the SQLITE_U8TEXT_STDIO option is defined, then use O_U8TEXT
|
||||
** when appropriate when writing to stdout or stderr. Use O_BINARY
|
||||
** or O_TEXT (depending on things like the .mode and the .crlf setting
|
||||
** in the CLI, or other context clues in other applications) for all
|
||||
** other output channels.
|
||||
**
|
||||
** The SQLITE_U8TEXT_STDIO compile-time option is a compromise.
|
||||
** It always enables _O_WTEXT or similar for stdin, stdout, stderr,
|
||||
** but allows other streams to be _O_TEXT and/or O_BINARY. The
|
||||
** SQLITE_U8TEXT_STDIO option has the same downside as SQLITE_U8TEXT_ONLY
|
||||
** in that stray 0x0d characters might appear where they ought not, but
|
||||
** at least with this option those characters only appear on standard
|
||||
** I/O streams, and not on new streams that might be created by the
|
||||
** application using sqlite3_fopen() or sqlite3_popen().
|
||||
** The default behavior, if neither of the above is defined is to
|
||||
** use O_U8TEXT when writing to the Windows console (or anything
|
||||
** else for which _isatty() returns true) and to use O_BINARY or O_TEXT
|
||||
** for all other output channels.
|
||||
*/
|
||||
#if defined(SQLITE_U8TEXT_ONLY)
|
||||
# define UseWtextForOutput(fd) 1
|
||||
@@ -67,6 +61,31 @@
|
||||
# define IsConsole(fd) 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Global variables determine if simulated O_BINARY mode is to be
|
||||
** used for stdout or other, respectively. Simulated O_BINARY mode
|
||||
** means the mode is usually O_BINARY, but switches to O_U8TEXT for
|
||||
** unicode characters U+0080 or greater (any character that has a
|
||||
** multi-byte representation in UTF-8). This is the only way we
|
||||
** have found to render Unicode characters on a Windows console while
|
||||
** at the same time avoiding undesirable \n to \r\n translation.
|
||||
*/
|
||||
static int simBinaryStdout = 0;
|
||||
static int simBinaryOther = 0;
|
||||
|
||||
|
||||
/*
|
||||
** Determine if simulated binary mode should be used for output to fd
|
||||
*/
|
||||
static int UseBinaryWText(FILE *fd){
|
||||
if( fd==stdout || fd==stderr ){
|
||||
return simBinaryStdout;
|
||||
}else{
|
||||
return simBinaryOther;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Work-alike for the fopen() routine from the standard C library.
|
||||
*/
|
||||
@@ -88,6 +107,7 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){
|
||||
}
|
||||
free(b1);
|
||||
free(b2);
|
||||
simBinaryOther = 0;
|
||||
return fp;
|
||||
}
|
||||
|
||||
@@ -143,13 +163,53 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Send ASCII text as O_BINARY. But for Unicode characters U+0080 and
|
||||
** greater, switch to O_U8TEXT.
|
||||
*/
|
||||
static void piecemealOutput(wchar_t *b1, int sz, FILE *out){
|
||||
int i;
|
||||
wchar_t c;
|
||||
while( sz>0 ){
|
||||
for(i=0; i<sz && b1[i]>=0x80; i++){}
|
||||
if( i>0 ){
|
||||
c = b1[i];
|
||||
b1[i] = 0;
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
fputws(b1, out);
|
||||
fflush(out);
|
||||
b1 += i;
|
||||
b1[0] = c;
|
||||
sz -= i;
|
||||
}else{
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_TEXT);
|
||||
_setmode(_fileno(out), _O_BINARY);
|
||||
fwrite(&b1[0], 1, 1, out);
|
||||
for(i=1; i<sz && b1[i]<0x80; i++){
|
||||
fwrite(&b1[i], 1, 1, out);
|
||||
}
|
||||
fflush(out);
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
b1 += i;
|
||||
sz -= i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Work-alike for fputs() from the standard C library.
|
||||
*/
|
||||
int sqlite3_fputs(const char *z, FILE *out){
|
||||
if( UseWtextForOutput(out) ){
|
||||
if( !UseWtextForOutput(out) ){
|
||||
/* Writing to a file or other destination, just write bytes without
|
||||
** any translation. */
|
||||
return fputs(z, out);
|
||||
}else{
|
||||
/* When writing to the command-prompt in Windows, it is necessary
|
||||
** to use _O_WTEXT input mode and write UTF-16 characters.
|
||||
** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
|
||||
** use O_U8TEXT for everything in text mode.
|
||||
*/
|
||||
int sz = (int)strlen(z);
|
||||
wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) );
|
||||
@@ -157,13 +217,13 @@ int sqlite3_fputs(const char *z, FILE *out){
|
||||
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
|
||||
b1[sz] = 0;
|
||||
_setmode(_fileno(out), _O_U8TEXT);
|
||||
fputws(b1, out);
|
||||
if( UseBinaryWText(out) ){
|
||||
piecemealOutput(b1, sz, out);
|
||||
}else{
|
||||
fputws(b1, out);
|
||||
}
|
||||
sqlite3_free(b1);
|
||||
return 0;
|
||||
}else{
|
||||
/* Writing to a file or other destination, just write bytes without
|
||||
** any translation. */
|
||||
return fputs(z, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +265,10 @@ void sqlite3_fsetmode(FILE *fp, int mode){
|
||||
if( !UseWtextForOutput(fp) ){
|
||||
fflush(fp);
|
||||
_setmode(_fileno(fp), mode);
|
||||
}else if( fp==stdout || fp==stderr ){
|
||||
simBinaryStdout = (mode==_O_BINARY);
|
||||
}else{
|
||||
simBinaryOther = (mode==_O_BINARY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -744,7 +744,7 @@ static const char *recoverUnusedString(
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of scalar SQL function "escape_crnl". The argument passed to
|
||||
** Implementation of scalar SQL function "escape_crlf". The argument passed to
|
||||
** this function is the output of built-in function quote(). If the first
|
||||
** character of the input is "'", indicating that the value passed to quote()
|
||||
** was a text value, then this function searches the input for "\n" and "\r"
|
||||
@@ -755,7 +755,7 @@ static const char *recoverUnusedString(
|
||||
** Or, if the first character of the input is not "'", then a copy of the input
|
||||
** is returned.
|
||||
*/
|
||||
static void recoverEscapeCrnl(
|
||||
static void recoverEscapeCrlf(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
@@ -970,7 +970,7 @@ static int recoverOpenOutput(sqlite3_recover *p){
|
||||
{ "getpage", 1, recoverGetPage },
|
||||
{ "page_is_used", 1, recoverPageIsUsed },
|
||||
{ "read_i32", 2, recoverReadI32 },
|
||||
{ "escape_crnl", 1, recoverEscapeCrnl },
|
||||
{ "escape_crlf", 1, recoverEscapeCrlf },
|
||||
};
|
||||
|
||||
const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
|
||||
@@ -1323,7 +1323,7 @@ static sqlite3_stmt *recoverInsertStmt(
|
||||
|
||||
if( bSql ){
|
||||
zBind = recoverMPrintf(p,
|
||||
"%z%sescape_crnl(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind
|
||||
"%z%sescape_crlf(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind
|
||||
);
|
||||
zSqlSep = "||', '||";
|
||||
}else{
|
||||
|
||||
@@ -569,7 +569,7 @@ dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
|
||||
$(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
RSYNC_SRC = \
|
||||
$(TOP)/tool/sqlite3-rsync.c \
|
||||
$(TOP)/tool/sqlite3_rsync.c \
|
||||
sqlite3.c
|
||||
|
||||
RSYNC_OPT = \
|
||||
@@ -578,7 +578,7 @@ RSYNC_OPT = \
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_OMIT_DEPRECATED
|
||||
|
||||
sqlite3-rsync$(EXE): $(RSYNC_SRC)
|
||||
sqlite3_rsync$(EXE): $(RSYNC_SRC)
|
||||
$(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS)
|
||||
|
||||
scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o
|
||||
@@ -1159,7 +1159,7 @@ clean:
|
||||
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
||||
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
|
||||
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
|
||||
rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE)
|
||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE)
|
||||
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
|
||||
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
|
||||
rm -f threadtest5$(TEXE)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
C Add\ssqlite3rc.h\sbuild.
|
||||
D 2024-10-09T13:26:01.411
|
||||
C Merge\strunk\sinto\sthis\sbranch.
|
||||
D 2024-10-16T13:02:07.918
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in e09c278841effbb93503fe3846337350bebc215f06c63f2c998e8cce7b109e8b
|
||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||
F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864
|
||||
F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4
|
||||
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
|
||||
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -18,20 +18,20 @@ F auto.def 42b2334f320fafcebb09673453fc9df470839e136d84ddeb74699af16b08b056
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.msc 2aced6442addab13ed115696eba28d9ed29caa3dd604a31392c2c7a5da301492
|
||||
F autoconf/Makefile.msc 0a1fdef1f2c618815cf7c82c817a7369c1e07b3cfed490803db16fb43326d506
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
|
||||
F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
|
||||
F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196
|
||||
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
|
||||
F autoconf/tea/README.txt 94fa2472d3ee4139ab24b364d99a70445d0a25531dac3ce03af2055d581f76b4 w autoconf/tea/README
|
||||
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
|
||||
F autoconf/tea/configure.ac 0deb5d6c49c8119f75f436488219fc043127d72057af5dfba2c9ce096a5734bc
|
||||
F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
|
||||
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
|
||||
F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce
|
||||
F autoconf/tea/pkgIndex.tcl.in 55aec3c6d7e9a1de9b8d2fdc9c27fd055da3ac3a51b572195e2ae7300bcfd3a2
|
||||
F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00
|
||||
F autoconf/tea/tclconfig/tcl.m4 c6e5f2fc7178f40d087403daa044ef3b86a8e30793f3b121bdcbdf152c6a776a
|
||||
F autoconf/tea/win/makefile.vc 2c478a9a962e48b2bf9062734e04d7c63c556e217095419173f9d7938d7d78f7
|
||||
F autoconf/tea/win/makefile.vc 9b33af4214a5c8360549b96380f55ece1a2df76a51ab4c726296e5c43d8a2227
|
||||
F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea00342d1a1a7eaa19cb
|
||||
F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5
|
||||
F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4
|
||||
@@ -55,10 +55,11 @@ F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d7
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
|
||||
F configure.ac 934d33880d4c7dbff05c2ebaa3820e344e1321d5fff6d6393963e50c3a613e40
|
||||
F configure.ac 6bb3470ed862e753a5e6754cc0eea16e1de7e8c6aac458de1ee7706a8da26f19
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/compile-for-windows.md 4d4bfafda42a7a33f166d23aed4db1bb4ea1e5751595a5cced2bad349fd14652
|
||||
F doc/compile-for-unix.md 90f17554cc3d19b2dae8142b5aeda1a8890692d5f2e091ed4a6f9b46b8f10f62
|
||||
F doc/compile-for-windows.md a9ab9f6c49763d63d177a386a9e53ee670101f80e8bcb73cafca438156229076
|
||||
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
||||
F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b
|
||||
F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706
|
||||
@@ -76,8 +77,8 @@ F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c7
|
||||
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test b10f9e20f64102a015c0fcf54cb7b7680266b397e91d93cdad45f57857cdfba6
|
||||
F ext/expert/sqlite3expert.c df417a6d91873a74d35daa9259171647c23c6601415e938e8a71702703f3d677
|
||||
F ext/expert/expert1.test 1fa0201d8610883c32214b1d83e3a6cc582694ac1067be8319b280235145a555
|
||||
F ext/expert/sqlite3expert.c b7cbbd7cc109c66ebdf6091467d790abb9d7c25ae3b822bb76388509641d37de
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70
|
||||
F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee
|
||||
@@ -124,7 +125,7 @@ F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9
|
||||
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
||||
F ext/fts5/fts5_tokenize.c ae9c4fa93174ef06ffc138bd4280a1c37f7e13624d3d2706aad4b80573f23c41
|
||||
F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9
|
||||
F ext/fts5/fts5_unicode2.c 6f9b0fb79a8facaed76628ffd4eb9c16d7f2b84b52872784f617cf3422a9b043
|
||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||
F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0
|
||||
@@ -440,13 +441,13 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
|
||||
F ext/misc/series.c a6089b5e8e3002bd1e5d9877cee6aead0b9a6426e406c09a399817db9e9ae823
|
||||
F ext/misc/series.c 596afbfbbc81ccf4ea6da11f016f7eed630ed195b5e9d548117e19f06d63f641
|
||||
F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9
|
||||
F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f
|
||||
F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634
|
||||
F ext/misc/sqlite3_stdio.c f110e6f2dc97c67e89f941f82af7dbd221193fa44d1e3ef38a691454a2cbccda
|
||||
F ext/misc/sqlite3_stdio.c 73192f75e1e89722fbdf209056a562ca2a35df3c9e998f9270331e03cb621e7a
|
||||
F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176
|
||||
F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321
|
||||
F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc
|
||||
@@ -527,7 +528,7 @@ F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52
|
||||
F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
|
||||
F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
|
||||
F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
|
||||
F ext/recover/sqlite3recover.c 2dcf6b56c5e0e2b43fc4c6115b689ab194c374ced7f7f8380ad9a24d8ef24ac9
|
||||
F ext/recover/sqlite3recover.c e822ecbb05a04a5c85d1309765fcd6cf392d100d02d2227cd7720c9d6921a17a
|
||||
F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
|
||||
F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -708,7 +709,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk 0a55ebec3508ca1bdb593d86f3aa19d7fa42a2ddd3220703e6dc0a65f1338a43
|
||||
F main.mk c6501abe2d915ed1a2ec3d074e652c096177f93c50ac91f815c831e3417f9019
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@@ -738,10 +739,10 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
||||
F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
||||
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
|
||||
F src/expr.c a9d9f5fdfbdd3b2c94d7af1b11f181464b8a641736cf32cb92fa3c5e7ecb30df
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||
F src/func.c df400a1d3f4625997d4dd8a81951c303e066277c29b861d37e03cd152d7858dd
|
||||
F src/func.c 1d093b93b8f097665721e59a1c404d7db4dc591e1a777a7a1022dfbda21e108b
|
||||
F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
@@ -772,7 +773,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
|
||||
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
|
||||
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
|
||||
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
|
||||
F src/os_unix.c 779e83666ecd535f6725497ba6da069c1d15138ff6a4ee123edad1ae0cdfbe83
|
||||
F src/os_unix.c 14d0f80e4779f5f76bcc71e7af97e3efe318fa3d0b22335623c59fab7d39302b
|
||||
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
|
||||
@@ -781,23 +782,23 @@ F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||
F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684
|
||||
F src/pragma.c cd613126f7cdd0c2ded4648c3c7b7b0239e678d7f3489e88c4b6d6858372fd07
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225
|
||||
F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 9750a281f7ba073b4e6da2be1a6c4071f5d841a7746c5fb3f70d6d793b6675ea
|
||||
F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||
F src/shell.c.in 981efe98f98a983c1d0193d18528eb2d765207c0c82b67b610be60f17995a43e
|
||||
F src/sqlite.h.in 1def838497ad53c81486649ce79821925d1ac20a9843af317a344d507efe116e
|
||||
F src/shell.c.in 0662f9bcf0725461778d0254a06150e5d61c08c5a87a7281ccdf45552050c79d
|
||||
F src/sqlite.h.in add9e064d6b42af8f1a4a3322bddadec76696e520aedebd83e0d3211c15ac999
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 989dca8b25ca11f5c52e5a457cc500042c43b0b3e5fea9a12d9020d0350722cd
|
||||
F src/sqliteInt.h ad02397dc4d22b77f9a331412d46e4c1e49459dd386fba8373fa148998e1e7d0
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c c6888598f08dee3d9112a38ef42c8f5c89ca7f3190f4694744d0b84250f4bf8c
|
||||
F src/tclsqlite.c e2b752dd08034c834e3639afa3300940d6e847fcd94207e1f2f1b83ce08b87be
|
||||
F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
|
||||
F src/test1.c 8bf8b74145b768f42386787f93f6d6dad7bc400a4ee2d50e4ad5a06a20a97ef1
|
||||
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
|
||||
@@ -855,7 +856,7 @@ F src/treeview.c 88aa39b754f5ef7214385c1bbbdd2f3dc20efafeed0cf590e8d1199b9c6e44a
|
||||
F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
|
||||
F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
|
||||
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c 7bc550af6f3ddd5f5dc82d092c41f728acb760c92e0b47f391963b01ae52569b
|
||||
F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
|
||||
F src/util.c 4d57ae861d0e234019be9596818228d7715e44e6efaccb612cf4498bedc2e023
|
||||
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
|
||||
F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457
|
||||
@@ -873,10 +874,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c a0d42bfdef935e1389737152394d08e59e7c48697f40a9fc2e0552cb19dc731f
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 461d41017d900d4248a268df96d2d30506c4dcc2257f4167c4f46072003ce2cf
|
||||
F src/where.c 12fe24880901997372b88fd7ca9a21457404ad35201712c02cc57978578abb10
|
||||
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
|
||||
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
|
||||
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
|
||||
F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f
|
||||
F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
@@ -1061,7 +1062,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test ac13504593d89d69690d45479547616ed12644d42b5cb7eeb2e759a76fc23dcb
|
||||
F test/corruptL.test 652fc8ac0763a6fd3eb28b951d481924167b2d9936083bcc68253b2274a0c8fe
|
||||
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
||||
F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4
|
||||
F test/corruptN.test 40bc47aee4af9aadff902be43f14d69dc17b3731448dad6c7cc722da913f1455
|
||||
F test/cost.test cc434a026b1e9d0d98137a147e24e5daf1b1ad09e9ff7da63b34c83ddd136d92
|
||||
F test/count.test cd4bd531066e8d77ef8fe1e3fc8253d042072e117ccab214b290cf83f1602249
|
||||
F test/countofview.test 4088e461a10ee33e69803c177a69aa1d7bba81a9ffc2df66d76465a22ca7fdfc
|
||||
@@ -1343,6 +1344,7 @@ F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4
|
||||
F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0
|
||||
F test/indexexpr1.test 24fa85a12da384dd1d56f7b24e593c51a8a54b4c5e2e8bbb9e5fdf1099427faf
|
||||
F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a
|
||||
F test/indexexpr3.test 9d893bf440937ebcc1e59c7c9c1505c40c918346a3ddde76a69078f3c733c45d
|
||||
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6
|
||||
@@ -1409,7 +1411,7 @@ F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/lemon-test01.y 70110eff607ab137ccc851edb2bc7e14a6d4f246b5d2d25f82a60b69d87a9ff2
|
||||
F test/like.test 242ee7f5d08a031144c0daf63bbd7e7710c847ccf387a83347e0b61b3aa69526
|
||||
F test/like.test b3ea2ba3558199aa8f25a42ddeb54772e234fab50868c9f066047acdbda8fc58
|
||||
F test/like2.test d3be15fefee3e02fc88942a9b98f26c5339bbdef7783c90023c092c4955fe3d3
|
||||
F test/like3.test a76e5938fadbe6d32807284c796bafd869974a961057bc5fc5a28e06de98745c
|
||||
F test/limit.test 350f5d03c29e7dff9a2cde016f84f8d368d40bcd02fa2b2a52fa10c4bf3cbfaf
|
||||
@@ -1423,7 +1425,7 @@ F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
|
||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
||||
F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8
|
||||
F test/lock5.test 24693e40a805f71d80836f720d1f2034684a39b64f1e1990989002c7968c11ee
|
||||
F test/lock5.test 583cae05992af0f66607286917f7d5f8aed3b6053c52df5994efb98f2a8fdbaf
|
||||
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
|
||||
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
|
||||
F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413
|
||||
@@ -1647,7 +1649,7 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21
|
||||
F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test b02d628494fa284cdb2b7b2fecdadea96913796afd623f340a79d68f055dcb7e
|
||||
F test/shell1.test 5d84e415adf7cc4edd5913c4f23c761104ff135b9c190fcf7b430a4cbca6cb65
|
||||
F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
|
||||
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
|
||||
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
|
||||
@@ -1746,7 +1748,7 @@ F test/thread005.test 50d10b5684399676174bd96c94ad4250b1a2c8b6
|
||||
F test/thread1.test df115faa10a4ba1d456e9d4d9ec165016903eae4
|
||||
F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
|
||||
F test/thread3.test a12656a56cdf67acb6a2ff7638826c6d6a645f79909d86df521045ad31cf547d
|
||||
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
|
||||
F test/thread_common.tcl b3b19a769fe30ef5537cdfa60acd49b78f771301627720d1add2d3bac77d9039
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
|
||||
F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b43b781
|
||||
@@ -2168,7 +2170,7 @@ F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6
|
||||
F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa18665e0
|
||||
F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617f8423
|
||||
F tool/mktoolzip.tcl 1b3383c6cd1ca3e1bfdf157d1383f29d6264b9600c381e682789c83617dc1014
|
||||
F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a
|
||||
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
||||
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
|
||||
@@ -2196,11 +2198,11 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
|
||||
F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60
|
||||
F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b
|
||||
F tool/sqlite3-rsync.c 2f06f02ee3a28f847b3fb8c0f32e3b3296571e0f8027939b95d32df5edfe1dd9
|
||||
F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918
|
||||
F tool/sqlite3_rsync.c 2a2b79a0463d400696aa9429be5c0ddec6b1f7ceefa5fed7acfdc859a435221f w tool/sqlite3-rsync.c
|
||||
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f
|
||||
F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4
|
||||
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
||||
F tool/srctree-check.tcl c15f860a3c97d5f7b4c14b60392d9466af29dd006c4ef18127f502641e2977a8
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
@@ -2236,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 292ad7d519d39f16f130d082d3f134deadd5409d56ffb5340064a1996f4b4d57
|
||||
R b2998251d1a1c77a7b55806ea3c31919
|
||||
P 8d5f99f7e3f0ff9eaea1cb550369864e49a0fe0b00a53b1eba6ed099b61d8d24 86e794cbaa5ae600635c933b46298a39f2465daf4c5cd1570f2a03e19ac08d9d
|
||||
R 0f51619208545f999beb801583f35ef3
|
||||
U stephan
|
||||
Z 2c5ae792bbaf5eea557dff2e61da4cd7
|
||||
Z b40f13e331b5567249a3bbe5622b7fa3
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
8d5f99f7e3f0ff9eaea1cb550369864e49a0fe0b00a53b1eba6ed099b61d8d24
|
||||
9c3bb3dc4f5b5cd7db6cd50d22dbe8f933cccf5f2fd253467bb50f36b3207a93
|
||||
|
||||
+64
@@ -4554,6 +4554,59 @@ static int exprCodeInlineFunction(
|
||||
return target;
|
||||
}
|
||||
|
||||
/*
|
||||
** Expression Node callback for sqlite3ExprCanReturnSubtype().
|
||||
**
|
||||
** Only a function call is able to return a subtype. So if the node
|
||||
** is not a function call, return WRC_Prune immediately.
|
||||
**
|
||||
** A function call is able to return a subtype if it has the
|
||||
** SQLITE_RESULT_SUBTYPE property.
|
||||
**
|
||||
** Assume that every function is able to pass-through a subtype from
|
||||
** one of its argument (using sqlite3_result_value()). Most functions
|
||||
** are not this way, but we don't have a mechanism to distinguish those
|
||||
** that are from those that are not, so assume they all work this way.
|
||||
** That means that if one of its arguments is another function and that
|
||||
** other function is able to return a subtype, then this function is
|
||||
** able to return a subtype.
|
||||
*/
|
||||
static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){
|
||||
int n;
|
||||
FuncDef *pDef;
|
||||
sqlite3 *db;
|
||||
if( pExpr->op!=TK_FUNCTION ){
|
||||
return WRC_Prune;
|
||||
}
|
||||
assert( ExprUseXList(pExpr) );
|
||||
db = pWalker->pParse->db;
|
||||
n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0;
|
||||
pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
|
||||
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
|
||||
pWalker->eCode = 1;
|
||||
return WRC_Prune;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if expression pExpr is able to return a subtype.
|
||||
**
|
||||
** A TRUE return does not guarantee that a subtype will be returned.
|
||||
** It only indicates that a subtype return is possible. False positives
|
||||
** are acceptable as they only disable an optimization. False negatives,
|
||||
** on the other hand, can lead to incorrect answers.
|
||||
*/
|
||||
static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.pParse = pParse;
|
||||
w.xExprCallback = exprNodeCanReturnSubtype;
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
return w.eCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr.
|
||||
** If it is, then resolve the expression by reading from the index and
|
||||
@@ -4586,6 +4639,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Functions that might set a subtype should not be replaced by the
|
||||
** value taken from an expression index if they are themselves an
|
||||
** argument to another scalar function or aggregate.
|
||||
** https://sqlite.org/forum/forumpost/68d284c86b082c3e */
|
||||
if( ExprHasProperty(pExpr, EP_SubtArg)
|
||||
&& sqlite3ExprCanReturnSubtype(pParse, pExpr)
|
||||
){
|
||||
continue;
|
||||
}
|
||||
|
||||
v = pParse->pVdbe;
|
||||
assert( v!=0 );
|
||||
if( p->bMaybeNullRow ){
|
||||
|
||||
+87
-3
@@ -2535,7 +2535,13 @@ static void signFunc(
|
||||
** Implementation of fpdecode(x,y,z) function.
|
||||
**
|
||||
** x is a real number that is to be decoded. y is the precision.
|
||||
** z is the maximum real precision.
|
||||
** z is the maximum real precision. Return a string that shows the
|
||||
** results of the sqlite3FpDecode() function.
|
||||
**
|
||||
** Used for testing and debugging only, specifically testing and debugging
|
||||
** of the sqlite3FpDecode() function. This SQL function does not appear
|
||||
** in production builds. This function is not an API and is subject to
|
||||
** modification or removal in future versions of SQLite.
|
||||
*/
|
||||
static void fpdecodeFunc(
|
||||
sqlite3_context *context,
|
||||
@@ -2562,6 +2568,82 @@ static void fpdecodeFunc(
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Implementation of parseuri(uri,flags) function.
|
||||
**
|
||||
** Required Arguments:
|
||||
** "uri" The URI to parse.
|
||||
** "flags" Bitmask of flags, as if to sqlite3_open_v2().
|
||||
**
|
||||
** Additional arguments beyond the first two make calls to
|
||||
** sqlite3_uri_key() for integers and sqlite3_uri_parameter for
|
||||
** anything else.
|
||||
**
|
||||
** The result is a string showing the results of calling sqlite3ParseUri().
|
||||
**
|
||||
** Used for testing and debugging only, specifically testing and debugging
|
||||
** of the sqlite3ParseUri() function. This SQL function does not appear
|
||||
** in production builds. This function is not an API and is subject to
|
||||
** modification or removal in future versions of SQLite.
|
||||
*/
|
||||
static void parseuriFunc(
|
||||
sqlite3_context *ctx,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3_str *pResult;
|
||||
const char *zVfs;
|
||||
const char *zUri;
|
||||
unsigned int flgs;
|
||||
int rc;
|
||||
sqlite3_vfs *pVfs = 0;
|
||||
char *zFile = 0;
|
||||
char *zErr = 0;
|
||||
|
||||
if( argc<2 ) return;
|
||||
pVfs = sqlite3_vfs_find(0);
|
||||
assert( pVfs );
|
||||
zVfs = pVfs->zName;
|
||||
zUri = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zUri==0 ) return;
|
||||
flgs = (unsigned int)sqlite3_value_int(argv[1]);
|
||||
rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr);
|
||||
pResult = sqlite3_str_new(0);
|
||||
if( pResult ){
|
||||
int i;
|
||||
sqlite3_str_appendf(pResult, "rc=%d", rc);
|
||||
sqlite3_str_appendf(pResult, ", flags=0x%x", flgs);
|
||||
sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0);
|
||||
sqlite3_str_appendf(pResult, ", err=%Q", zErr);
|
||||
sqlite3_str_appendf(pResult, ", file=%Q", zFile);
|
||||
if( zFile ){
|
||||
const char *z = zFile;
|
||||
z += sqlite3Strlen30(z)+1;
|
||||
while( z[0] ){
|
||||
sqlite3_str_appendf(pResult, ", %Q", z);
|
||||
z += sqlite3Strlen30(z)+1;
|
||||
}
|
||||
for(i=2; i<argc; i++){
|
||||
const char *zArg;
|
||||
if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){
|
||||
int k = sqlite3_value_int(argv[i]);
|
||||
sqlite3_str_appendf(pResult, ", '%d:%q'",k,sqlite3_uri_key(zFile, k));
|
||||
}else if( (zArg = (const char*)sqlite3_value_text(argv[i]))!=0 ){
|
||||
sqlite3_str_appendf(pResult, ", '%q:%q'",
|
||||
zArg, sqlite3_uri_parameter(zFile,zArg));
|
||||
}else{
|
||||
sqlite3_str_appendf(pResult, ", NULL");
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_result_text(ctx, sqlite3_str_finish(pResult), -1, sqlite3_free);
|
||||
}
|
||||
sqlite3_free_filename(zFile);
|
||||
sqlite3_free(zErr);
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** All of the FuncDef structures in the aBuiltinFunc[] array above
|
||||
** to the global function hash table. This occurs at start-time (as
|
||||
@@ -2624,7 +2706,8 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
|
||||
SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
|
||||
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
|
||||
FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF),
|
||||
FUNCTION2(subtype, 1, 0, 0, subtypeFunc,
|
||||
SQLITE_FUNC_TYPEOF|SQLITE_SUBTYPE),
|
||||
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
|
||||
FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN),
|
||||
FUNCTION(instr, 2, 0, 0, instrFunc ),
|
||||
@@ -2635,6 +2718,7 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
FUNCTION(abs, 1, 0, 0, absFunc ),
|
||||
#ifdef SQLITE_DEBUG
|
||||
FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ),
|
||||
FUNCTION(parseuri, -1, 0, 0, parseuriFunc ),
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
FUNCTION(round, 1, 0, 0, roundFunc ),
|
||||
@@ -2729,7 +2813,7 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
MFUNCTION(sqrt, 1, sqrt, math1Func ),
|
||||
MFUNCTION(radians, 1, degToRad, math1Func ),
|
||||
MFUNCTION(degrees, 1, radToDeg, math1Func ),
|
||||
FUNCTION(pi, 0, 0, 0, piFunc ),
|
||||
MFUNCTION(pi, 0, 0, piFunc ),
|
||||
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
|
||||
FUNCTION(sign, 1, 0, 0, signFunc ),
|
||||
INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
|
||||
|
||||
+20
-41
@@ -2464,54 +2464,33 @@ static int robust_flock(int fd, int op){
|
||||
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
|
||||
*/
|
||||
static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
int rc = SQLITE_OK;
|
||||
int reserved = 0;
|
||||
#ifdef SQLITE_DEBUG
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
#else
|
||||
UNUSED_PARAMETER(id);
|
||||
#endif
|
||||
|
||||
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
|
||||
|
||||
assert( pFile );
|
||||
assert( pFile->eFileLock<=SHARED_LOCK );
|
||||
|
||||
/* Check if a thread in this process holds such a lock */
|
||||
if( pFile->eFileLock>SHARED_LOCK ){
|
||||
reserved = 1;
|
||||
}
|
||||
/* The flock VFS only ever takes exclusive locks (see function flockLock).
|
||||
** Therefore, if this connection is holding any lock at all, no other
|
||||
** connection may be holding a RESERVED lock. So set *pResOut to 0
|
||||
** in this case.
|
||||
**
|
||||
** Or, this connection may be holding no lock. In that case, set *pResOut to
|
||||
** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the
|
||||
** db in order to roll the hot journal back. If there is another connection
|
||||
** holding a lock, that attempt will fail and an SQLITE_BUSY returned to
|
||||
** the user. With other VFS, we try to avoid this, in order to allow a reader
|
||||
** to proceed while a writer is preparing its transaction. But that won't
|
||||
** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is
|
||||
** not a problem in this case. */
|
||||
*pResOut = 0;
|
||||
|
||||
/* Otherwise see if some other process holds it. */
|
||||
if( !reserved ){
|
||||
/* attempt to get the lock */
|
||||
int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
|
||||
if( !lrc ){
|
||||
/* got the lock, unlock it */
|
||||
lrc = robust_flock(pFile->h, LOCK_UN);
|
||||
if ( lrc ) {
|
||||
int tErrno = errno;
|
||||
/* unlock failed with an error */
|
||||
lrc = SQLITE_IOERR_UNLOCK;
|
||||
storeLastErrno(pFile, tErrno);
|
||||
rc = lrc;
|
||||
}
|
||||
} else {
|
||||
int tErrno = errno;
|
||||
reserved = 1;
|
||||
/* someone else might have it reserved */
|
||||
lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
|
||||
if( IS_LOCK_ERROR(lrc) ){
|
||||
storeLastErrno(pFile, tErrno);
|
||||
rc = lrc;
|
||||
}
|
||||
}
|
||||
}
|
||||
OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
|
||||
|
||||
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
|
||||
if( (rc & 0xff) == SQLITE_IOERR ){
|
||||
rc = SQLITE_OK;
|
||||
reserved=1;
|
||||
}
|
||||
#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
|
||||
*pResOut = reserved;
|
||||
return rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1761,6 +1761,7 @@ void sqlite3Pragma(
|
||||
|
||||
/* Make sure sufficient number of registers have been allocated */
|
||||
sqlite3TouchRegister(pParse, 8+cnt);
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt);
|
||||
sqlite3ClearTempRegCache(pParse);
|
||||
|
||||
/* Do the b-tree integrity checks */
|
||||
|
||||
@@ -1183,6 +1183,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the function may call sqlite3_value_subtype(), then set the
|
||||
** EP_SubtArg flag on all of its argument expressions. This prevents
|
||||
** where.c from replacing the expression with a value read from an
|
||||
** index on the same expression, which will not have the correct
|
||||
** subtype. Also set the flag if the function expression itself is
|
||||
** an EP_SubtArg expression. In this case subtypes are required as
|
||||
** the function may return a value with a subtype back to its
|
||||
** caller using sqlite3_result_value(). */
|
||||
if( (pDef->funcFlags & SQLITE_SUBTYPE)
|
||||
|| ExprHasProperty(pExpr, EP_SubtArg)
|
||||
){
|
||||
int ii;
|
||||
for(ii=0; ii<n; ii++){
|
||||
ExprSetProperty(pList->a[ii].pExpr, EP_SubtArg);
|
||||
}
|
||||
}
|
||||
|
||||
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
|
||||
/* For the purposes of the EP_ConstFunc flag, date and time
|
||||
** functions and other functions that change slowly are considered
|
||||
|
||||
+60
-54
@@ -1448,6 +1448,7 @@ struct ShellState {
|
||||
u8 bSafeMode; /* True to prohibit unsafe operations */
|
||||
u8 bSafeModePersist; /* The long-term value of bSafeMode */
|
||||
u8 eRestoreState; /* See comments above doAutoDetectRestore() */
|
||||
u8 crlfMode; /* Do NL-to-CRLF translations when enabled (maybe) */
|
||||
ColModeOpts cmOpts; /* Option values affecting columnar mode output */
|
||||
unsigned statsOn; /* True to display memory stats before each finalize */
|
||||
unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
|
||||
@@ -1628,13 +1629,7 @@ static const char *modeDescr[] = {
|
||||
#define SEP_Tab "\t"
|
||||
#define SEP_Space " "
|
||||
#define SEP_Comma ","
|
||||
#ifdef SQLITE_U8TEXT_ONLY
|
||||
/* With the SQLITE_U8TEXT_ONLY option, the output will always be in
|
||||
** text mode. The \r will be inserted automatically. */
|
||||
# define SEP_CrLf "\n"
|
||||
#else
|
||||
# define SEP_CrLf "\r\n"
|
||||
#endif
|
||||
#define SEP_CrLf "\r\n"
|
||||
#define SEP_Unit "\x1F"
|
||||
#define SEP_Record "\x1E"
|
||||
|
||||
@@ -1719,7 +1714,7 @@ static void editFunc(
|
||||
char *zCmd = 0;
|
||||
int bBin;
|
||||
int rc;
|
||||
int hasCRNL = 0;
|
||||
int hasCRLF = 0;
|
||||
FILE *f = 0;
|
||||
sqlite3_int64 sz;
|
||||
sqlite3_int64 x;
|
||||
@@ -1764,7 +1759,7 @@ static void editFunc(
|
||||
}else{
|
||||
const char *z = (const char*)sqlite3_value_text(argv[0]);
|
||||
/* Remember whether or not the value originally contained \r\n */
|
||||
if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
|
||||
if( z && strstr(z,"\r\n")!=0 ) hasCRLF = 1;
|
||||
x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
|
||||
}
|
||||
fclose(f);
|
||||
@@ -1809,7 +1804,7 @@ static void editFunc(
|
||||
sqlite3_result_blob64(context, p, sz, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_int64 i, j;
|
||||
if( hasCRNL ){
|
||||
if( hasCRLF ){
|
||||
/* If the original contains \r\n then do no conversions back to \n */
|
||||
}else{
|
||||
/* If the file did not originally contain \r\n then convert any new
|
||||
@@ -1851,6 +1846,21 @@ static void outputModePop(ShellState *p){
|
||||
memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
|
||||
}
|
||||
|
||||
/*
|
||||
** Set output mode to text or binary for Windows.
|
||||
*/
|
||||
static void setCrlfMode(ShellState *p){
|
||||
#ifdef _WIN32
|
||||
if( p->crlfMode ){
|
||||
sqlite3_fsetmode(p->out, _O_TEXT);
|
||||
}else{
|
||||
sqlite3_fsetmode(p->out, _O_BINARY);
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the given string as a hex-encoded blob (eg. X'1234' )
|
||||
*/
|
||||
@@ -1901,9 +1911,10 @@ static const char *unused_string(
|
||||
**
|
||||
** See also: output_quoted_escaped_string()
|
||||
*/
|
||||
static void output_quoted_string(FILE *out, const char *z){
|
||||
static void output_quoted_string(ShellState *p, const char *z){
|
||||
int i;
|
||||
char c;
|
||||
FILE *out = p->out;
|
||||
sqlite3_fsetmode(out, _O_BINARY);
|
||||
if( z==0 ) return;
|
||||
for(i=0; (c = z[i])!=0 && c!='\''; i++){}
|
||||
@@ -1929,7 +1940,7 @@ static void output_quoted_string(FILE *out, const char *z){
|
||||
}
|
||||
sqlite3_fputs("'", out);
|
||||
}
|
||||
sqlite3_fsetmode(out, _O_TEXT);
|
||||
setCrlfMode(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1941,9 +1952,10 @@ static void output_quoted_string(FILE *out, const char *z){
|
||||
** This is like output_quoted_string() but with the addition of the \r\n
|
||||
** escape mechanism.
|
||||
*/
|
||||
static void output_quoted_escaped_string(FILE *out, const char *z){
|
||||
static void output_quoted_escaped_string(ShellState *p, const char *z){
|
||||
int i;
|
||||
char c;
|
||||
FILE *out = p->out;
|
||||
sqlite3_fsetmode(out, _O_BINARY);
|
||||
for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
|
||||
if( c==0 ){
|
||||
@@ -1996,7 +2008,7 @@ static void output_quoted_escaped_string(FILE *out, const char *z){
|
||||
sqlite3_fprintf(out, ",'%s',char(10))", zNL);
|
||||
}
|
||||
}
|
||||
sqlite3_fsetmode(stdout, _O_TEXT);
|
||||
setCrlfMode(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2793,7 +2805,7 @@ static int shell_callback(
|
||||
}
|
||||
sqlite3_fputs(p->rowSeparator, p->out);
|
||||
}
|
||||
sqlite3_fsetmode(p->out, _O_TEXT);
|
||||
setCrlfMode(p);
|
||||
break;
|
||||
}
|
||||
case MODE_Insert: {
|
||||
@@ -2821,9 +2833,9 @@ static int shell_callback(
|
||||
sqlite3_fputs("NULL", p->out);
|
||||
}else if( aiType && aiType[i]==SQLITE_TEXT ){
|
||||
if( ShellHasFlag(p, SHFLG_Newlines) ){
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
output_quoted_string(p, azArg[i]);
|
||||
}else{
|
||||
output_quoted_escaped_string(p->out, azArg[i]);
|
||||
output_quoted_escaped_string(p, azArg[i]);
|
||||
}
|
||||
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
|
||||
sqlite3_fputs(azArg[i], p->out);
|
||||
@@ -2852,9 +2864,9 @@ static int shell_callback(
|
||||
}else if( isNumber(azArg[i], 0) ){
|
||||
sqlite3_fputs(azArg[i], p->out);
|
||||
}else if( ShellHasFlag(p, SHFLG_Newlines) ){
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
output_quoted_string(p, azArg[i]);
|
||||
}else{
|
||||
output_quoted_escaped_string(p->out, azArg[i]);
|
||||
output_quoted_escaped_string(p, azArg[i]);
|
||||
}
|
||||
}
|
||||
sqlite3_fputs(");\n", p->out);
|
||||
@@ -2907,7 +2919,7 @@ static int shell_callback(
|
||||
if( p->cnt==0 && p->showHeader ){
|
||||
for(i=0; i<nArg; i++){
|
||||
if( i>0 ) sqlite3_fputs(p->colSeparator, p->out);
|
||||
output_quoted_string(p->out, azCol[i]);
|
||||
output_quoted_string(p, azCol[i]);
|
||||
}
|
||||
sqlite3_fputs(p->rowSeparator, p->out);
|
||||
}
|
||||
@@ -2917,7 +2929,7 @@ static int shell_callback(
|
||||
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
|
||||
sqlite3_fputs("NULL", p->out);
|
||||
}else if( aiType && aiType[i]==SQLITE_TEXT ){
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
output_quoted_string(p, azArg[i]);
|
||||
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
|
||||
sqlite3_fputs(azArg[i], p->out);
|
||||
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
|
||||
@@ -2932,7 +2944,7 @@ static int shell_callback(
|
||||
}else if( isNumber(azArg[i], 0) ){
|
||||
sqlite3_fputs(azArg[i], p->out);
|
||||
}else{
|
||||
output_quoted_string(p->out, azArg[i]);
|
||||
output_quoted_string(p, azArg[i]);
|
||||
}
|
||||
}
|
||||
sqlite3_fputs(p->rowSeparator, p->out);
|
||||
@@ -4751,7 +4763,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
|
||||
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
|
||||
|
||||
if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
|
||||
if( !dataOnly ) sqlite3_fputs("DELETE FROM sqlite_sequence;\n", p->out);
|
||||
/* no-op */
|
||||
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
|
||||
if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
|
||||
}else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
|
||||
@@ -4936,10 +4948,7 @@ static const char *(azHelp[]) = {
|
||||
".clone NEWDB Clone data into NEWDB from the existing database",
|
||||
#endif
|
||||
".connection [close] [#] Open or close an auxiliary database connection",
|
||||
#if defined(_WIN32) && !defined(SQLITE_U8TEXT_ONLY) \
|
||||
&& !defined(SQLITE_U8TEXT_STDIO)
|
||||
".crnl on|off Translate \\n to \\r\\n. Default ON",
|
||||
#endif /* _WIN32 && U8TEXT_ONLY && U8TEXT_STDIO */
|
||||
".crlf ?on|off? Whether or not to use \\r\\n line endings",
|
||||
".databases List names and files of attached databases",
|
||||
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
|
||||
#if SQLITE_SHELL_HAVE_RECOVER
|
||||
@@ -5938,7 +5947,7 @@ static void output_file_close(FILE *f){
|
||||
** recognized and do the right thing. NULL is returned if the output
|
||||
** filename is "off".
|
||||
*/
|
||||
static FILE *output_file_open(const char *zFile, int bTextMode){
|
||||
static FILE *output_file_open(const char *zFile){
|
||||
FILE *f;
|
||||
if( cli_strcmp(zFile,"stdout")==0 ){
|
||||
f = stdout;
|
||||
@@ -5947,7 +5956,7 @@ static FILE *output_file_open(const char *zFile, int bTextMode){
|
||||
}else if( cli_strcmp(zFile, "off")==0 ){
|
||||
f = 0;
|
||||
}else{
|
||||
f = sqlite3_fopen(zFile, bTextMode ? "w" : "wb");
|
||||
f = sqlite3_fopen(zFile, "w");
|
||||
if( f==0 ){
|
||||
sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
|
||||
}
|
||||
@@ -6420,6 +6429,7 @@ static void output_redir(ShellState *p, FILE *pfNew){
|
||||
sqlite3_fputs("Output already redirected.\n", stderr);
|
||||
}else{
|
||||
p->out = pfNew;
|
||||
setCrlfMode(p);
|
||||
if( p->mode==MODE_Www ){
|
||||
sqlite3_fputs(
|
||||
"<!DOCTYPE html>\n"
|
||||
@@ -6475,6 +6485,7 @@ static void output_reset(ShellState *p){
|
||||
}
|
||||
p->outfile[0] = 0;
|
||||
p->out = stdout;
|
||||
setCrlfMode(p);
|
||||
}
|
||||
#else
|
||||
# define output_redir(SS,pfO)
|
||||
@@ -8427,9 +8438,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
/* Undocumented. Legacy only. See "crnl" below */
|
||||
/* Undocumented. Legacy only. See "crlf" below */
|
||||
if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){
|
||||
eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n");
|
||||
eputz("The \".binary\" command is deprecated.\n");
|
||||
rc = 1;
|
||||
}else
|
||||
|
||||
@@ -8555,22 +8566,18 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){
|
||||
#if !defined(_WIN32) || defined(SQLITE_U8TEXT_ONLY) \
|
||||
|| defined(SQLITE_U8TEXT_STDIO)
|
||||
sqlite3_fputs("The \".crnl\" command is disable in this build.\n", p->out);
|
||||
#else
|
||||
if( c=='c' && n==4
|
||||
&& (cli_strncmp(azArg[0], "crlf", n)==0
|
||||
|| cli_strncmp(azArg[0], "crnl",n)==0)
|
||||
){
|
||||
if( nArg==2 ){
|
||||
if( booleanValue(azArg[1]) ){
|
||||
sqlite3_fsetmode(p->out, _O_TEXT);
|
||||
}else{
|
||||
sqlite3_fsetmode(p->out, _O_BINARY);
|
||||
}
|
||||
}else{
|
||||
eputz("Usage: .crnl on|off\n");
|
||||
rc = 1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
p->crlfMode = booleanValue(azArg[1]);
|
||||
#else
|
||||
p->crlfMode = 0;
|
||||
#endif
|
||||
}
|
||||
sqlite3_fprintf(stderr, "crlf is %s\n", p->crlfMode ? "ON" : "OFF");
|
||||
}else
|
||||
|
||||
if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
|
||||
@@ -9650,7 +9657,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
output_file_close(p->pLog);
|
||||
if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
|
||||
p->pLog = output_file_open(zFile, 0);
|
||||
p->pLog = output_file_open(zFile);
|
||||
}
|
||||
}else
|
||||
|
||||
@@ -9905,7 +9912,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|| (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0)
|
||||
){
|
||||
char *zFile = 0;
|
||||
int bTxtMode = 0;
|
||||
int i;
|
||||
int eMode = 0;
|
||||
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */
|
||||
@@ -9987,11 +9993,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
/* web-browser mode. */
|
||||
newTempFile(p, "html");
|
||||
if( !bPlain ) p->mode = MODE_Www;
|
||||
bTxtMode = 1;
|
||||
}else{
|
||||
/* text editor mode */
|
||||
newTempFile(p, "txt");
|
||||
bTxtMode = 1;
|
||||
}
|
||||
sqlite3_free(zFile);
|
||||
zFile = sqlite3_mprintf("%s", p->zTempFile);
|
||||
@@ -10015,7 +10019,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
FILE *pfFile = output_file_open(zFile, bTxtMode);
|
||||
FILE *pfFile = output_file_open(zFile);
|
||||
if( pfFile==0 ){
|
||||
if( cli_strcmp(zFile,"off")!=0 ){
|
||||
sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
|
||||
@@ -10023,13 +10027,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = 1;
|
||||
} else {
|
||||
output_redir(p, pfFile);
|
||||
if( zBom ) sqlite3_fputs(zBom, pfFile);
|
||||
if( bPlain && eMode=='w' ){
|
||||
sqlite3_fputs(
|
||||
"<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n",
|
||||
pfFile
|
||||
);
|
||||
}
|
||||
if( zBom ) sqlite3_fputs(zBom, pfFile);
|
||||
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
|
||||
}
|
||||
}
|
||||
@@ -10226,7 +10230,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
#ifdef SQLITE_OMIT_POPEN
|
||||
eputz("Error: pipes are not supported in this OS\n");
|
||||
rc = 1;
|
||||
p->out = stdout;
|
||||
#else
|
||||
p->in = sqlite3_popen(azArg[1]+1, "r");
|
||||
if( p->in==0 ){
|
||||
@@ -11213,7 +11216,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
/* Begin redirecting output to the file "testcase-out.txt" */
|
||||
if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){
|
||||
output_reset(p);
|
||||
p->out = output_file_open("testcase-out.txt", 0);
|
||||
p->out = output_file_open("testcase-out.txt");
|
||||
if( p->out==0 ){
|
||||
eputz("Error: cannot open 'testcase-out.txt'\n");
|
||||
}
|
||||
@@ -11717,7 +11720,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else{
|
||||
output_file_close(p->traceOut);
|
||||
p->traceOut = output_file_open(z, 0);
|
||||
p->traceOut = output_file_open(z);
|
||||
}
|
||||
}
|
||||
if( p->traceOut==0 ){
|
||||
@@ -12594,6 +12597,9 @@ static void main_init(ShellState *data) {
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->normalMode = data->cMode = data->mode = MODE_List;
|
||||
data->autoExplain = 1;
|
||||
#ifdef _WIN32
|
||||
data->crlfMode = 1;
|
||||
#endif
|
||||
data->pAuxDb = &data->aAuxDb[0];
|
||||
memcpy(data->colSeparator,SEP_Column, 2);
|
||||
memcpy(data->rowSeparator,SEP_Row, 2);
|
||||
|
||||
+11
-1
@@ -4232,7 +4232,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** is the number of bytes in the input string <i>including</i>
|
||||
** the nul-terminator.
|
||||
** Note that nByte measure the length of the input in bytes, not
|
||||
** characters, even for the UTF-16 inferfaces.
|
||||
** characters, even for the UTF-16 interfaces.
|
||||
**
|
||||
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
|
||||
** past the end of the first SQL statement in zSql. These routines only
|
||||
@@ -9344,6 +9344,16 @@ typedef struct sqlite3_backup sqlite3_backup;
|
||||
** APIs are not strictly speaking threadsafe. If they are invoked at the
|
||||
** same time as another thread is invoking sqlite3_backup_step() it is
|
||||
** possible that they return invalid values.
|
||||
**
|
||||
** <b>Alternatives To Using The Backup API</b>
|
||||
**
|
||||
** Other techniques for safely creating a consistent backup of an SQLite
|
||||
** database include:
|
||||
**
|
||||
** <ul>
|
||||
** <li> The [VACUUM INTO] command.
|
||||
** <li> The [sqlite3_rsync] utility program.
|
||||
** </ul>
|
||||
*/
|
||||
sqlite3_backup *sqlite3_backup_init(
|
||||
sqlite3 *pDest, /* Destination database handle */
|
||||
|
||||
+1
-1
@@ -3104,7 +3104,7 @@ struct Expr {
|
||||
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
|
||||
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
|
||||
#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
|
||||
/* 0x80000000 // Available */
|
||||
#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */
|
||||
|
||||
/* The EP_Propagate mask is a set of properties that automatically propagate
|
||||
** upwards into parent nodes.
|
||||
|
||||
+15
-1
@@ -3981,7 +3981,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
** The EXTERN macros are required by TCL in order to work on windows.
|
||||
*/
|
||||
EXTERN int Sqlite3_Init(Tcl_Interp *interp){
|
||||
int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
|
||||
int rc = Tcl_InitStubs(interp, "8.5-", 0) ? TCL_OK : TCL_ERROR;
|
||||
if( rc==TCL_OK ){
|
||||
Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
|
||||
#ifndef SQLITE_3_SUFFIX_ONLY
|
||||
@@ -4037,6 +4037,20 @@ EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);}
|
||||
static const char *tclsh_main_loop(void){
|
||||
static const char zMainloop[] =
|
||||
"if {[llength $argv]>=1} {\n"
|
||||
#ifdef WIN32
|
||||
"set new [list]\n"
|
||||
"foreach arg $argv {\n"
|
||||
"if {[file exists $arg]} {\n"
|
||||
"lappend new $arg\n"
|
||||
"} else {\n"
|
||||
"foreach match [lsort [glob -nocomplain $arg]] {\n"
|
||||
"lappend new $match\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
"set argv $new\n"
|
||||
"unset new\n"
|
||||
#endif
|
||||
"set argv0 [lindex $argv 0]\n"
|
||||
"set argv [lrange $argv 1 end]\n"
|
||||
"source $argv0\n"
|
||||
|
||||
@@ -136,7 +136,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
|
||||
c = *(zIn++); \
|
||||
if( c>=0xc0 ){ \
|
||||
c = sqlite3Utf8Trans1[c-0xc0]; \
|
||||
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
|
||||
while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \
|
||||
c = (c<<6) + (0x3f & *(zIn++)); \
|
||||
} \
|
||||
if( c<0x80 \
|
||||
|
||||
-58
@@ -6302,58 +6302,6 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Expression Node callback for sqlite3ExprCanReturnSubtype().
|
||||
**
|
||||
** Only a function call is able to return a subtype. So if the node
|
||||
** is not a function call, return WRC_Prune immediately.
|
||||
**
|
||||
** A function call is able to return a subtype if it has the
|
||||
** SQLITE_RESULT_SUBTYPE property.
|
||||
**
|
||||
** Assume that every function is able to pass-through a subtype from
|
||||
** one of its argument (using sqlite3_result_value()). Most functions
|
||||
** are not this way, but we don't have a mechanism to distinguish those
|
||||
** that are from those that are not, so assume they all work this way.
|
||||
** That means that if one of its arguments is another function and that
|
||||
** other function is able to return a subtype, then this function is
|
||||
** able to return a subtype.
|
||||
*/
|
||||
static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){
|
||||
int n;
|
||||
FuncDef *pDef;
|
||||
sqlite3 *db;
|
||||
if( pExpr->op!=TK_FUNCTION ){
|
||||
return WRC_Prune;
|
||||
}
|
||||
assert( ExprUseXList(pExpr) );
|
||||
db = pWalker->pParse->db;
|
||||
n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0;
|
||||
pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
|
||||
if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
|
||||
pWalker->eCode = 1;
|
||||
return WRC_Prune;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if expression pExpr is able to return a subtype.
|
||||
**
|
||||
** A TRUE return does not guarantee that a subtype will be returned.
|
||||
** It only indicates that a subtype return is possible. False positives
|
||||
** are acceptable as they only disable an optimization. False negatives,
|
||||
** on the other hand, can lead to incorrect answers.
|
||||
*/
|
||||
static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){
|
||||
Walker w;
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.pParse = pParse;
|
||||
w.xExprCallback = exprNodeCanReturnSubtype;
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
return w.eCode;
|
||||
}
|
||||
|
||||
/*
|
||||
** The index pIdx is used by a query and contains one or more expressions.
|
||||
** In other words pIdx is an index on an expression. iIdxCur is the cursor
|
||||
@@ -6387,12 +6335,6 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
|
||||
continue;
|
||||
}
|
||||
if( sqlite3ExprIsConstant(0,pExpr) ) continue;
|
||||
if( pExpr->op==TK_FUNCTION && sqlite3ExprCanReturnSubtype(pParse,pExpr) ){
|
||||
/* Functions that might set a subtype should not be replaced by the
|
||||
** value taken from an expression index since the index omits the
|
||||
** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
|
||||
continue;
|
||||
}
|
||||
p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr));
|
||||
if( p==0 ) break;
|
||||
p->pIENext = pParse->pIdxEpr;
|
||||
|
||||
+16
-11
@@ -219,20 +219,25 @@ static int isLikeOrGlob(
|
||||
z = (u8*)pRight->u.zToken;
|
||||
}
|
||||
if( z ){
|
||||
|
||||
/* Count the number of prefix characters prior to the first wildcard.
|
||||
** If the underlying database has a UTF16LE encoding, then only consider
|
||||
** ASCII characters. Note that the encoding of z[] is UTF8 - we are
|
||||
** dealing with only UTF8 here in this code, but the database engine
|
||||
** itself might be processing content using a different encoding. */
|
||||
/* Count the number of prefix bytes prior to the first wildcard.
|
||||
** or U+fffd character. If the underlying database has a UTF16LE
|
||||
** encoding, then only consider ASCII characters. Note that the
|
||||
** encoding of z[] is UTF8 - we are dealing with only UTF8 here in
|
||||
** this code, but the database engine itself might be processing
|
||||
** content using a different encoding. */
|
||||
cnt = 0;
|
||||
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
|
||||
cnt++;
|
||||
if( c==wc[3] && z[cnt]!=0 ){
|
||||
if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){
|
||||
cnt++;
|
||||
}else if( c>=0x80 && ENC(db)==SQLITE_UTF16LE ){
|
||||
cnt--;
|
||||
break;
|
||||
}else if( c>=0x80 ){
|
||||
const u8 *z2 = z+cnt-1;
|
||||
if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){
|
||||
cnt--;
|
||||
break;
|
||||
}else{
|
||||
cnt = (int)(z2-z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +249,7 @@ static int isLikeOrGlob(
|
||||
** range search. The third is because the caller assumes that the pattern
|
||||
** consists of at least one character after all escapes have been
|
||||
** removed. */
|
||||
if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){
|
||||
if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){
|
||||
Expr *pPrefix;
|
||||
|
||||
/* A "complete" match if the pattern ends with "*" or "%" */
|
||||
|
||||
@@ -276,4 +276,31 @@ do_catchsql_test 6.3 {
|
||||
UPDATE t1 SET x='hello world' WHERE rowid=1;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
BEGIN;
|
||||
CREATE TABLE p1(x PRIMARY KEY);
|
||||
CREATE TABLE c1(y);
|
||||
|
||||
PRAGMA schema_version = 0;
|
||||
PRAGMA writable_schema = RESET;
|
||||
|
||||
INSERT INTO c1 VALUES(1000);
|
||||
ROLLBACK;
|
||||
}
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
PRAGMA table_info = p1;
|
||||
} {0 x {} 0 {} 1}
|
||||
|
||||
do_catchsql_test 7.2 {
|
||||
SELECT * FROM p1;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 7.3 {
|
||||
PRAGMA integrity_check
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# 2024-10-05
|
||||
#
|
||||
# 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 file is testing indexes on expressions.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix indexexpr3
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, j);
|
||||
INSERT INTO t1 VALUES(1, '{x:"one"}');
|
||||
INSERT INTO t1 VALUES(2, '{x:"two"}');
|
||||
INSERT INTO t1 VALUES(3, '{x:"three"}');
|
||||
|
||||
CREATE INDEX i1 ON t1( json_extract(j, '$.x') );
|
||||
CREATE INDEX i2 ON t1( a, json_extract(j, '$.x') );
|
||||
}
|
||||
|
||||
proc do_hasfunction_test {tn sql res} {
|
||||
set nFunction 0
|
||||
db eval "EXPLAIN $sql" x {
|
||||
if {$x(opcode)=="Function"} {
|
||||
incr nFunction
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test $tn "
|
||||
SELECT $nFunction;
|
||||
$sql
|
||||
" $res
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.1 {
|
||||
SELECT json_extract(j, '$.x') FROM t1 ORDER BY 1;
|
||||
} {
|
||||
0 one three two
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.2 {
|
||||
SELECT json_extract(j, '$.x') FROM t1 WHERE a=2
|
||||
} {
|
||||
0 two
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.3 {
|
||||
SELECT coalesce(json_extract(j, '$.x'), 'five') FROM t1 WHERE a=2
|
||||
} {
|
||||
0 two
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.4 {
|
||||
SELECT json_extract(j, '$.x') || '.two' FROM t1 WHERE a=2
|
||||
} {
|
||||
0 two.two
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.5 {
|
||||
SELECT json_insert( '{}', '$.y', json_extract(j, '$.x') ) FROM t1 WHERE a=2
|
||||
} {
|
||||
2 {{"y":"two"}}
|
||||
}
|
||||
|
||||
do_hasfunction_test 1.6 {
|
||||
SELECT json_insert( '{}', '$.y', coalesce( json_extract(j, '$.x'), 'five' ) )
|
||||
FROM t1 WHERE a=2
|
||||
} {
|
||||
2 {{"y":"two"}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-3
@@ -731,16 +731,16 @@ ifcapable like_opt&&!icu {
|
||||
}
|
||||
do_test like-9.5.1 {
|
||||
set res [sqlite3_exec_hex db {
|
||||
SELECT x FROM t2 WHERE x LIKE '%fe%25'
|
||||
SELECT 1 FROM t2 WHERE x LIKE '%fe%25'
|
||||
}]
|
||||
} {0 {}}
|
||||
} {0 {1 1}}
|
||||
ifcapable explain {
|
||||
do_test like-9.5.2 {
|
||||
set res [sqlite3_exec_hex db {
|
||||
EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%fe%25'
|
||||
}]
|
||||
regexp {INDEX i2} $res
|
||||
} {1}
|
||||
} {0}
|
||||
}
|
||||
|
||||
# Do an SQL statement. Append the search count to the end of the result.
|
||||
|
||||
@@ -146,6 +146,54 @@ do_test lock5-flock.8 {
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
do_test lock5-flock.9 {
|
||||
sqlite3 db test.db -vfs unix-flock
|
||||
execsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 2}
|
||||
|
||||
do_test lock5-flock.10 {
|
||||
sqlite3 db2 test.db -vfs unix-flock
|
||||
execsql {
|
||||
SELECT * FROM t1
|
||||
} db2
|
||||
} {1 2}
|
||||
|
||||
do_test lock5-flock.10 {
|
||||
execsql {
|
||||
PRAGMA cache_size = 1;
|
||||
BEGIN;
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000
|
||||
)
|
||||
INSERT INTO t1 SELECT i, i+1 FROM s;
|
||||
}
|
||||
|
||||
catchsql {
|
||||
SELECT * FROM t1
|
||||
} db2
|
||||
} {1 {database is locked}}
|
||||
|
||||
if {[permutation]!="inmemory_journal"} {
|
||||
do_test lock5-flock.11 {
|
||||
forcecopy test.db test.db2
|
||||
forcecopy test.db-journal test.db2-journal
|
||||
db2 close
|
||||
sqlite3 db2 test.db2 -vfs unix-flock
|
||||
catchsql {
|
||||
SELECT * FROM t1
|
||||
} db2
|
||||
} {0 {1 2}}
|
||||
|
||||
do_test lock5-flock.12 {
|
||||
file exists test.db2-journal
|
||||
} 0
|
||||
}
|
||||
|
||||
db close
|
||||
db2 close
|
||||
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
+4
-1
@@ -1063,7 +1063,10 @@ do_test shell1-5.0 {
|
||||
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>=0x80} {
|
||||
if {$i<=0x9F || $tcl_version>=9.0} continue
|
||||
if {$tcl_platform(platform)=="windows"} continue
|
||||
}
|
||||
if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue
|
||||
if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue
|
||||
set hex [format %02X $i]
|
||||
|
||||
@@ -95,7 +95,7 @@ proc run_thread_tests {{print_warning 0}} {
|
||||
if {[info commands sqlthread] eq ""} {
|
||||
set zProblem "SQLite build is not threadsafe"
|
||||
}
|
||||
if {![info exists ::tcl_platform(threaded)]} {
|
||||
if {![tcl::pkgconfig get threaded]} {
|
||||
set zProblem "Linked against a non-threadsafe Tcl build"
|
||||
}
|
||||
if {[info exists zProblem]} {
|
||||
@@ -107,4 +107,3 @@ proc run_thread_tests {{print_warning 0}} {
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
+4
-13
@@ -54,16 +54,7 @@ close $in
|
||||
scan $vers %d.%d.%d v1 v2 v3
|
||||
set v2 [format 3%02d%02d00 $v2 $v3]
|
||||
set name sqlite-tools-$OS-$ARCH-$v2.zip
|
||||
|
||||
if {$OS=="win32"} {
|
||||
# The win32 tar.exe supports the -a ("auto-compress") option. This causes
|
||||
# tar to create an archive type based on the extension of the output file.
|
||||
# In this case, a zip file.
|
||||
puts "tar -a -cf $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE"
|
||||
puts [exec tar -a -cf $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE]
|
||||
puts "$name: [file size $name] bytes"
|
||||
} else {
|
||||
puts "zip $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE"
|
||||
puts [exec zip $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE]
|
||||
puts [exec ls -l $name]
|
||||
}
|
||||
set toollist "sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE sqlite3_rsync$EXE"
|
||||
puts "zip $name {*}$toollist"
|
||||
exec zip $name {*}$toollist
|
||||
puts "$name: [file size $name] bytes"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "sqlite3.h"
|
||||
|
||||
static const char zUsage[] =
|
||||
"sqlite3-rsync ORIGIN REPLICA ?OPTIONS?\n"
|
||||
"sqlite3_rsync ORIGIN REPLICA ?OPTIONS?\n"
|
||||
"\n"
|
||||
"One of ORIGIN or REPLICA is a pathname to a database on the local\n"
|
||||
"machine and the other is of the form \"USER@HOST:PATH\" describing\n"
|
||||
@@ -30,7 +30,7 @@ static const char zUsage[] =
|
||||
"\n"
|
||||
"OPTIONS:\n"
|
||||
"\n"
|
||||
" --exe PATH Name of the sqlite3-rsync program on the remote side\n"
|
||||
" --exe PATH Name of the sqlite3_rsync program on the remote side\n"
|
||||
" --help Show this help screen\n"
|
||||
" --ssh PATH Name of the SSH program used to reach the remote side\n"
|
||||
" -v Verbose. Multiple v's for increasing output\n"
|
||||
@@ -1197,6 +1197,7 @@ static void originSide(SQLiteRsync *p){
|
||||
int c = 0;
|
||||
unsigned int nPage = 0;
|
||||
unsigned int iPage = 0;
|
||||
unsigned int lockBytePage = 0;
|
||||
unsigned int szPg = 0;
|
||||
sqlite3_stmt *pCkHash = 0;
|
||||
char buf[200];
|
||||
@@ -1235,6 +1236,7 @@ static void originSide(SQLiteRsync *p){
|
||||
p->nPage = nPage;
|
||||
p->szPage = szPg;
|
||||
p->iProtocol = PROTOCOL_VERSION;
|
||||
lockBytePage = (1<<30)/szPg + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1290,6 +1292,7 @@ static void originSide(SQLiteRsync *p){
|
||||
" INSERT INTO badHash SELECT n FROM c",
|
||||
iPage+1, p->nPage);
|
||||
}
|
||||
runSql(p, "DELETE FROM badHash WHERE pgno=%d", lockBytePage);
|
||||
pStmt = prepareStmt(p,
|
||||
"SELECT pgno, data"
|
||||
" FROM badHash JOIN sqlite_dbpage('main') USING(pgno)");
|
||||
@@ -1583,13 +1586,13 @@ static char *hostSeparator(const char *zIn){
|
||||
**
|
||||
** Input formats:
|
||||
**
|
||||
** (1) sqlite3-rsync FILENAME1 USER@HOST:FILENAME2
|
||||
** (1) sqlite3_rsync FILENAME1 USER@HOST:FILENAME2
|
||||
**
|
||||
** (2) sqlite3-rsync USER@HOST:FILENAME1 FILENAME2
|
||||
** (2) sqlite3_rsync USER@HOST:FILENAME1 FILENAME2
|
||||
**
|
||||
** (3) sqlite3-rsync --origin FILENAME1
|
||||
** (3) sqlite3_rsync --origin FILENAME1
|
||||
**
|
||||
** (4) sqlite3-rsync --replica FILENAME2
|
||||
** (4) sqlite3_rsync --replica FILENAME2
|
||||
**
|
||||
** The user types (1) or (2). SSH launches (3) or (4).
|
||||
**
|
||||
@@ -1613,7 +1616,7 @@ int main(int argc, char const * const *argv){
|
||||
FILE *pOut = 0;
|
||||
int childPid = 0;
|
||||
const char *zSsh = "ssh";
|
||||
const char *zExe = "sqlite3-rsync";
|
||||
const char *zExe = "sqlite3_rsync";
|
||||
char *zCmd = 0;
|
||||
sqlite3_int64 tmStart;
|
||||
sqlite3_int64 tmEnd;
|
||||
@@ -854,12 +854,16 @@ int main(int argc, char **argv){
|
||||
xErr = errorMsgNH;
|
||||
continue;
|
||||
}
|
||||
usage:
|
||||
fprintf(stderr, "Usage: %s DIRECTORY\n"
|
||||
" or: %s --sha1 FILE ...\n"
|
||||
" or: %s --sha3 FILE ...\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if( !zDir ){
|
||||
goto usage;
|
||||
}
|
||||
if( strlen(zDir)>1000 ){
|
||||
fprintf(stderr, "Directory argument too big: [%s]\n", zDir);
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user