mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: f9ce1ababbd62c579658c737059f6992bdb32909e7a06282fe6a359d10ad1272
This commit is contained in:
81
Makefile.in
81
Makefile.in
@@ -652,6 +652,7 @@ FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c
|
|||||||
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
|
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
|
||||||
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
|
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
|
||||||
FUZZCHECK_SRC += $(TOP)/test/vt02.c
|
FUZZCHECK_SRC += $(TOP)/test/vt02.c
|
||||||
|
FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c
|
||||||
FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c
|
FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c
|
||||||
DBFUZZ_OPT =
|
DBFUZZ_OPT =
|
||||||
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
|
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
|
||||||
@@ -662,11 +663,16 @@ SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE)
|
|||||||
SQLITE3_SHELL_TARGET_1 =
|
SQLITE3_SHELL_TARGET_1 =
|
||||||
SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@)
|
SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@)
|
||||||
|
|
||||||
|
# Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either
|
||||||
|
# libtclsqlite3.la or an empty value.
|
||||||
|
libtclsqlite3.la_0 =
|
||||||
|
libtclsqlite3.la_1 = libtclsqlite3.la
|
||||||
|
|
||||||
# This is the default Makefile target. The objects listed here
|
# This is the default Makefile target. The objects listed here
|
||||||
# are what get build when you type just "make" with no arguments.
|
# are what get build when you type just "make" with no arguments.
|
||||||
#
|
#
|
||||||
all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \
|
all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \
|
||||||
$(HAVE_TCL:1=libtclsqlite3.la)
|
$(libtclsqlite3.la_$(HAVE_TCL))
|
||||||
|
|
||||||
Makefile: $(TOP)/Makefile.in
|
Makefile: $(TOP)/Makefile.in
|
||||||
./config.status
|
./config.status
|
||||||
@@ -1184,6 +1190,7 @@ SHELL_DEP = \
|
|||||||
$(TOP)/ext/misc/ieee754.c \
|
$(TOP)/ext/misc/ieee754.c \
|
||||||
$(TOP)/ext/misc/memtrace.c \
|
$(TOP)/ext/misc/memtrace.c \
|
||||||
$(TOP)/ext/misc/pcachetrace.c \
|
$(TOP)/ext/misc/pcachetrace.c \
|
||||||
|
$(TOP)/ext/misc/percentile.c \
|
||||||
$(TOP)/ext/misc/regexp.c \
|
$(TOP)/ext/misc/regexp.c \
|
||||||
$(TOP)/ext/misc/series.c \
|
$(TOP)/ext/misc/series.c \
|
||||||
$(TOP)/ext/misc/shathree.c \
|
$(TOP)/ext/misc/shathree.c \
|
||||||
@@ -1392,7 +1399,7 @@ srctree-check: $(TOP)/tool/srctree-check.tcl
|
|||||||
|
|
||||||
# Testing for a release
|
# Testing for a release
|
||||||
#
|
#
|
||||||
releasetest: srctree-check has_tclsh85
|
releasetest: srctree-check has_tclsh85 verify-source
|
||||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
|
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
|
||||||
|
|
||||||
# Minimal testing that runs in less than 3 minutes
|
# Minimal testing that runs in less than 3 minutes
|
||||||
@@ -1566,7 +1573,12 @@ lib_install: libsqlite3.la
|
|||||||
$(INSTALL) -d $(DESTDIR)$(libdir)
|
$(INSTALL) -d $(DESTDIR)$(libdir)
|
||||||
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
|
||||||
|
|
||||||
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
|
# Use $(tcl_install_$(HAVE_TCL)) to resolve to either tcl_install or
|
||||||
|
# an empty value.
|
||||||
|
tcl_install_0 =
|
||||||
|
tcl_install_1 = tcl_install
|
||||||
|
|
||||||
|
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc $(tcl_install_$(HAVE_TCL))
|
||||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||||
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
|
||||||
$(INSTALL) -d $(DESTDIR)$(includedir)
|
$(INSTALL) -d $(DESTDIR)$(includedir)
|
||||||
@@ -1608,43 +1620,40 @@ tclextension-uninstall:
|
|||||||
tclextension-list:
|
tclextension-list:
|
||||||
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info
|
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
# Remove build products sufficient so that subsequent makes will recompile
|
||||||
rm -f sqlite3.h opcodes.*
|
# everything from scratch. Do not remove:
|
||||||
rm -rf .libs .deps
|
#
|
||||||
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
|
# * test results and test logs
|
||||||
rm -f mkkeywordhash$(BEXE) keywordhash.h
|
# * output from ./configure
|
||||||
rm -f mksourceid$(BEXE)
|
#
|
||||||
rm -f *.da *.bb *.bbg gmon.out
|
tidy:
|
||||||
rm -rf tsrc .target_source
|
rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
|
||||||
rm -f tclsqlite3$(TEXE)
|
rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h
|
||||||
rm -f testfixture$(TEXE) test.db
|
rm -rf .libs .deps tsrc .target_source
|
||||||
|
rm -f lemon$(BEXE) sqlite*.tar.gz
|
||||||
|
rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE)
|
||||||
|
rm -f parse.* fts5parse.*
|
||||||
|
rm -f tclsqlite3$(TEXE) $(TESTPROGS)
|
||||||
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
|
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
|
||||||
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
||||||
rm -f wordcount$(TEXE) changeset$(TEXE)
|
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
|
||||||
rm -f version-info$(TEXT)
|
rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl
|
||||||
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
|
rm -f sqlite3_analyzer$(TEXE)
|
||||||
rm -f sqlite3.c
|
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
|
||||||
rm -f sqlite3rc.h
|
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
|
||||||
rm -f shell.c sqlite3ext.h
|
rm -f threadtest5$(TEXE)
|
||||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
rm -f src-verify has_tclsh*
|
||||||
rm -f sqlite-*-output.vsix
|
|
||||||
rm -f mptester mptester.exe
|
|
||||||
rm -f rbu rbu.exe
|
|
||||||
rm -f srcck1 srcck1.exe
|
|
||||||
rm -f fuzzershell fuzzershell.exe
|
|
||||||
rm -f fuzzcheck fuzzcheck.exe
|
|
||||||
rm -f sqldiff sqldiff.exe
|
|
||||||
rm -f dbhash dbhash.exe
|
|
||||||
rm -f fts5.* fts5parse.*
|
|
||||||
rm -f threadtest5
|
|
||||||
rm -f src-verify
|
|
||||||
rm -f custom.rws
|
|
||||||
rm -f has_tclsh84 has_tclsh85
|
|
||||||
|
|
||||||
|
# Removes build products and test logs. Retains ./configure outputs.
|
||||||
|
#
|
||||||
|
clean: tidy
|
||||||
|
rm -rf omittest* testrunner* testdir*
|
||||||
|
|
||||||
|
# Clean up everything. No exceptions.
|
||||||
|
#
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \
|
rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL)
|
||||||
$(TESTPROGS)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Windows section
|
# Windows section
|
||||||
|
@@ -938,7 +938,7 @@ TCLSUFFIX =
|
|||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFNDEF TCLDIR
|
!IFNDEF TCLDIR
|
||||||
TCLDIR = $(TOP)\compat\tcl
|
TCLDIR = C:\Tcl
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFNDEF TCLINCDIR
|
!IFNDEF TCLINCDIR
|
||||||
@@ -1768,6 +1768,7 @@ FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.c
|
|||||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
|
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
|
||||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
|
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
|
||||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
|
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
|
||||||
|
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\percentile.c
|
||||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
|
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
|
||||||
|
|
||||||
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
||||||
@@ -2314,6 +2315,7 @@ SHELL_DEP = \
|
|||||||
$(TOP)\ext\misc\ieee754.c \
|
$(TOP)\ext\misc\ieee754.c \
|
||||||
$(TOP)\ext\misc\memtrace.c \
|
$(TOP)\ext\misc\memtrace.c \
|
||||||
$(TOP)\ext\misc\pcachetrace.c \
|
$(TOP)\ext\misc\pcachetrace.c \
|
||||||
|
$(TOP)\ext\misc\percentile.c \
|
||||||
$(TOP)\ext\misc\regexp.c \
|
$(TOP)\ext\misc\regexp.c \
|
||||||
$(TOP)\ext\misc\series.c \
|
$(TOP)\ext\misc\series.c \
|
||||||
$(TOP)\ext\misc\shathree.c \
|
$(TOP)\ext\misc\shathree.c \
|
||||||
|
70
README.md
70
README.md
@@ -73,23 +73,26 @@ archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
|
|||||||
then click on the "Tarball" or "ZIP Archive" links on the information
|
then click on the "Tarball" or "ZIP Archive" links on the information
|
||||||
page.
|
page.
|
||||||
|
|
||||||
To access sources directly using Fossil, first install Fossil version 2.0 or later.
|
To access sources directly using [Fossil](https://fossil-scm.org/home),
|
||||||
Source tarballs and precompiled binaries available
|
first install Fossil version 2.0 or later.
|
||||||
[here](https://www.fossil-scm.org/home/uv/download.html). Fossil is
|
Source tarballs and precompiled binaries available at
|
||||||
|
<https://fossil-scm.org/home/uv/download.html>. Fossil is
|
||||||
a stand-alone program. To install, simply download or build the single
|
a stand-alone program. To install, simply download or build the single
|
||||||
executable file and put that file someplace on your $PATH.
|
executable file and put that file someplace on your $PATH.
|
||||||
Then run commands like this:
|
Then run commands like this:
|
||||||
|
|
||||||
mkdir -p ~/sqlite ~/Fossils
|
mkdir -p ~/sqlite
|
||||||
cd ~/sqlite
|
cd ~/sqlite
|
||||||
fossil clone https://www.sqlite.org/src ~/Fossils/sqlite.fossil
|
fossil open https://sqlite.org/src
|
||||||
fossil open ~/Fossils/sqlite.fossil
|
|
||||||
|
|
||||||
After setting up a repository using the steps above, you can do
|
The "fossil open" command will take two or three minutes. Afterwards,
|
||||||
bandwidth-efficient updates to the latest version using:
|
you can do fast, bandwidth-efficient updates to the whatever versions
|
||||||
|
of SQLite you like. Some examples:
|
||||||
|
|
||||||
fossil update trunk ;# latest trunk check-in
|
fossil update trunk ;# latest trunk check-in
|
||||||
fossil update release ;# latest official release
|
fossil update release ;# latest official release
|
||||||
|
fossil update trunk:2024-01-01 ;# First trunk check-in after 2024-01-01
|
||||||
|
fossil update version-3.39.0 ;# Version 3.39.0
|
||||||
|
|
||||||
Or type "fossil ui" to get a web-based user interface.
|
Or type "fossil ui" to get a web-based user interface.
|
||||||
|
|
||||||
@@ -103,17 +106,19 @@ script found at the root of the source tree. Then run "make".
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
|
apt install gcc make tcl-dev ;# Make sure you have all the necessary build tools
|
||||||
mkdir bld ;# Build will occur in a sibling directory
|
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
|
||||||
cd bld ;# Change to the build directory
|
mkdir bld ;# Build will occur in a sibling directory
|
||||||
../sqlite/configure ;# Run the configure script
|
cd bld ;# Change to the build directory
|
||||||
make sqlite3 ;# Builds the "sqlite3" command-line tool
|
../sqlite/configure ;# Run the configure script
|
||||||
make sqlite3.c ;# Build the "amalgamation" source file
|
make sqlite3 ;# Builds the "sqlite3" command-line tool
|
||||||
make devtest ;# Run development tests (requires tcl-dev)
|
make sqlite3.c ;# Build the "amalgamation" source file
|
||||||
make releasetest ;# Run full release tests (requires tcl-dev)
|
make sqldiff ;# Builds the "sqldiff" command-line tool
|
||||||
make sqldiff ;# Builds the "sqldiff" command-line tool
|
# Makefile targets below this point require tcl-dev
|
||||||
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool (requires tcl-dev)
|
make tclextension-install ;# Build and install the SQLite TCL extension
|
||||||
make tclextension-install ;# Build and install the SQLite TCL extension
|
make devtest ;# Run development tests
|
||||||
|
make releasetest ;# Run full release tests
|
||||||
|
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool
|
||||||
|
|
||||||
See the makefile for additional targets. For debugging builds, the
|
See the makefile for additional targets. For debugging builds, the
|
||||||
core developers typically run "configure" with options like this:
|
core developers typically run "configure" with options like this:
|
||||||
@@ -124,9 +129,12 @@ For release builds, the core developers usually do:
|
|||||||
|
|
||||||
../sqlite/configure --enable-all
|
../sqlite/configure --enable-all
|
||||||
|
|
||||||
Almost all makefile targets require a "tclsh" TCL interpreter
|
Almost all makefile targets require a "tclsh" TCL interpreter version 8.6 or
|
||||||
version 8.6 or later. The targets marked with "(requires tcl-dev)" also require
|
later. The "tclextension-install" target and the test targets that follow
|
||||||
the TCL development libraries.
|
all require TCL development libraries too. ("apt install tcl-dev"). It is
|
||||||
|
helpful, but is not required, to install the SQLite TCL extension (the
|
||||||
|
"tclextension-install" target) prior to running tests. The "releasetest"
|
||||||
|
target has additional requiremenst, such as "valgrind".
|
||||||
|
|
||||||
On "make" command-lines, one can add "OPTIONS=..." to specify additional
|
On "make" command-lines, one can add "OPTIONS=..." to specify additional
|
||||||
compile-time options over and above those set by ./configure. For example,
|
compile-time options over and above those set by ./configure. For example,
|
||||||
@@ -143,7 +151,7 @@ show what changes are needed.
|
|||||||
|
|
||||||
## Compiling for Windows Using MSVC
|
## Compiling for Windows Using MSVC
|
||||||
|
|
||||||
On Windows, all applicable build products can be compiled with MSVC.
|
On Windows, everything can be compiled with MSVC.
|
||||||
You will also need a working installation of TCL.
|
You will also need a working installation of TCL.
|
||||||
See the [compile-for-windows.md](doc/compile-for-windows.md) document for
|
See the [compile-for-windows.md](doc/compile-for-windows.md) document for
|
||||||
additional information about how to install MSVC and TCL and configure your
|
additional information about how to install MSVC and TCL and configure your
|
||||||
@@ -157,15 +165,21 @@ TCL library, using a command like this:
|
|||||||
SQLite uses "tclsh.exe" as part of the build process, and so that
|
SQLite uses "tclsh.exe" as part of the build process, and so that
|
||||||
program will need to be somewhere on your %PATH%. SQLite itself
|
program will need to be somewhere on your %PATH%. SQLite itself
|
||||||
does not contain any TCL code, but it does use TCL to help with the
|
does not contain any TCL code, but it does use TCL to help with the
|
||||||
build process and to run tests.
|
build process and to run tests. You may need to install TCL development
|
||||||
|
libraries in order to successfully complete some makefile targets.
|
||||||
|
It is helpful, but is not required, to install the SQLite TCL extension
|
||||||
|
(the "tclextension-install" target) prior to running tests.
|
||||||
|
|
||||||
Build using Makefile.msc. Example:
|
Build using Makefile.msc. Example:
|
||||||
|
|
||||||
nmake /f Makefile.msc sqlite3.exe
|
nmake /f Makefile.msc sqlite3.exe
|
||||||
nmake /f Makefile.msc sqlite3.c
|
nmake /f Makefile.msc sqlite3.c
|
||||||
|
nmake /f Makefile.msc sqldiff.exe
|
||||||
|
# Makefile targets below this point require TCL development libraries
|
||||||
|
nmake /f Makefile.msc tclextension-install
|
||||||
nmake /f Makefile.msc devtest
|
nmake /f Makefile.msc devtest
|
||||||
nmake /f Makefile.msc releasetest
|
nmake /f Makefile.msc releasetest
|
||||||
nmake /f Makefile.msc tclextension-install
|
nmake /f Makefile.msc sqlite3_analyzer.exe
|
||||||
|
|
||||||
There are many other makefile targets. See comments in Makefile.msc for
|
There are many other makefile targets. See comments in Makefile.msc for
|
||||||
details.
|
details.
|
||||||
@@ -372,7 +386,7 @@ implementation. It will not be the easiest library in the world to hack.
|
|||||||
* **VERSION**, **manifest**, and **manifest.uuid** - These files define
|
* **VERSION**, **manifest**, and **manifest.uuid** - These files define
|
||||||
the current SQLite version number. The "VERSION" file is human generated,
|
the current SQLite version number. The "VERSION" file is human generated,
|
||||||
but the "manifest" and "manifest.uuid" files are automatically generated
|
but the "manifest" and "manifest.uuid" files are automatically generated
|
||||||
by the [Fossil version control system](https://fossil-scm/).
|
by the [Fossil version control system](https://fossil-scm.org/).
|
||||||
|
|
||||||
There are many other source files. Each has a succinct header comment that
|
There are many other source files. Each has a succinct header comment that
|
||||||
describes its purpose and role within the larger system.
|
describes its purpose and role within the larger system.
|
||||||
|
@@ -57,11 +57,22 @@ canonical source on a new Windows 11 PC, as of 2023-11-01:
|
|||||||
<ul>
|
<ul>
|
||||||
<li> `nmake /f makefile.msc`
|
<li> `nmake /f makefile.msc`
|
||||||
<li> `nmake /f makefile.msc sqlite3.c`
|
<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 tclextension-install`
|
||||||
<li> `nmake /f makefile.msc devtest`
|
<li> `nmake /f makefile.msc devtest`
|
||||||
<li> `nmake /f makefile.msc releasetest`
|
<li> `nmake /f makefile.msc releasetest`
|
||||||
<li> `nmake /f makefile.msc sqlite3.exe`
|
<li> `nmake /f makefile.msc sqlite3_analyzer.exe`
|
||||||
</ul>
|
</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"
|
7. For a debugging build of the CLI, where the ".treetrace" and ".wheretrace"
|
||||||
commands work, add the DEBUG=3 argument to nmake. Like this:
|
commands work, add the DEBUG=3 argument to nmake. Like this:
|
||||||
<ul>
|
<ul>
|
||||||
|
@@ -655,6 +655,10 @@ cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* An fgets() equivalent, using Win32 file API for actual input.
|
||||||
|
** Input ends when given buffer is filled or a newline is read.
|
||||||
|
** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
|
||||||
|
*/
|
||||||
SQLITE_INTERNAL_LINKAGE char *
|
SQLITE_INTERNAL_LINKAGE char *
|
||||||
cfGets(char *cBuf, int n, FILE *pf){
|
cfGets(char *cBuf, int n, FILE *pf){
|
||||||
int nci = 0;
|
int nci = 0;
|
||||||
@@ -665,7 +669,10 @@ cfGets(char *cBuf, int n, FILE *pf){
|
|||||||
while( nci < n-1 ){
|
while( nci < n-1 ){
|
||||||
DWORD nr;
|
DWORD nr;
|
||||||
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
|
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
|
||||||
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
|
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
|
||||||
|
nci += nr;
|
||||||
|
if( cBuf[nci-nr]=='\n' ) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( nci < n ) cBuf[nci] = 0;
|
if( nci < n ) cBuf[nci] = 0;
|
||||||
return (nci>0)? cBuf : 0;
|
return (nci>0)? cBuf : 0;
|
||||||
|
@@ -2185,7 +2185,7 @@ static void fts5SegIterNext_None(
|
|||||||
|
|
||||||
if( iOff<pIter->iEndofDoclist ){
|
if( iOff<pIter->iEndofDoclist ){
|
||||||
/* Next entry is on the current page */
|
/* Next entry is on the current page */
|
||||||
i64 iDelta;
|
u64 iDelta;
|
||||||
iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
|
iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
|
||||||
pIter->iLeafOffset = iOff;
|
pIter->iLeafOffset = iOff;
|
||||||
pIter->iRowid += iDelta;
|
pIter->iRowid += iDelta;
|
||||||
|
56
ext/fts5/test/fts5integrity2.test
Normal file
56
ext/fts5/test/fts5integrity2.test
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 2024 September 3
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# This file contains tests focused on the integrity-check procedure.
|
||||||
|
#
|
||||||
|
|
||||||
|
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||||
|
set testprefix fts5integrity2
|
||||||
|
|
||||||
|
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||||
|
ifcapable !fts5 {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 2.0 {
|
||||||
|
CREATE VIRTUAL TABLE t2 USING fts5(a, detail='none');
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t2(rowid, a) VALUES(-1, 'hello world');
|
||||||
|
INSERT INTO t2(rowid, a) VALUES(9223372036854775807, 'hello world');
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 2.1 {
|
||||||
|
SELECT rowid FROM t2('hello AND world');
|
||||||
|
} {-1 9223372036854775807}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
do_execsql_test 2.0 {
|
||||||
|
CREATE VIRTUAL TABLE t1 USING fts5(a, detail='none');
|
||||||
|
CREATE TABLE r1(r);
|
||||||
|
|
||||||
|
WITH c(x) AS (VALUES(1) UNION SELECT x<<1 FROM c)
|
||||||
|
INSERT INTO r1(r) SELECT -1-x FROM c;
|
||||||
|
|
||||||
|
INSERT INTO t1(rowid, a) SELECT r, 'abc' FROM r1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 2.1 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
do_execsql_test 2.2 {
|
||||||
|
SELECT rowid FROM t1('abc') ORDER BY +rowid;
|
||||||
|
} [db eval {SELECT r FROM r1 ORDER BY r}]
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
@@ -11,7 +11,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
**
|
**
|
||||||
** This file contains code to implement the percentile(Y,P) SQL function
|
** This file contains code to implement the percentile(Y,P) SQL function
|
||||||
** as described below:
|
** and similar as described below:
|
||||||
**
|
**
|
||||||
** (1) The percentile(Y,P) function is an aggregate function taking
|
** (1) The percentile(Y,P) function is an aggregate function taking
|
||||||
** exactly two arguments.
|
** exactly two arguments.
|
||||||
@@ -60,31 +60,105 @@
|
|||||||
**
|
**
|
||||||
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
|
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
|
||||||
**
|
**
|
||||||
** (14) A separate percentile_cond(Y,X) function is the equivalent of
|
** (14) A separate percentile_cont(Y,P) function is equivalent to
|
||||||
** percentile(Y,X*100.0).
|
** percentile(Y,P/100.0). In other words, the fraction value in
|
||||||
|
** the second argument is in the range of 0 to 1 instead of 0 to 100.
|
||||||
|
**
|
||||||
|
** (15) A separate percentile_disc(Y,P) function is like
|
||||||
|
** percentile_cont(Y,P) except that instead of returning the weighted
|
||||||
|
** average of the nearest two input values, it returns the next lower
|
||||||
|
** value. So the percentile_disc(Y,P) will always return a value
|
||||||
|
** that was one of the inputs.
|
||||||
|
**
|
||||||
|
** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and
|
||||||
|
** percentile_disc(Y,P) can be used as window functions.
|
||||||
|
**
|
||||||
|
** Differences from standard SQL:
|
||||||
|
**
|
||||||
|
** * The percentile_cont(X,P) function is equivalent to the following in
|
||||||
|
** standard SQL:
|
||||||
|
**
|
||||||
|
** (percentile_cont(P) WITHIN GROUP (ORDER BY X))
|
||||||
|
**
|
||||||
|
** The SQLite syntax is much more compact. The standard SQL syntax
|
||||||
|
** is also supported if SQLite is compiled with the
|
||||||
|
** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option.
|
||||||
|
**
|
||||||
|
** * No median(X) function exists in the SQL standard. App developers
|
||||||
|
** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)".
|
||||||
|
**
|
||||||
|
** * No percentile(Y,P) function exists in the SQL standard. Instead of
|
||||||
|
** percential(Y,P), developers must write this:
|
||||||
|
** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that
|
||||||
|
** the fraction parameter to percentile() goes from 0 to 100 whereas
|
||||||
|
** the fraction parameter in SQL standard percentile_cont() goes from
|
||||||
|
** 0 to 1.
|
||||||
|
**
|
||||||
|
** Implementation notes as of 2024-08-31:
|
||||||
|
**
|
||||||
|
** * The regular aggregate-function versions of these routines work
|
||||||
|
** by accumulating all values in an array of doubles, then sorting
|
||||||
|
** that array using quicksort before computing the answer. Thus
|
||||||
|
** the runtime is O(NlogN) where N is the number of rows of input.
|
||||||
|
**
|
||||||
|
** * For the window-function versions of these routines, the array of
|
||||||
|
** inputs is sorted as soon as the first value is computed. Thereafter,
|
||||||
|
** the array is kept in sorted order using an insert-sort. This
|
||||||
|
** results in O(N*K) performance where K is the size of the window.
|
||||||
|
** One can imagine alternative implementations that give O(N*logN*logK)
|
||||||
|
** performance, but they require more complex logic and data structures.
|
||||||
|
** The developers have elected to keep the asymptotically slower
|
||||||
|
** algorithm for now, for simplicity, under the theory that window
|
||||||
|
** functions are seldom used and when they are, the window size K is
|
||||||
|
** often small. The developers might revisit that decision later,
|
||||||
|
** should the need arise.
|
||||||
*/
|
*/
|
||||||
#include "sqlite3ext.h"
|
#if defined(SQLITE3_H)
|
||||||
SQLITE_EXTENSION_INIT1
|
/* no-op */
|
||||||
|
#elif defined(SQLITE_STATIC_PERCENTILE)
|
||||||
|
# include "sqlite3.h"
|
||||||
|
#else
|
||||||
|
# include "sqlite3ext.h"
|
||||||
|
SQLITE_EXTENSION_INIT1
|
||||||
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* The following object is the session context for a single percentile()
|
/* The following object is the group context for a single percentile()
|
||||||
** function. We have to remember all input Y values until the very end.
|
** aggregate. Remember all input Y values until the very end.
|
||||||
** Those values are accumulated in the Percentile.a[] array.
|
** Those values are accumulated in the Percentile.a[] array.
|
||||||
*/
|
*/
|
||||||
typedef struct Percentile Percentile;
|
typedef struct Percentile Percentile;
|
||||||
struct Percentile {
|
struct Percentile {
|
||||||
unsigned nAlloc; /* Number of slots allocated for a[] */
|
unsigned nAlloc; /* Number of slots allocated for a[] */
|
||||||
unsigned nUsed; /* Number of slots actually used in a[] */
|
unsigned nUsed; /* Number of slots actually used in a[] */
|
||||||
double rPct; /* 1.0 more than the value for P */
|
char bSorted; /* True if a[] is already in sorted order */
|
||||||
|
char bKeepSorted; /* True if advantageous to keep a[] sorted */
|
||||||
|
char bPctValid; /* True if rPct is valid */
|
||||||
|
double rPct; /* Fraction. 0.0 to 1.0 */
|
||||||
double *a; /* Array of Y values */
|
double *a; /* Array of Y values */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Details of each function in the percentile family */
|
||||||
|
typedef struct PercentileFunc PercentileFunc;
|
||||||
|
struct PercentileFunc {
|
||||||
|
const char *zName; /* Function name */
|
||||||
|
char nArg; /* Number of arguments */
|
||||||
|
char mxFrac; /* Maximum value of the "fraction" input */
|
||||||
|
char bDiscrete; /* True for percentile_disc() */
|
||||||
|
};
|
||||||
|
static const PercentileFunc aPercentFunc[] = {
|
||||||
|
{ "median", 1, 1, 0 },
|
||||||
|
{ "percentile", 2, 100, 0 },
|
||||||
|
{ "percentile_cont", 2, 1, 0 },
|
||||||
|
{ "percentile_disc", 2, 1, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return TRUE if the input floating-point number is an infinity.
|
** Return TRUE if the input floating-point number is an infinity.
|
||||||
*/
|
*/
|
||||||
static int isInfinity(double r){
|
static int percentIsInfinity(double r){
|
||||||
sqlite3_uint64 u;
|
sqlite3_uint64 u;
|
||||||
assert( sizeof(u)==sizeof(r) );
|
assert( sizeof(u)==sizeof(r) );
|
||||||
memcpy(&u, &r, sizeof(u));
|
memcpy(&u, &r, sizeof(u));
|
||||||
@@ -92,13 +166,64 @@ static int isInfinity(double r){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return TRUE if two doubles differ by 0.001 or less
|
** Return TRUE if two doubles differ by 0.001 or less.
|
||||||
*/
|
*/
|
||||||
static int sameValue(double a, double b){
|
static int percentSameValue(double a, double b){
|
||||||
a -= b;
|
a -= b;
|
||||||
return a>=-0.001 && a<=0.001;
|
return a>=-0.001 && a<=0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Search p (which must have p->bSorted) looking for an entry with
|
||||||
|
** value y. Return the index of that entry.
|
||||||
|
**
|
||||||
|
** If bExact is true, return -1 if the entry is not found.
|
||||||
|
**
|
||||||
|
** If bExact is false, return the index at which a new entry with
|
||||||
|
** value y should be insert in order to keep the values in sorted
|
||||||
|
** order. The smallest return value in this case will be 0, and
|
||||||
|
** the largest return value will be p->nUsed.
|
||||||
|
*/
|
||||||
|
static int percentBinarySearch(Percentile *p, double y, int bExact){
|
||||||
|
int iFirst = 0; /* First element of search range */
|
||||||
|
int iLast = p->nUsed - 1; /* Last element of search range */
|
||||||
|
while( iLast>=iFirst ){
|
||||||
|
int iMid = (iFirst+iLast)/2;
|
||||||
|
double x = p->a[iMid];
|
||||||
|
if( x<y ){
|
||||||
|
iFirst = iMid + 1;
|
||||||
|
}else if( x>y ){
|
||||||
|
iLast = iMid - 1;
|
||||||
|
}else{
|
||||||
|
return iMid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( bExact ) return -1;
|
||||||
|
return iFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate an error for a percentile function.
|
||||||
|
**
|
||||||
|
** The error format string must have exactly one occurrance of "%%s()"
|
||||||
|
** (with two '%' characters). That substring will be replaced by the name
|
||||||
|
** of the function.
|
||||||
|
*/
|
||||||
|
static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
|
||||||
|
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
|
||||||
|
char *zMsg1;
|
||||||
|
char *zMsg2;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, zFormat);
|
||||||
|
zMsg1 = sqlite3_vmprintf(zFormat, ap);
|
||||||
|
va_end(ap);
|
||||||
|
zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0;
|
||||||
|
sqlite3_result_error(pCtx, zMsg2, -1);
|
||||||
|
sqlite3_free(zMsg1);
|
||||||
|
sqlite3_free(zMsg2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The "step" function for percentile(Y,P) is called once for each
|
** The "step" function for percentile(Y,P) is called once for each
|
||||||
** input row.
|
** input row.
|
||||||
@@ -112,28 +237,20 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
|||||||
|
|
||||||
if( argc==1 ){
|
if( argc==1 ){
|
||||||
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
|
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
|
||||||
rPct = 50.0;
|
rPct = 0.5;
|
||||||
}else if( sqlite3_user_data(pCtx)==0 ){
|
|
||||||
/* Requirement 3: P must be a number between 0 and 100 */
|
|
||||||
eType = sqlite3_value_numeric_type(argv[1]);
|
|
||||||
rPct = sqlite3_value_double(argv[1]);
|
|
||||||
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|
|
||||||
|| rPct<0.0 || rPct>100.0 ){
|
|
||||||
sqlite3_result_error(pCtx, "2nd argument to percentile() is not "
|
|
||||||
"a number between 0.0 and 100.0", -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
/* Requirement 3: P must be a number between 0 and 1 */
|
/* Requirement 3: P must be a number between 0 and 100 */
|
||||||
|
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
|
||||||
eType = sqlite3_value_numeric_type(argv[1]);
|
eType = sqlite3_value_numeric_type(argv[1]);
|
||||||
rPct = sqlite3_value_double(argv[1]);
|
rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac;
|
||||||
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|
||||||
|| rPct<0.0 || rPct>1.0 ){
|
|| rPct<0.0 || rPct>1.0
|
||||||
sqlite3_result_error(pCtx, "2nd argument to percentile_cont() is not "
|
){
|
||||||
"a number between 0.0 and 1.0", -1);
|
percentError(pCtx, "the fraction argument to %%s()"
|
||||||
|
" is not between 0.0 and %.1f",
|
||||||
|
(double)pFunc->mxFrac);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rPct *= 100.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the session context. */
|
/* Allocate the session context. */
|
||||||
@@ -142,11 +259,12 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
|||||||
|
|
||||||
/* Remember the P value. Throw an error if the P value is different
|
/* Remember the P value. Throw an error if the P value is different
|
||||||
** from any prior row, per Requirement (2). */
|
** from any prior row, per Requirement (2). */
|
||||||
if( p->rPct==0.0 ){
|
if( !p->bPctValid ){
|
||||||
p->rPct = rPct+1.0;
|
p->rPct = rPct;
|
||||||
}else if( !sameValue(p->rPct,rPct+1.0) ){
|
p->bPctValid = 1;
|
||||||
sqlite3_result_error(pCtx, "2nd argument to percentile() is not the "
|
}else if( !percentSameValue(p->rPct,rPct) ){
|
||||||
"same for all input rows", -1);
|
percentError(pCtx, "the fraction argument to %%s()"
|
||||||
|
" is not the same for all input rows");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,15 +275,14 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
|||||||
/* If not NULL, then Y must be numeric. Otherwise throw an error.
|
/* If not NULL, then Y must be numeric. Otherwise throw an error.
|
||||||
** Requirement 4 */
|
** Requirement 4 */
|
||||||
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
|
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
|
||||||
sqlite3_result_error(pCtx, "1st argument to percentile() is not "
|
percentError(pCtx, "input to %%s() is not numeric");
|
||||||
"numeric", -1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Throw an error if the Y value is infinity or NaN */
|
/* Throw an error if the Y value is infinity or NaN */
|
||||||
y = sqlite3_value_double(argv[0]);
|
y = sqlite3_value_double(argv[0]);
|
||||||
if( isInfinity(y) ){
|
if( percentIsInfinity(y) ){
|
||||||
sqlite3_result_error(pCtx, "Inf input to percentile()", -1);
|
percentError(pCtx, "Inf input to %%s()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,49 +299,79 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
|||||||
p->nAlloc = n;
|
p->nAlloc = n;
|
||||||
p->a = a;
|
p->a = a;
|
||||||
}
|
}
|
||||||
p->a[p->nUsed++] = y;
|
if( p->nUsed==0 ){
|
||||||
|
p->a[p->nUsed++] = y;
|
||||||
|
p->bSorted = 1;
|
||||||
|
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
|
||||||
|
p->a[p->nUsed++] = y;
|
||||||
|
}else if( p->bKeepSorted ){
|
||||||
|
int i;
|
||||||
|
i = percentBinarySearch(p, y, 0);
|
||||||
|
if( i<(int)p->nUsed ){
|
||||||
|
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
|
||||||
|
}
|
||||||
|
p->a[i] = y;
|
||||||
|
p->nUsed++;
|
||||||
|
}else{
|
||||||
|
p->a[p->nUsed++] = y;
|
||||||
|
p->bSorted = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Sort an array of doubles.
|
** Interchange two doubles.
|
||||||
*/
|
*/
|
||||||
static void sortDoubles(double *a, int n){
|
#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
|
||||||
int iLt; /* Entries with index less than iLt are less than rPivot */
|
|
||||||
int iGt; /* Entries with index iGt or more are greater than rPivot */
|
/*
|
||||||
|
** Sort an array of doubles.
|
||||||
|
**
|
||||||
|
** Algorithm: quicksort
|
||||||
|
**
|
||||||
|
** This is implemented separately rather than using the qsort() routine
|
||||||
|
** from the standard library because:
|
||||||
|
**
|
||||||
|
** (1) To avoid a dependency on qsort()
|
||||||
|
** (2) To avoid the function call to the comparison routine for each
|
||||||
|
** comparison.
|
||||||
|
*/
|
||||||
|
static void percentSort(double *a, unsigned int n){
|
||||||
|
int iLt; /* Entries before a[iLt] are less than rPivot */
|
||||||
|
int iGt; /* Entries at or after a[iGt] are greater than rPivot */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
double rPivot; /* The pivot value */
|
double rPivot; /* The pivot value */
|
||||||
double rTmp; /* Temporary used to swap two values */
|
|
||||||
|
|
||||||
if( n<2 ) return;
|
assert( n>=2 );
|
||||||
if( n>5 ){
|
if( a[0]>a[n-1] ){
|
||||||
rPivot = (a[0] + a[n/2] + a[n-1])/3.0;
|
SWAP_DOUBLE(a[0],a[n-1])
|
||||||
}else{
|
|
||||||
rPivot = a[n/2];
|
|
||||||
}
|
}
|
||||||
iLt = i = 0;
|
if( n==2 ) return;
|
||||||
iGt = n;
|
iGt = n-1;
|
||||||
while( i<iGt ){
|
i = n/2;
|
||||||
|
if( a[0]>a[i] ){
|
||||||
|
SWAP_DOUBLE(a[0],a[i])
|
||||||
|
}else if( a[i]>a[iGt] ){
|
||||||
|
SWAP_DOUBLE(a[i],a[iGt])
|
||||||
|
}
|
||||||
|
if( n==3 ) return;
|
||||||
|
rPivot = a[i];
|
||||||
|
iLt = i = 1;
|
||||||
|
do{
|
||||||
if( a[i]<rPivot ){
|
if( a[i]<rPivot ){
|
||||||
if( i>iLt ){
|
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
|
||||||
rTmp = a[i];
|
|
||||||
a[i] = a[iLt];
|
|
||||||
a[iLt] = rTmp;
|
|
||||||
}
|
|
||||||
iLt++;
|
iLt++;
|
||||||
i++;
|
i++;
|
||||||
}else if( a[i]>rPivot ){
|
}else if( a[i]>rPivot ){
|
||||||
do{
|
do{
|
||||||
iGt--;
|
iGt--;
|
||||||
}while( iGt>i && a[iGt]>rPivot );
|
}while( iGt>i && a[iGt]>rPivot );
|
||||||
rTmp = a[i];
|
SWAP_DOUBLE(a[i],a[iGt])
|
||||||
a[i] = a[iGt];
|
|
||||||
a[iGt] = rTmp;
|
|
||||||
}else{
|
}else{
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}while( i<iGt );
|
||||||
if( iLt>=2 ) sortDoubles(a, iLt);
|
if( iLt>=2 ) percentSort(a, iLt);
|
||||||
if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt);
|
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
|
||||||
|
|
||||||
/* Uncomment for testing */
|
/* Uncomment for testing */
|
||||||
#if 0
|
#if 0
|
||||||
@@ -234,12 +381,61 @@ static void sortDoubles(double *a, int n){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Called to compute the final output of percentile() and to clean
|
** The "inverse" function for percentile(Y,P) is called to remove a
|
||||||
** up all allocated memory.
|
** row that was previously inserted by "step".
|
||||||
*/
|
*/
|
||||||
static void percentFinal(sqlite3_context *pCtx){
|
static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
|
||||||
Percentile *p;
|
Percentile *p;
|
||||||
|
int eType;
|
||||||
|
double y;
|
||||||
|
int i;
|
||||||
|
assert( argc==2 || argc==1 );
|
||||||
|
|
||||||
|
/* Allocate the session context. */
|
||||||
|
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
|
assert( p!=0 );
|
||||||
|
|
||||||
|
/* Ignore rows for which Y is NULL */
|
||||||
|
eType = sqlite3_value_type(argv[0]);
|
||||||
|
if( eType==SQLITE_NULL ) return;
|
||||||
|
|
||||||
|
/* If not NULL, then Y must be numeric. Otherwise throw an error.
|
||||||
|
** Requirement 4 */
|
||||||
|
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore the Y value if it is infinity or NaN */
|
||||||
|
y = sqlite3_value_double(argv[0]);
|
||||||
|
if( percentIsInfinity(y) ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( p->bSorted==0 ){
|
||||||
|
assert( p->nUsed>1 );
|
||||||
|
percentSort(p->a, p->nUsed);
|
||||||
|
p->bSorted = 1;
|
||||||
|
}
|
||||||
|
p->bKeepSorted = 1;
|
||||||
|
|
||||||
|
/* Find and remove the row */
|
||||||
|
i = percentBinarySearch(p, y, 1);
|
||||||
|
if( i>=0 ){
|
||||||
|
p->nUsed--;
|
||||||
|
if( i<(int)p->nUsed ){
|
||||||
|
memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Compute the final output of percentile(). Clean up all allocated
|
||||||
|
** memory if and only if bIsFinal is true.
|
||||||
|
*/
|
||||||
|
static void percentCompute(sqlite3_context *pCtx, int bIsFinal){
|
||||||
|
Percentile *p;
|
||||||
|
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
|
||||||
unsigned i1, i2;
|
unsigned i1, i2;
|
||||||
double v1, v2;
|
double v1, v2;
|
||||||
double ix, vx;
|
double ix, vx;
|
||||||
@@ -247,21 +443,38 @@ static void percentFinal(sqlite3_context *pCtx){
|
|||||||
if( p==0 ) return;
|
if( p==0 ) return;
|
||||||
if( p->a==0 ) return;
|
if( p->a==0 ) return;
|
||||||
if( p->nUsed ){
|
if( p->nUsed ){
|
||||||
sortDoubles(p->a, p->nUsed);
|
if( p->bSorted==0 ){
|
||||||
ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
|
assert( p->nUsed>1 );
|
||||||
|
percentSort(p->a, p->nUsed);
|
||||||
|
p->bSorted = 1;
|
||||||
|
}
|
||||||
|
ix = p->rPct*(p->nUsed-1);
|
||||||
i1 = (unsigned)ix;
|
i1 = (unsigned)ix;
|
||||||
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
|
if( pFunc->bDiscrete ){
|
||||||
v1 = p->a[i1];
|
vx = p->a[i1];
|
||||||
v2 = p->a[i2];
|
}else{
|
||||||
vx = v1 + (v2-v1)*(ix-i1);
|
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
|
||||||
|
v1 = p->a[i1];
|
||||||
|
v2 = p->a[i2];
|
||||||
|
vx = v1 + (v2-v1)*(ix-i1);
|
||||||
|
}
|
||||||
sqlite3_result_double(pCtx, vx);
|
sqlite3_result_double(pCtx, vx);
|
||||||
}
|
}
|
||||||
sqlite3_free(p->a);
|
if( bIsFinal ){
|
||||||
memset(p, 0, sizeof(*p));
|
sqlite3_free(p->a);
|
||||||
|
memset(p, 0, sizeof(*p));
|
||||||
|
}else{
|
||||||
|
p->bKeepSorted = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void percentFinal(sqlite3_context *pCtx){
|
||||||
|
percentCompute(pCtx, 1);
|
||||||
|
}
|
||||||
|
static void percentValue(sqlite3_context *pCtx){
|
||||||
|
percentCompute(pCtx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE)
|
||||||
#ifdef _WIN32
|
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
#endif
|
#endif
|
||||||
int sqlite3_percentile_init(
|
int sqlite3_percentile_init(
|
||||||
@@ -270,20 +483,21 @@ int sqlite3_percentile_init(
|
|||||||
const sqlite3_api_routines *pApi
|
const sqlite3_api_routines *pApi
|
||||||
){
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
unsigned int i;
|
||||||
|
#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
|
||||||
|
(void)pApi; /* Unused parameter */
|
||||||
|
#else
|
||||||
SQLITE_EXTENSION_INIT2(pApi);
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
|
#endif
|
||||||
(void)pzErrMsg; /* Unused parameter */
|
(void)pzErrMsg; /* Unused parameter */
|
||||||
rc = sqlite3_create_function(db, "percentile", 2,
|
for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){
|
||||||
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
|
rc = sqlite3_create_window_function(db,
|
||||||
0, percentStep, percentFinal);
|
aPercentFunc[i].zName,
|
||||||
if( rc==SQLITE_OK ){
|
aPercentFunc[i].nArg,
|
||||||
rc = sqlite3_create_function(db, "median", 1,
|
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1,
|
||||||
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
|
(void*)&aPercentFunc[i],
|
||||||
0, percentStep, percentFinal);
|
percentStep, percentFinal, percentValue, percentInverse, 0);
|
||||||
}
|
if( rc ) break;
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3_create_function(db, "percentile_cont", 2,
|
|
||||||
SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep,
|
|
||||||
0, percentStep, percentFinal);
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -336,6 +336,27 @@ struct RbuFrame {
|
|||||||
u32 iWalFrame;
|
u32 iWalFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef UNUSED_PARAMETER
|
||||||
|
/*
|
||||||
|
** The following macros are used to suppress compiler warnings and to
|
||||||
|
** make it clear to human readers when a function parameter is deliberately
|
||||||
|
** left unused within the body of a function. This usually happens when
|
||||||
|
** a function is called via a function pointer. For example the
|
||||||
|
** implementation of an SQL aggregate step callback may not use the
|
||||||
|
** parameter indicating the number of arguments passed to the aggregate,
|
||||||
|
** if it knows that this is enforced elsewhere.
|
||||||
|
**
|
||||||
|
** When a function parameter is not used at all within the body of a function,
|
||||||
|
** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
|
||||||
|
** However, these macros may also be used to suppress warnings related to
|
||||||
|
** parameters that may or may not be used depending on compilation options.
|
||||||
|
** For example those parameters only used in assert() statements. In these
|
||||||
|
** cases the parameters are named as per the usual conventions.
|
||||||
|
*/
|
||||||
|
#define UNUSED_PARAMETER(x) (void)(x)
|
||||||
|
#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** RBU handle.
|
** RBU handle.
|
||||||
**
|
**
|
||||||
@@ -387,7 +408,7 @@ struct sqlite3rbu {
|
|||||||
int rc; /* Value returned by last rbu_step() call */
|
int rc; /* Value returned by last rbu_step() call */
|
||||||
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
|
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
|
||||||
int nStep; /* Rows processed for current object */
|
int nStep; /* Rows processed for current object */
|
||||||
int nProgress; /* Rows processed for all objects */
|
sqlite3_int64 nProgress; /* Rows processed for all objects */
|
||||||
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
|
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
|
||||||
const char *zVfsName; /* Name of automatically created rbu vfs */
|
const char *zVfsName; /* Name of automatically created rbu vfs */
|
||||||
rbu_file *pTargetFd; /* File handle open on target db */
|
rbu_file *pTargetFd; /* File handle open on target db */
|
||||||
@@ -504,7 +525,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
|
|||||||
v = (v<<6) + c;
|
v = (v<<6) + c;
|
||||||
}
|
}
|
||||||
z--;
|
z--;
|
||||||
*pLen -= z - zStart;
|
*pLen -= (int)(z - zStart);
|
||||||
*pz = (char*)z;
|
*pz = (char*)z;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -689,6 +710,7 @@ static void rbuFossilDeltaFunc(
|
|||||||
char *aOut;
|
char *aOut;
|
||||||
|
|
||||||
assert( argc==2 );
|
assert( argc==2 );
|
||||||
|
UNUSED_PARAMETER(argc);
|
||||||
|
|
||||||
nOrig = sqlite3_value_bytes(argv[0]);
|
nOrig = sqlite3_value_bytes(argv[0]);
|
||||||
aOrig = (const char*)sqlite3_value_blob(argv[0]);
|
aOrig = (const char*)sqlite3_value_blob(argv[0]);
|
||||||
@@ -2268,13 +2290,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
|
|||||||
else if( c==')' ){
|
else if( c==')' ){
|
||||||
nParen--;
|
nParen--;
|
||||||
if( nParen==0 ){
|
if( nParen==0 ){
|
||||||
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
|
int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
|
||||||
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else if( c==',' && nParen==1 ){
|
}else if( c==',' && nParen==1 ){
|
||||||
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
|
int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
|
||||||
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
|
||||||
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
|
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
|
||||||
}else if( c=='"' || c=='\'' || c=='`' ){
|
}else if( c=='"' || c=='\'' || c=='`' ){
|
||||||
@@ -2964,6 +2986,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){
|
|||||||
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
|
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
|
||||||
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
|
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
UNUSED_PARAMETER2(zBase,z);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3548,7 +3572,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
|
|||||||
"(%d, %Q), "
|
"(%d, %Q), "
|
||||||
"(%d, %Q), "
|
"(%d, %Q), "
|
||||||
"(%d, %d), "
|
"(%d, %d), "
|
||||||
"(%d, %d), "
|
"(%d, %lld), "
|
||||||
"(%d, %lld), "
|
"(%d, %lld), "
|
||||||
"(%d, %lld), "
|
"(%d, %lld), "
|
||||||
"(%d, %lld), "
|
"(%d, %lld), "
|
||||||
@@ -3906,6 +3930,7 @@ static void rbuIndexCntFunc(
|
|||||||
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
|
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
|
||||||
|
|
||||||
assert( nVal==1 );
|
assert( nVal==1 );
|
||||||
|
UNUSED_PARAMETER(nVal);
|
||||||
|
|
||||||
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
|
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
|
||||||
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
|
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
|
||||||
@@ -4181,7 +4206,7 @@ sqlite3rbu *sqlite3rbu_vacuum(
|
|||||||
){
|
){
|
||||||
if( zTarget==0 ){ return rbuMisuseError(); }
|
if( zTarget==0 ){ return rbuMisuseError(); }
|
||||||
if( zState ){
|
if( zState ){
|
||||||
int n = strlen(zState);
|
size_t n = strlen(zState);
|
||||||
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
|
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
|
||||||
return rbuMisuseError();
|
return rbuMisuseError();
|
||||||
}
|
}
|
||||||
@@ -4398,6 +4423,7 @@ int sqlite3rbu_savestate(sqlite3rbu *p){
|
|||||||
*/
|
*/
|
||||||
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
|
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
UNUSED_PARAMETER(pArg);
|
||||||
#if defined(_WIN32_WCE)
|
#if defined(_WIN32_WCE)
|
||||||
{
|
{
|
||||||
LPWSTR zWideOld;
|
LPWSTR zWideOld;
|
||||||
@@ -5302,6 +5328,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
|||||||
** No-op.
|
** No-op.
|
||||||
*/
|
*/
|
||||||
static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
|
static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
|
||||||
|
UNUSED_PARAMETER(pVfs);
|
||||||
|
UNUSED_PARAMETER(a);
|
||||||
|
UNUSED_PARAMETER(b);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -383,10 +383,10 @@ static int SQLITE_TCLAPI test_session_cmd(
|
|||||||
{ "rowid", SQLITE_SESSION_OBJCONFIG_ROWID },
|
{ "rowid", SQLITE_SESSION_OBJCONFIG_ROWID },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
size_t sz = sizeof(aOpt[0]);
|
int sz = (int)sizeof(aOpt[0]);
|
||||||
|
|
||||||
int iArg;
|
int iArg;
|
||||||
int iOpt;
|
Tcl_Size iOpt;
|
||||||
if( Tcl_GetIndexFromObjStruct(interp,objv[2],aOpt,sz,"option",0,&iOpt) ){
|
if( Tcl_GetIndexFromObjStruct(interp,objv[2],aOpt,sz,"option",0,&iOpt) ){
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
@@ -803,7 +803,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
|||||||
if( bV2 ){
|
if( bV2 ){
|
||||||
while( objc>1 ){
|
while( objc>1 ){
|
||||||
const char *z1 = Tcl_GetString(objv[1]);
|
const char *z1 = Tcl_GetString(objv[1]);
|
||||||
int n = strlen(z1);
|
int n = (int)strlen(z1);
|
||||||
if( n>3 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
|
if( n>3 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
|
||||||
flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
|
flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
|
||||||
}
|
}
|
||||||
@@ -1119,7 +1119,7 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach(
|
|||||||
|
|
||||||
while( objc>1 ){
|
while( objc>1 ){
|
||||||
char *zOpt = Tcl_GetString(objv[1]);
|
char *zOpt = Tcl_GetString(objv[1]);
|
||||||
int nOpt = strlen(zOpt);
|
int nOpt = (int)strlen(zOpt);
|
||||||
if( zOpt[0]!='-' ) break;
|
if( zOpt[0]!='-' ) break;
|
||||||
if( nOpt<=7 && 0==sqlite3_strnicmp(zOpt, "-invert", nOpt) ){
|
if( nOpt<=7 && 0==sqlite3_strnicmp(zOpt, "-invert", nOpt) ){
|
||||||
isInvert = 1;
|
isInvert = 1;
|
||||||
|
59
main.mk
59
main.mk
@@ -543,6 +543,7 @@ FUZZSRC += $(TOP)/test/vt02.c
|
|||||||
FUZZSRC += $(TOP)/test/fuzzinvariants.c
|
FUZZSRC += $(TOP)/test/fuzzinvariants.c
|
||||||
FUZZSRC += $(TOP)/ext/recover/dbdata.c
|
FUZZSRC += $(TOP)/ext/recover/dbdata.c
|
||||||
FUZZSRC += $(TOP)/ext/recover/sqlite3recover.c
|
FUZZSRC += $(TOP)/ext/recover/sqlite3recover.c
|
||||||
|
FUZZSRC += $(TOP)/ext/misc/percentile.c
|
||||||
FUZZSRC += $(TOP)/ext/misc/randomjson.c
|
FUZZSRC += $(TOP)/ext/misc/randomjson.c
|
||||||
DBFUZZ_OPT =
|
DBFUZZ_OPT =
|
||||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||||
@@ -766,6 +767,7 @@ SHELL_DEP = \
|
|||||||
$(TOP)/ext/misc/ieee754.c \
|
$(TOP)/ext/misc/ieee754.c \
|
||||||
$(TOP)/ext/misc/memtrace.c \
|
$(TOP)/ext/misc/memtrace.c \
|
||||||
$(TOP)/ext/misc/pcachetrace.c \
|
$(TOP)/ext/misc/pcachetrace.c \
|
||||||
|
$(TOP)/ext/misc/percentile.c \
|
||||||
$(TOP)/ext/misc/regexp.c \
|
$(TOP)/ext/misc/regexp.c \
|
||||||
$(TOP)/ext/misc/series.c \
|
$(TOP)/ext/misc/series.c \
|
||||||
$(TOP)/ext/misc/shathree.c \
|
$(TOP)/ext/misc/shathree.c \
|
||||||
@@ -1132,41 +1134,22 @@ install: sqlite3 libsqlite3.a sqlite3.h
|
|||||||
mv sqlite3.h /usr/include
|
mv sqlite3.h /usr/include
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
|
rm -f *.lo *.la *.o *.c *.h *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
|
||||||
rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
|
rm -rf .libs .deps tsrc libtool target_source testrunner_*
|
||||||
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
|
rm -f lemon$(BEXE) sqlite*.tar.gz
|
||||||
rm -f $(PUBLISH)
|
rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE)
|
||||||
rm -f *.da *.bb *.bbg gmon.out
|
rm -f parse.* fts5parse.*
|
||||||
rm -rf tsrc target_source
|
rm -rf tsrc .target_source testrunner_bld_* testdir*
|
||||||
rm -f testloadext.dll libtestloadext.so
|
rm -f tclsqlite3$(TEXE)
|
||||||
rm -f amalgamation-testfixture amalgamation-testfixture.exe
|
rm -f $(TESTPROGS) testrunner.*
|
||||||
rm -f fts3-testfixture fts3-testfixture.exe
|
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
|
||||||
rm -f testfixture testfixture.exe
|
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
||||||
rm -f threadtest3 threadtest3.exe
|
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
|
||||||
rm -f LogEst LogEst.exe
|
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
|
||||||
rm -f fts3view fts3view.exe
|
rm -f sqlite3_analyzer$(TEXE)
|
||||||
rm -f rollback-test rollback-test.exe
|
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
|
||||||
rm -f showdb showdb.exe
|
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
|
||||||
rm -f showjournal showjournal.exe
|
rm -f threadtest5$(TEXE)
|
||||||
rm -f showstat4 showstat4.exe
|
rm -f src-verify has_tclsh*
|
||||||
rm -f showwal showwal.exe
|
|
||||||
rm -f changeset changeset.exe
|
distclean: clean
|
||||||
rm -f speedtest1 speedtest1.exe
|
|
||||||
rm -f wordcount wordcount.exe
|
|
||||||
rm -f rbu rbu.exe
|
|
||||||
rm -f srcck1 srcck1.exe
|
|
||||||
rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
|
|
||||||
rm -f sqlite3rc.h
|
|
||||||
rm -f shell.c sqlite3ext.h
|
|
||||||
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
|
||||||
rm -f sqlite3_expert sqlite3_expert.exe
|
|
||||||
rm -f sqlite-*-output.vsix
|
|
||||||
rm -f mptester mptester.exe
|
|
||||||
rm -f fuzzershell fuzzershell.exe
|
|
||||||
rm -f fuzzcheck fuzzcheck.exe
|
|
||||||
rm -f sessionfuzz
|
|
||||||
rm -f sqldiff sqldiff.exe
|
|
||||||
rm -f fts5.* fts5parse.*
|
|
||||||
rm -f lsm.h lsm1.c
|
|
||||||
rm -f threadtest5
|
|
||||||
rm -f src-verify
|
|
||||||
|
75
manifest
75
manifest
@@ -1,12 +1,12 @@
|
|||||||
C Fix\sa\sproblem\sin\swinOpen().\s\sMerge\sthe\smakefile\senhancements\sfrom\strunk.
|
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sreuse-schema\sbranch.
|
||||||
D 2024-08-29T22:05:38.293
|
D 2024-09-06T15:52:48.974
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
F Makefile.in c322adca45438743dd48882921f73c75f37f0fd4ab67446928b98e3fe928f65f
|
F Makefile.in 9a0a78b9b8ec286340d206de94871ef551734d2a683dffa13ffbb3b7c7531ce6
|
||||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||||
F Makefile.msc 0ed3a1a328c744dc9fbecb848997105ea5ebd9635dbf6481ca179383a216d88f
|
F Makefile.msc ee5f555631cc843c086082bed01bca1eeeae75a56e709a0d1a39cc242078e57e
|
||||||
F README.md 5b678e264236788390d11991f2c0052bd73f19790173883fc56d638bcb849154
|
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
|
||||||
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
|
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||||
@@ -39,7 +39,7 @@ F configure 49523f0a070b583cea040d26eff53a65fb0893eca4663b1343a4d5a9a964da53 x
|
|||||||
F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000
|
F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000
|
||||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||||
F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d
|
F doc/compile-for-windows.md 4d4bfafda42a7a33f166d23aed4db1bb4ea1e5751595a5cced2bad349fd14652
|
||||||
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
|
||||||
F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b
|
F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b
|
||||||
F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706
|
F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706
|
||||||
@@ -54,7 +54,7 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
|||||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||||
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
|
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
|
||||||
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
||||||
F ext/consio/console_io.c 6e02dea912a49f55785b0027fe77960aafee6c236307c23f82ec86a69f1a2001 x
|
F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c74fe5d2b13f x
|
||||||
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
|
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
|
||||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||||
@@ -100,7 +100,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70
|
|||||||
F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81cbefc109ea
|
F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81cbefc109ea
|
||||||
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
|
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
|
||||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||||
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
|
F ext/fts5/fts5_index.c 571483823193f09439356741669aa8c81da838ae6f5e1bfa7517f7ee2fb3addd
|
||||||
F ext/fts5/fts5_main.c 1fddb53f495425d9314c74b30c5848a9dd254be0e5f445bfe38292d5ab21c288
|
F ext/fts5/fts5_main.c 1fddb53f495425d9314c74b30c5848a9dd254be0e5f445bfe38292d5ab21c288
|
||||||
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
|
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
|
||||||
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
||||||
@@ -185,6 +185,7 @@ F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affc
|
|||||||
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
||||||
F ext/fts5/test/fts5hash.test fd3e0367fbf0b0944d6936fdb22696350f57b9871069c6766251578a103e8a14
|
F ext/fts5/test/fts5hash.test fd3e0367fbf0b0944d6936fdb22696350f57b9871069c6766251578a103e8a14
|
||||||
F ext/fts5/test/fts5integrity.test 646796671205dae46af5bb12a49b5696483cfe8e12d71d21454940b13ace95ab
|
F ext/fts5/test/fts5integrity.test 646796671205dae46af5bb12a49b5696483cfe8e12d71d21454940b13ace95ab
|
||||||
|
F ext/fts5/test/fts5integrity2.test 4c3636615c0201232c44a8105d5cb14fd5499fd0ee3014d7ffd7e83aac76ece8
|
||||||
F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c
|
F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c
|
||||||
F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1
|
F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1
|
||||||
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
|
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
|
||||||
@@ -411,7 +412,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58
|
|||||||
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
|
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
|
||||||
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
||||||
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
||||||
F ext/misc/percentile.c af1941dc87d45dd0c2698a3087fbfe9ee0d157e5e72da521430c4b784abcbe81
|
F ext/misc/percentile.c 42eb041edab407e512aaa087f99ed9287fe0b3224f7a6d194456c00fc1454312
|
||||||
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
|
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
|
||||||
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
|
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
|
||||||
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
||||||
@@ -484,7 +485,7 @@ F ext/rbu/rbuvacuum.test 542561741ff2b262e3694bc6012b44694ee62c545845319a06f3237
|
|||||||
F ext/rbu/rbuvacuum2.test ae097d04feb041446a74fac94b24bffeb3fdd60e32b848c5611e507ab702b81b
|
F ext/rbu/rbuvacuum2.test ae097d04feb041446a74fac94b24bffeb3fdd60e32b848c5611e507ab702b81b
|
||||||
F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de
|
F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de
|
||||||
F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205
|
F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205
|
||||||
F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8
|
F ext/rbu/sqlite3rbu.c c07817e89477b8fc286ab6ed87da5bc82fc3490bbbe9e9b22eb2d900e81ee5dc
|
||||||
F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
|
F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
|
||||||
F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0
|
F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0
|
||||||
F ext/recover/dbdata.c 5295f4f922b60d7035b6b9fd5846b13071b9d97ed7fad8496837bb7640d24771
|
F ext/recover/dbdata.c 5295f4f922b60d7035b6b9fd5846b13071b9d97ed7fad8496837bb7640d24771
|
||||||
@@ -595,7 +596,7 @@ F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544
|
|||||||
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
||||||
F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe
|
F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe
|
||||||
F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
|
F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
|
||||||
F ext/session/test_session.c 6acbe67db80ab0806147eb62a12f9e3a44930f4a740b68b0a4340dddda2c10d7
|
F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c
|
||||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||||
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
|
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
|
||||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||||
@@ -686,7 +687,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
|
|||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||||
F main.mk 6b4e3eb9f0e885f9f4b103c11862e3045018f089c335389b8301660f734b92a6
|
F main.mk cc0be8a9ab902e06c0b1c924fa30192e6a6cf3efa91e05ebc5dd1c652416e0a1
|
||||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||||
@@ -711,7 +712,7 @@ F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b
|
|||||||
F src/build.c 648138031b04e573fd9ad6781f0adb0fcd6b6c7d849611918c280f696d7dfab5
|
F src/build.c 648138031b04e573fd9ad6781f0adb0fcd6b6c7d849611918c280f696d7dfab5
|
||||||
F src/callback.c fbd4e8247f1a7f37aec721bde0e312e79cc3bfa41f55a59930bc876ca6baf455
|
F src/callback.c fbd4e8247f1a7f37aec721bde0e312e79cc3bfa41f55a59930bc876ca6baf455
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
|
F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
|
||||||
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
||||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||||
@@ -719,17 +720,17 @@ F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
|
|||||||
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
|
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||||
F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
|
F src/func.c df400a1d3f4625997d4dd8a81951c303e066277c29b861d37e03cd152d7858dd
|
||||||
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
||||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||||
F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
|
F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
|
||||||
F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d
|
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
|
||||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||||
F src/main.c 7cfb761ce0d25ab41419659071326fc98277f2a210cd306ca5e4297d12359640
|
F src/main.c d1662b77a1ab3211430f4149a0c2e9023b890e7043a65293cadb5a62374c35dd
|
||||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||||
@@ -755,7 +756,7 @@ F src/os_win.c 3c5614e5ea39e2ea33659d2d652fabd82ec3b5a39e342ca587eb6e5806e6d047
|
|||||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||||
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
|
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
|
||||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||||
F src/parse.y 5972b7d00af4c8d96fdad781af1ea1d5d51fc3b907ad61bda60e49503274e5ed
|
F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61
|
||||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||||
@@ -768,16 +769,16 @@ F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
|
|||||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||||
F src/shell.c.in 592f97a0b1e42d7eb685c0b7d2f1b473abd61adef9e1be63ccde3928c3b3fe68
|
F src/shell.c.in 592f97a0b1e42d7eb685c0b7d2f1b473abd61adef9e1be63ccde3928c3b3fe68
|
||||||
F src/sqlite.h.in 21f83722ed7518e87dd23a023bdc879acabb837c51da12d90db6f78327b84066
|
F src/sqlite.h.in fa87b85bd482e1ee14afecec21a8624c2140e48b686d64af3b6eb011ad91ffd5
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||||
F src/sqliteInt.h e1234e14a5be5d4cc6de94667bc183453ad76fa6de6d6f053dbc64a9405592c4
|
F src/sqliteInt.h 9c620e7a97237847664f32abf45da3caf2923f14cb1e357154d4d079975f6837
|
||||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||||
F src/status.c 5028a0afee355aa492f26f0b6a3ec23145caa9261a93164d96cd0b9bf1b2318f
|
F src/status.c 5028a0afee355aa492f26f0b6a3ec23145caa9261a93164d96cd0b9bf1b2318f
|
||||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||||
F src/tclsqlite.c f3c74b7612c6f583c94af48531caa1a7fecc53202bf4e0b202d39e54dc9322bc
|
F src/tclsqlite.c f3c74b7612c6f583c94af48531caa1a7fecc53202bf4e0b202d39e54dc9322bc
|
||||||
F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
|
F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
|
||||||
F src/test1.c 3f18399557d954bc85f4564aec8ea1777d2161a81d98a3ff6c9e9046bf3554c1
|
F src/test1.c 8d7cd219c004cd2ced60659ebf045025cc5c16ce19d12459589dacd4310f7f07
|
||||||
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
|
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
|
||||||
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
|
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
|
||||||
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
|
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
|
||||||
@@ -791,7 +792,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97
|
|||||||
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
|
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
|
||||||
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
|
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
|
||||||
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
|
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
|
||||||
F src/test_config.c 0e3579a520130bbbdb06c9166b11f181433fc23c22feb16f8c279fb9525a4b51
|
F src/test_config.c 54b4f17e0b4b49a04cd45394c172379d9471066ae56dd7441343146a650a751c
|
||||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||||
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
|
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
|
||||||
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
|
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
|
||||||
@@ -853,7 +854,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
|||||||
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
||||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||||
F src/where.c d37f2b9e5bef275e605f2d2204de7f2f844708f9e1cc907e52e3e4f7e7ae07cf
|
F src/where.c c924288b72eade267a3478c181f0aa8b627ed028734fc4ae6f1984d8bd5ad99e
|
||||||
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
|
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
|
||||||
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
|
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
|
||||||
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
|
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
|
||||||
@@ -1268,7 +1269,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
|
|||||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||||
F test/fuzzcheck.c 6e87c27df3d95c556870187987dff6efdc712b5cea60abedc8ab9215f471907a
|
F test/fuzzcheck.c 3b8b39e3c0c88422c51ef0a93481d3d528fb370668344bf0ae4c87629c18b021
|
||||||
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
||||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||||
@@ -1280,7 +1281,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767
|
|||||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||||
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
||||||
F test/fuzzinvariants.c 81167c9a7e82c0539a1d704aeb3384046d01f4108cda160a2447cb2a149d6362
|
F test/fuzzinvariants.c 3de49c7b33f5641b67edc2496328a49af029738e92c8499fafbf8618ad42f68d
|
||||||
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
|
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
|
||||||
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
|
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
|
||||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||||
@@ -1347,7 +1348,7 @@ F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d
|
|||||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||||
F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9
|
F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9
|
||||||
F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4
|
F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4
|
||||||
F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e
|
F test/join2.test f59d63264fb24784ae9c3bc9d867eb569cd6d442da5660f8852effe5c1938c27
|
||||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||||
F test/join5.test 380d12a9350f99f0cc681a4f1fea999886f18b3fe0d71a9b3065bcaead1e007f
|
F test/join5.test 380d12a9350f99f0cc681a4f1fea999886f18b3fe0d71a9b3065bcaead1e007f
|
||||||
@@ -1382,7 +1383,7 @@ F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8
|
|||||||
F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562
|
F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562
|
||||||
F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49
|
F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49
|
||||||
F test/json501.test b95e2d14988b682a5cadf079dd6162f0f85fb74cd59c6b1f1624110104a974eb
|
F test/json501.test b95e2d14988b682a5cadf079dd6162f0f85fb74cd59c6b1f1624110104a974eb
|
||||||
F test/json502.test 84634d3dbb521d2814e43624025b760c6198456c8197bbec6c977c0236648f5b
|
F test/json502.test 4ef68e4f272dfb083d4cbceb4e9e51d67ec1186a185e0c13637c50a4dc2f9796
|
||||||
F test/jsonb01.test f4cdfb4cf5a0c940091b17675ed9583f45add0c938f07d65b0de0e19d3a9a101
|
F test/jsonb01.test f4cdfb4cf5a0c940091b17675ed9583f45add0c938f07d65b0de0e19d3a9a101
|
||||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||||
F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
|
F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
|
||||||
@@ -1519,7 +1520,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
|
|||||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||||
F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
|
F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
|
||||||
F test/percentile.test 74e383216a075251512d6ba98beb9dccd6da465e3f73817fc438379e3a628de7
|
F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd
|
||||||
F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
|
F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
|
||||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||||
F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
|
F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
|
||||||
@@ -1722,9 +1723,9 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
|||||||
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
|
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
|
||||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||||
F test/tester.tcl 5fffa7c6d9e293fa109a3ccb925a92dba91c9ea1b824a2d64a0ae60b571231da
|
F test/tester.tcl 14284e98554d0a27c3982dcf4b7c4b88cf025ae8e238dd7e2683071c51c371fd
|
||||||
F test/testrunner.tcl 2c28979f936bc07cfc769080f4268fb7e95b64d0e16a4eca7f9cc6b7eefcde7d
|
F test/testrunner.tcl 0f371d50e606c43c09046fda1416ecdf69089bd125cb478800f040c70086bbe8 x
|
||||||
F test/testrunner_data.tcl 787af292f8c9e51ad2bb62dd8488ababd9e1bc303f920e4cbbe43a7650f3540e
|
F test/testrunner_data.tcl 47a8b2430f0f6a31f56fe6c5fe5c736b3619df4081acaa816fd877f96a68d46a
|
||||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||||
@@ -2060,7 +2061,7 @@ F test/wherelimit3.test 22d73e046870cf8bbe15573eda6b432b07ebe64a88711f9f849c6b36
|
|||||||
F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1
|
F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1
|
||||||
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
|
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
|
||||||
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
|
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
|
||||||
F test/win32longpath.test 42210789bcfc5c0ac202643d6d0237db08df2c9218f2070d9a69e8af1eccf7d7
|
F test/win32longpath.test 304006024ca47104bf5a7415ef31ca83ecfc29351af202baf8588b880cffc116
|
||||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||||
F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa
|
F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa
|
||||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||||
@@ -2141,8 +2142,8 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
|||||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||||
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
||||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||||
F tool/mkctimec.tcl 48ca8eefa9e615cb9057ce6485b9c9ae5801381f24690d7d60b3b2dc8e6b7457 x
|
F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x
|
||||||
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
|
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
|
||||||
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
|
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
|
||||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||||
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
|
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
|
||||||
@@ -2159,7 +2160,7 @@ F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617
|
|||||||
F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a
|
F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a
|
||||||
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
||||||
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
|
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
|
||||||
F tool/omittest.tcl e99c9fecc3f7a8ca2fa75d8ec8bdbb5acce33dc69f0c280aae53064693387f65
|
F tool/omittest.tcl 5ca5e4e01716d5f35b48b00fd351d929f01fbb98169a5a3cd00baf3d2e2019a9
|
||||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||||
F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a
|
F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a
|
||||||
@@ -2221,8 +2222,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 60795a30c64dbaa3be16dc35a39262b5487a5d4abcff20ae8973e12b73af5af2 854b3776ee1fcaa5931e3a0ed104978ca350d218e553586d1c40c2420e1be498
|
P bd247ae7f95d2e50436961e9aee60578e98ceccc0df9f71c201dd4b1884f2085 d94541ae76b5d8b69f5524f10dcccc0814283f438a03f553848ed631a1983633
|
||||||
R 25b272be2c06f88ae1e734e918af2e85
|
R 76a272439d4f25d75a300922d222edfc
|
||||||
U drh
|
U drh
|
||||||
Z 3d8456fdef56a3a1151e6f41c182190c
|
Z 51c246f5c4aa6e5e2a88e51d2bad5700
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
bd247ae7f95d2e50436961e9aee60578e98ceccc0df9f71c201dd4b1884f2085
|
f9ce1ababbd62c579658c737059f6992bdb32909e7a06282fe6a359d10ad1272
|
||||||
|
@@ -295,6 +295,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
|||||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||||
"ENABLE_OFFSET_SQL_FUNC",
|
"ENABLE_OFFSET_SQL_FUNC",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
"ENABLE_ORDERED_SET_AGGREGATES",
|
||||||
|
#endif
|
||||||
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||||
"ENABLE_OVERSIZE_CELL_CHECK",
|
"ENABLE_OVERSIZE_CELL_CHECK",
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2049,7 +2049,11 @@ static void minMaxFinalize(sqlite3_context *context){
|
|||||||
** group_concat(EXPR, ?SEPARATOR?)
|
** group_concat(EXPR, ?SEPARATOR?)
|
||||||
** string_agg(EXPR, SEPARATOR)
|
** string_agg(EXPR, SEPARATOR)
|
||||||
**
|
**
|
||||||
** The SEPARATOR goes before the EXPR string. This is tragic. The
|
** Content is accumulated in GroupConcatCtx.str with the SEPARATOR
|
||||||
|
** coming before the EXPR value, except for the first entry which
|
||||||
|
** omits the SEPARATOR.
|
||||||
|
**
|
||||||
|
** It is tragic that the SEPARATOR goes before the EXPR string. The
|
||||||
** groupConcatInverse() implementation would have been easier if the
|
** groupConcatInverse() implementation would have been easier if the
|
||||||
** SEPARATOR were appended after EXPR. And the order is undocumented,
|
** SEPARATOR were appended after EXPR. And the order is undocumented,
|
||||||
** so we could change it, in theory. But the old behavior has been
|
** so we could change it, in theory. But the old behavior has been
|
||||||
@@ -2153,7 +2157,7 @@ static void groupConcatInverse(
|
|||||||
/* pGCC is always non-NULL since groupConcatStep() will have always
|
/* pGCC is always non-NULL since groupConcatStep() will have always
|
||||||
** run first to initialize it */
|
** run first to initialize it */
|
||||||
if( ALWAYS(pGCC) ){
|
if( ALWAYS(pGCC) ){
|
||||||
int nVS;
|
int nVS; /* Number of characters to remove */
|
||||||
/* Must call sqlite3_value_text() to convert the argument into text prior
|
/* Must call sqlite3_value_text() to convert the argument into text prior
|
||||||
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
|
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
|
||||||
(void)sqlite3_value_text(argv[0]);
|
(void)sqlite3_value_text(argv[0]);
|
||||||
|
@@ -2847,7 +2847,9 @@ static u32 jsonLookupStep(
|
|||||||
zPath++;
|
zPath++;
|
||||||
if( zPath[0]=='"' ){
|
if( zPath[0]=='"' ){
|
||||||
zKey = zPath + 1;
|
zKey = zPath + 1;
|
||||||
for(i=1; zPath[i] && zPath[i]!='"'; i++){}
|
for(i=1; zPath[i] && zPath[i]!='"'; i++){
|
||||||
|
if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
|
||||||
|
}
|
||||||
nKey = i-1;
|
nKey = i-1;
|
||||||
if( zPath[i] ){
|
if( zPath[i] ){
|
||||||
i++;
|
i++;
|
||||||
|
@@ -1938,7 +1938,8 @@ int sqlite3CreateFunc(
|
|||||||
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
|
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
|
||||||
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
|
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
|
||||||
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
|
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
|
||||||
SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
|
SQLITE_SUBTYPE|SQLITE_INNOCUOUS|
|
||||||
|
SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1);
|
||||||
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
|
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
|
||||||
|
|
||||||
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
|
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
|
||||||
|
72
src/parse.y
72
src/parse.y
@@ -264,6 +264,9 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
|
|||||||
CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
|
CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
|
||||||
EXCLUDE GROUPS OTHERS TIES
|
EXCLUDE GROUPS OTHERS TIES
|
||||||
%endif SQLITE_OMIT_WINDOWFUNC
|
%endif SQLITE_OMIT_WINDOWFUNC
|
||||||
|
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
WITHIN
|
||||||
|
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
|
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
|
||||||
GENERATED ALWAYS
|
GENERATED ALWAYS
|
||||||
%endif
|
%endif
|
||||||
@@ -1179,6 +1182,65 @@ expr(A) ::= idj(X) LP STAR RP. {
|
|||||||
A = sqlite3ExprFunction(pParse, 0, &X, 0);
|
A = sqlite3ExprFunction(pParse, 0, &X, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
%include {
|
||||||
|
/* Generate an expression node that represents an ordered-set aggregate function.
|
||||||
|
**
|
||||||
|
** SQLite does not do anything special to evaluate ordered-set aggregates. The
|
||||||
|
** aggregate function itself is expected to do any required ordering on its own.
|
||||||
|
** This is just syntactic sugar.
|
||||||
|
**
|
||||||
|
** This syntax: percentile(f) WITHIN GROUP ( ORDER BY y )
|
||||||
|
**
|
||||||
|
** Is equivalent to: percentile(y,f)
|
||||||
|
**
|
||||||
|
** The purpose of this function is to generate an Expr node from the first syntax
|
||||||
|
** into a TK_FUNCTION node that looks like it came from the second syntax.
|
||||||
|
**
|
||||||
|
** Only functions that have the SQLITE_SELFORDER1 perperty are allowed to do this
|
||||||
|
** transformation. Because DISTINCT is not allowed in the ordered-set aggregate
|
||||||
|
** syntax, an error is raised if DISTINCT is used.
|
||||||
|
*/
|
||||||
|
static Expr *sqlite3ExprAddOrderedsetFunction(
|
||||||
|
Parse *pParse, /* Parsing context */
|
||||||
|
Token *pFuncname, /* Name of the function */
|
||||||
|
int isDistinct, /* DISTINCT or ALL qualifier */
|
||||||
|
ExprList *pOrig, /* Arguments to the function */
|
||||||
|
Expr *pOrderby /* Expression in the ORDER BY clause */
|
||||||
|
){
|
||||||
|
ExprList *p; /* Modified argument list */
|
||||||
|
Expr *pExpr; /* Final result */
|
||||||
|
p = sqlite3ExprListAppend(pParse, 0, pOrderby);
|
||||||
|
if( pOrig ){
|
||||||
|
int i;
|
||||||
|
for(i=0; i<pOrig->nExpr; i++){
|
||||||
|
p = sqlite3ExprListAppend(pParse, p, pOrig->a[i].pExpr);
|
||||||
|
pOrig->a[i].pExpr = 0;
|
||||||
|
}
|
||||||
|
sqlite3ExprListDelete(pParse->db, pOrig);
|
||||||
|
}
|
||||||
|
pExpr = sqlite3ExprFunction(pParse, p, pFuncname, 0);
|
||||||
|
if( pParse->nErr==0 ){
|
||||||
|
FuncDef *pDef;
|
||||||
|
u8 enc = ENC(pParse->db);
|
||||||
|
assert( pExpr!=0 ); /* Because otherwise pParse->nErr would not be zero */
|
||||||
|
assert( p!=0 ); /* Because otherwise pParse->nErr would not be zero */
|
||||||
|
pDef = sqlite3FindFunction(pParse->db, pExpr->u.zToken, -2, enc, 0);
|
||||||
|
if( pDef==0 || (pDef->funcFlags & SQLITE_SELFORDER1)==0 ){
|
||||||
|
sqlite3ErrorMsg(pParse, "%#T() is not an ordered-set aggregate", pExpr);
|
||||||
|
}else if( isDistinct==SF_Distinct ){
|
||||||
|
sqlite3ErrorMsg(pParse, "DISTINCT not allowed on ordered-set aggregate %T()",
|
||||||
|
pFuncname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pExpr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP WITHIN GROUP LP ORDER BY expr(E) RP. {
|
||||||
|
A = sqlite3ExprAddOrderedsetFunction(pParse, &X, D, Y, E);
|
||||||
|
}
|
||||||
|
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
|
||||||
%ifndef SQLITE_OMIT_WINDOWFUNC
|
%ifndef SQLITE_OMIT_WINDOWFUNC
|
||||||
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
|
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
|
||||||
A = sqlite3ExprFunction(pParse, Y, &X, D);
|
A = sqlite3ExprFunction(pParse, Y, &X, D);
|
||||||
@@ -1193,7 +1255,15 @@ expr(A) ::= idj(X) LP STAR RP filter_over(Z). {
|
|||||||
A = sqlite3ExprFunction(pParse, 0, &X, 0);
|
A = sqlite3ExprFunction(pParse, 0, &X, 0);
|
||||||
sqlite3WindowAttach(pParse, A, Z);
|
sqlite3WindowAttach(pParse, A, Z);
|
||||||
}
|
}
|
||||||
%endif
|
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP WITHIN GROUP LP ORDER BY expr(E) RP
|
||||||
|
filter_over(Z). {
|
||||||
|
A = sqlite3ExprAddOrderedsetFunction(pParse, &X, D, Y, E);
|
||||||
|
sqlite3WindowAttach(pParse, A, Z);
|
||||||
|
}
|
||||||
|
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
|
||||||
|
%endif SQLITE_OMIT_WINDOWFUNC
|
||||||
|
|
||||||
term(A) ::= CTIME_KW(OP). {
|
term(A) ::= CTIME_KW(OP). {
|
||||||
A = sqlite3ExprFunction(pParse, 0, &OP, 0);
|
A = sqlite3ExprFunction(pParse, 0, &OP, 0);
|
||||||
|
@@ -5616,6 +5616,15 @@ int sqlite3_create_window_function(
|
|||||||
** [sqlite3_result_subtype()] should avoid setting this property, as the
|
** [sqlite3_result_subtype()] should avoid setting this property, as the
|
||||||
** purpose of this property is to disable certain optimizations that are
|
** purpose of this property is to disable certain optimizations that are
|
||||||
** incompatible with subtypes.
|
** incompatible with subtypes.
|
||||||
|
**
|
||||||
|
** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
|
||||||
|
** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
|
||||||
|
** that internally orders the values provided to the first argument. The
|
||||||
|
** ordered-set aggregate SQL notation with a single ORDER BY term can be
|
||||||
|
** used to invoke this function. If the ordered-set aggregate notation is
|
||||||
|
** used on a function that lacks this flag, then an error is raised. Note
|
||||||
|
** that the ordered-set aggregate syntax is only available if SQLite is
|
||||||
|
** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
|
||||||
** </dd>
|
** </dd>
|
||||||
** </dl>
|
** </dl>
|
||||||
*/
|
*/
|
||||||
@@ -5624,6 +5633,7 @@ int sqlite3_create_window_function(
|
|||||||
#define SQLITE_SUBTYPE 0x000100000
|
#define SQLITE_SUBTYPE 0x000100000
|
||||||
#define SQLITE_INNOCUOUS 0x000200000
|
#define SQLITE_INNOCUOUS 0x000200000
|
||||||
#define SQLITE_RESULT_SUBTYPE 0x001000000
|
#define SQLITE_RESULT_SUBTYPE 0x001000000
|
||||||
|
#define SQLITE_SELFORDER1 0x002000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Deprecated Functions
|
** CAPI3REF: Deprecated Functions
|
||||||
|
@@ -658,6 +658,8 @@
|
|||||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||||
# define double sqlite_int64
|
# define double sqlite_int64
|
||||||
# define float sqlite_int64
|
# define float sqlite_int64
|
||||||
|
# define fabs(X) ((X)<0?-(X):(X))
|
||||||
|
# define sqlite3IsOverflow(X) 0
|
||||||
# define LONGDOUBLE_TYPE sqlite_int64
|
# define LONGDOUBLE_TYPE sqlite_int64
|
||||||
# ifndef SQLITE_BIG_DBL
|
# ifndef SQLITE_BIG_DBL
|
||||||
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
|
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
|
||||||
|
@@ -2343,7 +2343,7 @@ static int SQLITE_TCLAPI test_stmt_scanstatus(
|
|||||||
}
|
}
|
||||||
for(ii=0; ii<(int)nFlag; ii++){
|
for(ii=0; ii<(int)nFlag; ii++){
|
||||||
int iVal = 0;
|
int iVal = 0;
|
||||||
int res = Tcl_GetIndexFromObjStruct(
|
res = Tcl_GetIndexFromObjStruct(
|
||||||
interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal
|
interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal
|
||||||
);
|
);
|
||||||
if( res ) return TCL_ERROR;
|
if( res ) return TCL_ERROR;
|
||||||
|
@@ -189,6 +189,14 @@ static void set_options(Tcl_Interp *interp){
|
|||||||
Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","0",TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","0",TCL_GLOBAL_ONLY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
Tcl_SetVar2(interp, "sqlite_options",
|
||||||
|
"ordered_set_aggregates","1",TCL_GLOBAL_ONLY);
|
||||||
|
#else
|
||||||
|
Tcl_SetVar2(interp, "sqlite_options",
|
||||||
|
"ordered_set_aggregates","0",TCL_GLOBAL_ONLY);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||||
Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY);
|
||||||
#else
|
#else
|
||||||
@@ -341,6 +349,14 @@ static void set_options(Tcl_Interp *interp){
|
|||||||
Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "0", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "0", TCL_GLOBAL_ONLY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_ORDEREDSETFUNC
|
||||||
|
Tcl_SetVar2(interp, "sqlite_options", "ordered_set_funcs", "1",
|
||||||
|
TCL_GLOBAL_ONLY);
|
||||||
|
#else
|
||||||
|
Tcl_SetVar2(interp, "sqlite_options", "ordered_set_funcs", "0",
|
||||||
|
TCL_GLOBAL_ONLY);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||||
Tcl_SetVar2(interp, "sqlite_options", "oversize_cell_check", "1",
|
Tcl_SetVar2(interp, "sqlite_options", "oversize_cell_check", "1",
|
||||||
TCL_GLOBAL_ONLY);
|
TCL_GLOBAL_ONLY);
|
||||||
|
@@ -6199,6 +6199,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
|
|||||||
WhereTerm *pTerm, *pEnd;
|
WhereTerm *pTerm, *pEnd;
|
||||||
SrcItem *pItem;
|
SrcItem *pItem;
|
||||||
WhereLoop *pLoop;
|
WhereLoop *pLoop;
|
||||||
|
Bitmask m1;
|
||||||
pLoop = pWInfo->a[i].pWLoop;
|
pLoop = pWInfo->a[i].pWLoop;
|
||||||
pItem = &pWInfo->pTabList->a[pLoop->iTab];
|
pItem = &pWInfo->pTabList->a[pLoop->iTab];
|
||||||
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
|
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
|
||||||
@@ -6225,7 +6226,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pTerm<pEnd ) continue;
|
if( pTerm<pEnd ) continue;
|
||||||
WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId));
|
WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId));
|
||||||
|
m1 = MASKBIT(i)-1;
|
||||||
|
testcase( ((pWInfo->revMask>>1) & ~m1)!=0 );
|
||||||
|
pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1);
|
||||||
notReady &= ~pLoop->maskSelf;
|
notReady &= ~pLoop->maskSelf;
|
||||||
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
|
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
|
||||||
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
|
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
|
||||||
|
@@ -159,10 +159,11 @@ static struct GlobalVars {
|
|||||||
} g;
|
} g;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Include the external vt02.c and randomjson.c modules.
|
** Include various extensions.
|
||||||
*/
|
*/
|
||||||
extern int sqlite3_vt02_init(sqlite3*,char**,const sqlite3_api_routines*);
|
extern int sqlite3_vt02_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||||
extern int sqlite3_randomjson_init(sqlite3*,char**,const sqlite3_api_routines*);
|
extern int sqlite3_randomjson_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||||
|
extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1044,10 +1045,11 @@ static void bindDebugParameters(sqlite3_stmt *pStmt){
|
|||||||
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
|
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
|
||||||
}else
|
}else
|
||||||
if( strncmp(zVar, "$text_", 6)==0 ){
|
if( strncmp(zVar, "$text_", 6)==0 ){
|
||||||
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
|
size_t szVar = strlen(zVar);
|
||||||
|
char *zBuf = sqlite3_malloc64( szVar-5 );
|
||||||
if( zBuf ){
|
if( zBuf ){
|
||||||
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
|
memcpy(zBuf, &zVar[6], szVar-5);
|
||||||
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
|
sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1329,7 +1331,8 @@ int runCombinedDbSqlInput(
|
|||||||
/* Add the vt02 virtual table */
|
/* Add the vt02 virtual table */
|
||||||
sqlite3_vt02_init(cx.db, 0, 0);
|
sqlite3_vt02_init(cx.db, 0, 0);
|
||||||
|
|
||||||
/* Add the random_json() and random_json5() functions */
|
/* Activate extensions */
|
||||||
|
sqlite3_percentile_init(cx.db, 0, 0);
|
||||||
sqlite3_randomjson_init(cx.db, 0, 0);
|
sqlite3_randomjson_init(cx.db, 0, 0);
|
||||||
|
|
||||||
/* Add support for sqlite_dbdata and sqlite_dbptr virtual tables used
|
/* Add support for sqlite_dbdata and sqlite_dbptr virtual tables used
|
||||||
|
@@ -54,10 +54,11 @@ static void bindDebugParameters(sqlite3_stmt *pStmt){
|
|||||||
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
|
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
|
||||||
}else
|
}else
|
||||||
if( strncmp(zVar, "$text_", 6)==0 ){
|
if( strncmp(zVar, "$text_", 6)==0 ){
|
||||||
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
|
size_t szVar = strlen(zVar);
|
||||||
|
char *zBuf = sqlite3_malloc64( szVar-5 );
|
||||||
if( zBuf ){
|
if( zBuf ){
|
||||||
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
|
memcpy(zBuf, &zVar[6], szVar-5);
|
||||||
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
|
sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -428,4 +428,25 @@ do_eqp_test 12.3 {
|
|||||||
`--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
`--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 2024-09-05 https://sqlite.org/forum/forumpost/8a1e467e905b8d27
|
||||||
|
# When performing the Omit-Noop-Join optimization, if FROM clause terms
|
||||||
|
# to the right of the omitted join have the reverse-order bit set in the
|
||||||
|
# WhereInfo.revMask bitmask, those bits need to be shifted to account
|
||||||
|
# for the omitted join.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 13.0 {
|
||||||
|
CREATE TABLE t1(a1 INTEGER PRIMARY KEY, b1 INT);
|
||||||
|
CREATE TABLE t2(c2 INT, d2 INTEGER PRIMARY KEY);
|
||||||
|
CREATE TABLE t3(e3 INTEGER PRIMARY KEY);
|
||||||
|
INSERT INTO t1 VALUES(33,0);
|
||||||
|
INSERT INTO t2 VALUES(33,1),(33,2);
|
||||||
|
}
|
||||||
|
do_execsql_test 13.1 {
|
||||||
|
SELECT t1.a1, t2.d2
|
||||||
|
FROM (t1 LEFT JOIN t3 ON t3.e3=t1.b1) JOIN t2 ON t2.c2=t1.a1
|
||||||
|
WHERE t1.a1=33
|
||||||
|
ORDER BY t2.d2 DESC;
|
||||||
|
} {33 2 33 1}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -64,4 +64,17 @@ ifcapable vtab {
|
|||||||
} {{\x17} 1 integer 1 1 null {$."\x17"} {$}}
|
} {{\x17} 1 integer 1 1 null {$."\x17"} {$}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# JSON PATH parsing bug involving backslash escapes, reported via
|
||||||
|
# private email from Florent De'Neve on 2024-09-04.
|
||||||
|
#
|
||||||
|
do_execsql_test 5.1 {
|
||||||
|
SELECT json_extract('{"A\"Key":1}', '$.A"Key');
|
||||||
|
} 1
|
||||||
|
do_execsql_test 5.2 {
|
||||||
|
SELECT json_extract('{"A\"Key":1}', '$."A\"Key"');
|
||||||
|
} 1
|
||||||
|
do_execsql_test 5.3 {
|
||||||
|
SELECT JSON_SET('{}', '$."\"Key"', 1);
|
||||||
|
} {{{"\"Key":1}}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -9,7 +9,8 @@
|
|||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is percentile.c extension
|
# focus of this file is percentile.c extension. This also tests
|
||||||
|
# the SQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -25,35 +26,65 @@ do_test percentile-1.0 {
|
|||||||
}
|
}
|
||||||
execsql {SELECT percentile(x,0) FROM t1}
|
execsql {SELECT percentile(x,0) FROM t1}
|
||||||
} {1.0}
|
} {1.0}
|
||||||
foreach {in out} {
|
foreach {in out disc} {
|
||||||
100 11.0
|
100 11.0 11.0
|
||||||
50 8.0
|
50 8.0 8.0
|
||||||
12.5 4.0
|
12.5 4.0 4.0
|
||||||
15 4.4
|
15 4.4 4.0
|
||||||
20 5.2
|
20 5.2 4.0
|
||||||
80 11.0
|
80 11.0 11.0
|
||||||
89 11.0
|
89 11.0 11.0
|
||||||
} {
|
} {
|
||||||
do_test percentile-1.1.$in {
|
do_test percentile-1.1.$in.1 {
|
||||||
execsql {SELECT percentile(x,$in) FROM t1}
|
execsql {SELECT percentile(x,$in) FROM t1}
|
||||||
} $out
|
} $out
|
||||||
|
do_test percentile-1.1.$in.2 {
|
||||||
|
execsql {SELECT percentile_cont(x,$in*0.01) FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.1.$in.3 {
|
||||||
|
execsql {SELECT percentile_disc(x,$in*0.01) FROM t1}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.1.$in.4 {
|
||||||
|
execsql {SELECT median(x) FROM t1}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.1.$in.5 {
|
||||||
|
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.1.$in.6 {
|
||||||
|
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.1.$in.7 {
|
||||||
|
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t1}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.1.$in.8 {
|
||||||
|
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do_execsql_test percentile-1.1.median {
|
do_execsql_test percentile-1.1.median {
|
||||||
SELECT median(x) FROM t1;
|
SELECT median(x) FROM t1;
|
||||||
} 8.0
|
} 8.0
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
foreach {in out} {
|
do_execsql_test percentile-1.1.median {
|
||||||
1.0 11.0
|
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
|
||||||
0.5 8.0
|
} 8.0
|
||||||
0.125 4.0
|
do_execsql_test percentile-1.1.distinct.1 {
|
||||||
0.15 4.4
|
SELECT median(DISTINCT x) FROM t1;
|
||||||
0.2 5.2
|
} 7.0
|
||||||
0.8 11.0
|
do_catchsql_test percentile-1.1.distinct.2 {
|
||||||
0.89 11.0
|
SELECT percentile(DISTINCT 50) WITHIN GROUP (ORDER BY x) FROM t1;
|
||||||
} {
|
} {1 {DISTINCT not allowed on ordered-set aggregate percentile()}}
|
||||||
do_test percentile-1.1b-$in {
|
} else {
|
||||||
execsql {SELECT percentile_cont(x,$in) FROM t1}
|
do_catchsql_test percentile-1.1.median {
|
||||||
} $out
|
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
|
||||||
|
} {1 {near "(": syntax error}}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add some NULL values.
|
# Add some NULL values.
|
||||||
@@ -61,28 +92,69 @@ foreach {in out} {
|
|||||||
do_test percentile-1.2 {
|
do_test percentile-1.2 {
|
||||||
execsql {INSERT INTO t1 VALUES(NULL),(NULL);}
|
execsql {INSERT INTO t1 VALUES(NULL),(NULL);}
|
||||||
} {}
|
} {}
|
||||||
foreach {in out} {
|
foreach {in out disc} {
|
||||||
100 11.0
|
100 11.0 11.0
|
||||||
50 8.0
|
50 8.0 8.0
|
||||||
12.5 4.0
|
12.5 4.0 4.0
|
||||||
15 4.4
|
15 4.4 4.0
|
||||||
20 5.2
|
20 5.2 4.0
|
||||||
80 11.0
|
80 11.0 11.0
|
||||||
89 11.0
|
89 11.0 11.0
|
||||||
} {
|
} {
|
||||||
do_test percentile-1.3.$in {
|
do_test percentile-1.3.$in.1 {
|
||||||
execsql {SELECT percentile(x,$in) FROM t1}
|
execsql {SELECT percentile(x,$in) FROM t1}
|
||||||
} $out
|
} $out
|
||||||
|
do_test percentile-1.3.$in.2 {
|
||||||
|
execsql {SELECT percentile_cont(x,$in*0.01) FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.3.$in.3 {
|
||||||
|
execsql {SELECT percentile_disc(x,$in*0.01) FROM t1}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.3.$in.4 {
|
||||||
|
execsql {SELECT median(x) FROM t1}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.3.$in.5 {
|
||||||
|
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.3.$in.6 {
|
||||||
|
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t1}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.3.$in.7 {
|
||||||
|
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t1}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.3.$in.8 {
|
||||||
|
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# The second argument to percentile can change some, but not much.
|
# The second argument to percentile can change some, but not much.
|
||||||
#
|
#
|
||||||
do_test percentile-1.4 {
|
do_test percentile-1.4.1 {
|
||||||
catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1}
|
catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1}
|
||||||
} {0 4.4}
|
} {0 4.4}
|
||||||
do_test percentile-1.5 {
|
do_test percentile-1.4.2 {
|
||||||
catchsql {SELECT round(percentile(x, 15+0.1*rowid),1) FROM t1}
|
catchsql {SELECT round(percentile_cont(x,(15+0.000001*rowid)*0.01),1) FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not the same for all input rows}}
|
} {0 4.4}
|
||||||
|
do_test percentile-1.4.3 {
|
||||||
|
catchsql {SELECT percentile_disc(x, (15+0.000001*rowid)*0.01) FROM t1}
|
||||||
|
} {0 4.0}
|
||||||
|
do_test percentile-1.5.1 {
|
||||||
|
catchsql {SELECT percentile(x, 15+0.1*rowid) FROM t1}
|
||||||
|
} {1 {the fraction argument to percentile() is not the same for all input rows}}
|
||||||
|
do_test percentile-1.5.2 {
|
||||||
|
catchsql {SELECT percentile_cont(x, (15+0.1*rowid)*0.01) FROM t1}
|
||||||
|
} {1 {the fraction argument to percentile_cont() is not the same for all input rows}}
|
||||||
|
do_test percentile-1.5.3 {
|
||||||
|
catchsql {SELECT percentile_disc(x, (15+0.1*rowid)*0.01) FROM t1}
|
||||||
|
} {1 {the fraction argument to percentile_disc() is not the same for all input rows}}
|
||||||
|
|
||||||
# Input values in a random order
|
# Input values in a random order
|
||||||
#
|
#
|
||||||
@@ -92,65 +164,152 @@ do_test percentile-1.6 {
|
|||||||
INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random();
|
INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random();
|
||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
foreach {in out} {
|
foreach {in out disc} {
|
||||||
100 11.0
|
100 11.0 11.0
|
||||||
50 8.0
|
50 8.0 8.0
|
||||||
12.5 4.0
|
12.5 4.0 4.0
|
||||||
15 4.4
|
15 4.4 4.0
|
||||||
20 5.2
|
20 5.2 4.0
|
||||||
80 11.0
|
80 11.0 11.0
|
||||||
89 11.0
|
89 11.0 11.0
|
||||||
} {
|
} {
|
||||||
do_test percentile-1.7.$in {
|
do_test percentile-1.7.$in.1 {
|
||||||
execsql {SELECT percentile(x,$in) FROM t2}
|
execsql {SELECT percentile(x,$in) FROM t2}
|
||||||
} $out
|
} $out
|
||||||
|
do_test percentile-1.7.$in.2 {
|
||||||
|
execsql {SELECT percentile_cont(x,$in*0.01) FROM t2}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.7.$in.3 {
|
||||||
|
execsql {SELECT percentile_disc(x,$in*0.01) FROM t2}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.7.$in.4 {
|
||||||
|
execsql {SELECT median(x) FROM t2}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.7.$in.5 {
|
||||||
|
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t2}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.7.$in.6 {
|
||||||
|
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t2}
|
||||||
|
} $out
|
||||||
|
do_test percentile-1.7.$in.7 {
|
||||||
|
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
|
||||||
|
FROM t2}
|
||||||
|
} $disc
|
||||||
|
if {$in==50} {
|
||||||
|
do_test percentile-1.7.$in.8 {
|
||||||
|
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t2}
|
||||||
|
} $out
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Wrong number of arguments
|
# Wrong number of arguments
|
||||||
#
|
#
|
||||||
do_test percentile-1.8 {
|
do_test percentile-1.8.1 {
|
||||||
catchsql {SELECT percentile(x,0,1) FROM t1}
|
catchsql {SELECT percentile(x,0,1) FROM t1}
|
||||||
} {1 {wrong number of arguments to function percentile()}}
|
} {1 {wrong number of arguments to function percentile()}}
|
||||||
do_test percentile-1.9 {
|
do_test percentile-1.8.2 {
|
||||||
|
catchsql {SELECT percentile_cont(x,0,1) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_cont()}}
|
||||||
|
do_test percentile-1.8.3 {
|
||||||
|
catchsql {SELECT percentile_disc(x,0,1) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_disc()}}
|
||||||
|
do_test percentile-1.8.4 {
|
||||||
|
catchsql {SELECT median(x,0) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function median()}}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.8.5 {
|
||||||
|
catchsql {SELECT percentile(0,1) WITHIN GROUP(ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile()}}
|
||||||
|
do_test percentile-1.8.2 {
|
||||||
|
catchsql {SELECT percentile_cont(0,1)WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_cont()}}
|
||||||
|
do_test percentile-1.8.3 {
|
||||||
|
catchsql {SELECT percentile_disc(0,1)WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_disc()}}
|
||||||
|
do_test percentile-1.8.4 {
|
||||||
|
catchsql {SELECT median(x) WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function median()}}
|
||||||
|
}
|
||||||
|
do_test percentile-1.9.1 {
|
||||||
catchsql {SELECT percentile(x) FROM t1}
|
catchsql {SELECT percentile(x) FROM t1}
|
||||||
} {1 {wrong number of arguments to function percentile()}}
|
} {1 {wrong number of arguments to function percentile()}}
|
||||||
|
do_test percentile-1.9.2 {
|
||||||
|
catchsql {SELECT percentile_cont(x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_cont()}}
|
||||||
|
do_test percentile-1.9.3 {
|
||||||
|
catchsql {SELECT percentile_disc(x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_disc()}}
|
||||||
|
do_test percentile-1.9.4 {
|
||||||
|
catchsql {SELECT median() FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function median()}}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.9.5 {
|
||||||
|
catchsql {SELECT percentile() WITHIN GROUP(ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile()}}
|
||||||
|
do_test percentile-1.9.6 {
|
||||||
|
catchsql {SELECT percentile_cont()WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_cont()}}
|
||||||
|
do_test percentile-1.9.7 {
|
||||||
|
catchsql {SELECT percentile_disc()WITHIN GROUP (ORDER BY x) FROM t1}
|
||||||
|
} {1 {wrong number of arguments to function percentile_disc()}}
|
||||||
|
}
|
||||||
|
|
||||||
# Second argument must be numeric
|
# Second argument must be numeric
|
||||||
#
|
#
|
||||||
do_test percentile-1.10 {
|
do_test percentile-1.10 {
|
||||||
catchsql {SELECT percentile(x,null) FROM t1}
|
catchsql {SELECT percentile(x,null) FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||||
do_test percentile-1.11 {
|
do_test percentile-1.11 {
|
||||||
catchsql {SELECT percentile(x,'fifty') FROM t1}
|
catchsql {SELECT percentile(x,'fifty') FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||||
do_test percentile-1.12 {
|
do_test percentile-1.12 {
|
||||||
catchsql {SELECT percentile(x,x'3530') FROM t1}
|
catchsql {SELECT percentile(x,x'3530') FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||||
do_test percentile-1.12b {
|
|
||||||
catchsql {SELECT percentile_cont(x,x'3530') FROM t1}
|
|
||||||
} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}}
|
|
||||||
|
|
||||||
# Second argument is out of range
|
# Second argument is out of range
|
||||||
#
|
#
|
||||||
do_test percentile-1.13 {
|
do_test percentile-1.13 {
|
||||||
catchsql {SELECT percentile(x,-0.0000001) FROM t1}
|
catchsql {SELECT percentile(x,-0.0000001) FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||||
do_test percentile-1.14 {
|
do_test percentile-1.14 {
|
||||||
catchsql {SELECT percentile(x,100.0000001) FROM t1}
|
catchsql {SELECT percentile(x,100.0000001) FROM t1}
|
||||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||||
do_test percentile-1.14b {
|
do_test percentile-1.14.2 {
|
||||||
catchsql {SELECT percentile_cont(x,1.0000001) FROM t1}
|
catchsql {SELECT percentile_cont(x,1.0000001) FROM t1}
|
||||||
} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}}
|
} {1 {the fraction argument to percentile_cont() is not between 0.0 and 1.0}}
|
||||||
|
do_test percentile-1.14.3 {
|
||||||
|
catchsql {SELECT percentile_disc(x,1.0000001) FROM t1}
|
||||||
|
} {1 {the fraction argument to percentile_disc() is not between 0.0 and 1.0}}
|
||||||
|
|
||||||
# First argument is not NULL and is not NUMERIC
|
# First argument is not NULL and is not NUMERIC
|
||||||
#
|
#
|
||||||
do_test percentile-1.15 {
|
do_test percentile-1.15.1 {
|
||||||
catchsql {
|
catchsql {
|
||||||
BEGIN;
|
BEGIN;
|
||||||
UPDATE t1 SET x='50' WHERE x IS NULL;
|
UPDATE t1 SET x='50' WHERE x IS NULL;
|
||||||
SELECT percentile(x, 50) FROM t1;
|
SELECT percentile(x, 50) FROM t1;
|
||||||
}
|
}
|
||||||
} {1 {1st argument to percentile() is not numeric}}
|
} {1 {input to percentile() is not numeric}}
|
||||||
|
do_test percentile-1.15.2 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_cont(x, 0.50) FROM t1;
|
||||||
|
}
|
||||||
|
} {1 {input to percentile_cont() is not numeric}}
|
||||||
|
do_test percentile-1.15.3 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_disc(x, 0.50) FROM t1;
|
||||||
|
}
|
||||||
|
} {1 {input to percentile_disc() is not numeric}}
|
||||||
|
do_test percentile-1.15.4 {
|
||||||
|
catchsql {
|
||||||
|
SELECT median(x) FROM t1;
|
||||||
|
}
|
||||||
|
} {1 {input to median() is not numeric}}
|
||||||
do_test percentile-1.16 {
|
do_test percentile-1.16 {
|
||||||
catchsql {
|
catchsql {
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
@@ -158,7 +317,7 @@ do_test percentile-1.16 {
|
|||||||
UPDATE t1 SET x=x'3530' WHERE x IS NULL;
|
UPDATE t1 SET x=x'3530' WHERE x IS NULL;
|
||||||
SELECT percentile(x, 50) FROM t1;
|
SELECT percentile(x, 50) FROM t1;
|
||||||
}
|
}
|
||||||
} {1 {1st argument to percentile() is not numeric}}
|
} {1 {input to percentile() is not numeric}}
|
||||||
do_test percentile-1.17 {
|
do_test percentile-1.17 {
|
||||||
catchsql {
|
catchsql {
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
@@ -186,7 +345,7 @@ do_test percentile-1.19 {
|
|||||||
|
|
||||||
# Infinity as an input
|
# Infinity as an input
|
||||||
#
|
#
|
||||||
do_test percentile-1.20 {
|
do_test percentile-1.20.1 {
|
||||||
catchsql {
|
catchsql {
|
||||||
DELETE FROM t1;
|
DELETE FROM t1;
|
||||||
INSERT INTO t1 SELECT x+0.0 FROM t2;
|
INSERT INTO t1 SELECT x+0.0 FROM t2;
|
||||||
@@ -194,6 +353,43 @@ do_test percentile-1.20 {
|
|||||||
SELECT percentile(x,50) from t1;
|
SELECT percentile(x,50) from t1;
|
||||||
}
|
}
|
||||||
} {1 {Inf input to percentile()}}
|
} {1 {Inf input to percentile()}}
|
||||||
|
do_test percentile-1.20.2 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_cont(x,0.50) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to percentile_cont()}}
|
||||||
|
do_test percentile-1.20.3 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_disc(x,0.50) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to percentile_disc()}}
|
||||||
|
do_test percentile-1.20.4 {
|
||||||
|
catchsql {
|
||||||
|
SELECT median(x) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to median()}}
|
||||||
|
ifcapable ordered_set_aggregates {
|
||||||
|
do_test percentile-1.20.5 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile(50) WITHIN GROUP (ORDER BY x) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to percentile()}}
|
||||||
|
do_test percentile-1.20.6 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_cont(0.50) WITHIN GROUP (ORDER BY x) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to percentile_cont()}}
|
||||||
|
do_test percentile-1.20.7 {
|
||||||
|
catchsql {
|
||||||
|
SELECT percentile_disc(0.50) WITHIN GROUP(ORDER BY X) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to percentile_disc()}}
|
||||||
|
do_test percentile-1.20.8 {
|
||||||
|
catchsql {
|
||||||
|
SELECT median() WITHIN GROUP (ORDER BY x) from t1;
|
||||||
|
}
|
||||||
|
} {1 {Inf input to median()}}
|
||||||
|
}
|
||||||
do_test percentile-1.21 {
|
do_test percentile-1.21 {
|
||||||
catchsql {
|
catchsql {
|
||||||
UPDATE t1 SET x=-1.0e300*1.0e300 WHERE rowid=5;
|
UPDATE t1 SET x=-1.0e300*1.0e300 WHERE rowid=5;
|
||||||
@@ -229,4 +425,172 @@ ifcapable vtab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# median() as a window function. (2024-08-31)
|
||||||
|
#
|
||||||
|
do_execsql_test percentile-3.0 {
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
|
||||||
|
INSERT INTO t1 VALUES (1, 'A', 'one', 8.4),
|
||||||
|
(2, 'B', 'two', 7.1),
|
||||||
|
(3, 'C', 'three', 5.9),
|
||||||
|
(4, 'D', 'one', 11.0),
|
||||||
|
(5, 'E', 'two', 12.5),
|
||||||
|
(6, 'F', 'three', 0.0),
|
||||||
|
(7, 'G', 'one', 2.7);
|
||||||
|
}
|
||||||
|
foreach {id oba expr} {
|
||||||
|
1 0 "median(d)"
|
||||||
|
2 0 "percentile(d,50)"
|
||||||
|
3 0 "percentile_cont(d,0.5)"
|
||||||
|
4 1 "median() WITHIN GROUP (ORDER BY d)"
|
||||||
|
5 1 "percentile(50) WITHIN GROUP (ORDER BY d)"
|
||||||
|
6 1 "percentile_cont(0.5) WITHIN GROUP (ORDER BY d)"
|
||||||
|
} {
|
||||||
|
if {$oba} {
|
||||||
|
ifcapable !ordered_set_aggregates break
|
||||||
|
}
|
||||||
|
set sql "SELECT a, b, c, d, \
|
||||||
|
group_concat(b,'.') OVER w1 AS 'elements', \
|
||||||
|
$expr OVER w1 AS 'median' \
|
||||||
|
FROM t1 \
|
||||||
|
WINDOW w1 AS (ORDER BY c, a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)"
|
||||||
|
do_execsql_test percentile-3.$id.1 $sql {
|
||||||
|
1 A one 8.4 A.D 9.7
|
||||||
|
4 D one 11.0 A.D.G 8.4
|
||||||
|
7 G one 2.7 D.G.C 5.9
|
||||||
|
3 C three 5.9 G.C.F 2.7
|
||||||
|
6 F three 0.0 C.F.B 5.9
|
||||||
|
2 B two 7.1 F.B.E 7.1
|
||||||
|
5 E two 12.5 B.E 9.8
|
||||||
|
}
|
||||||
|
|
||||||
|
set sql "SELECT a, b, c, d, \
|
||||||
|
group_concat(b,'.') OVER w1 AS 'elements', \
|
||||||
|
$expr OVER w1 AS 'median' \
|
||||||
|
FROM t1 \
|
||||||
|
WINDOW w1 AS (ORDER BY c, a \
|
||||||
|
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)"
|
||||||
|
do_execsql_test percentile-3.$id.2 $sql {
|
||||||
|
1 A one 8.4 A.D 9.7
|
||||||
|
4 D one 11.0 A.D.G 8.4
|
||||||
|
7 G one 2.7 A.D.G.C 7.15
|
||||||
|
3 C three 5.9 A.D.G.C.F 5.9
|
||||||
|
6 F three 0.0 A.D.G.C.F.B 6.5
|
||||||
|
2 B two 7.1 A.D.G.C.F.B.E 7.1
|
||||||
|
5 E two 12.5 A.D.G.C.F.B.E 7.1
|
||||||
|
}
|
||||||
|
|
||||||
|
set sql "SELECT a, b, c, d, \
|
||||||
|
group_concat(b,'.') OVER w1 AS 'elements', \
|
||||||
|
$expr OVER w1 AS 'median' \
|
||||||
|
FROM t1 \
|
||||||
|
WINDOW w1 AS (ORDER BY c, a \
|
||||||
|
ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)"
|
||||||
|
do_execsql_test percentile-3.$id.3 $sql {
|
||||||
|
1 A one 8.4 A.D.G.C.F.B.E 7.1
|
||||||
|
4 D one 11.0 A.D.G.C.F.B.E 7.1
|
||||||
|
7 G one 2.7 D.G.C.F.B.E 6.5
|
||||||
|
3 C three 5.9 G.C.F.B.E 5.9
|
||||||
|
6 F three 0.0 C.F.B.E 6.5
|
||||||
|
2 B two 7.1 F.B.E 7.1
|
||||||
|
5 E two 12.5 B.E 9.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test case adapted from examples shown at
|
||||||
|
# https://database.guide/3-functions-to-calculate-the-median-in-sql/
|
||||||
|
#
|
||||||
|
do_execsql_test percential-4.0 {
|
||||||
|
CREATE TABLE products(
|
||||||
|
vendorId INT,
|
||||||
|
productId INTEGER PRIMARY KEY,
|
||||||
|
productName REAL,
|
||||||
|
price REAL
|
||||||
|
);
|
||||||
|
INSERT INTO products VALUES
|
||||||
|
(1001, 17, 'Left-handed screwdriver', 25.99),
|
||||||
|
(1001, 49, 'Right-handed screwdriver', 25.99),
|
||||||
|
(1001, 216, 'Long weight (blue)', 14.75),
|
||||||
|
(1001, 31, 'Long weight (green)', 11.99),
|
||||||
|
(1002, 37, 'Sledge hammer', 33.49),
|
||||||
|
(1003, 7, 'Chainsaw', 245.00),
|
||||||
|
(1003, 8, 'Straw dog box', 55.99),
|
||||||
|
(1003, 12, 'Hammock', 11.01),
|
||||||
|
(1004, 113, 'Teapot', 12.45),
|
||||||
|
(1004, 117, 'Bottomless coffee mug', 9.99);
|
||||||
|
}
|
||||||
|
do_execsql_test percentile-4.1 {
|
||||||
|
SELECT VendorId, ProductId, /* ProductName,*/ Price,
|
||||||
|
avg(price) OVER (PARTITION BY vendorId) AS "Average",
|
||||||
|
median(price) OVER (PARTITION BY vendorId) AS "Median"
|
||||||
|
FROM products
|
||||||
|
ORDER BY vendorId, productId;
|
||||||
|
} {
|
||||||
|
1001 17 25.99 19.68 20.37
|
||||||
|
1001 31 11.99 19.68 20.37
|
||||||
|
1001 49 25.99 19.68 20.37
|
||||||
|
1001 216 14.75 19.68 20.37
|
||||||
|
1002 37 33.49 33.49 33.49
|
||||||
|
1003 7 245.0 104.0 55.99
|
||||||
|
1003 8 55.99 104.0 55.99
|
||||||
|
1003 12 11.01 104.0 55.99
|
||||||
|
1004 113 12.45 11.22 11.22
|
||||||
|
1004 117 9.99 11.22 11.22
|
||||||
|
}
|
||||||
|
do_execsql_test percentile-4.2 {
|
||||||
|
SELECT vendorId, median(price) FROM products
|
||||||
|
GROUP BY 1 ORDER BY 1;
|
||||||
|
} {1001 20.37 1002 33.49 1003 55.99 1004 11.22}
|
||||||
|
|
||||||
|
do_execsql_test percentile-5.0 {
|
||||||
|
CREATE TABLE user(name TEXT, class TEXT, cost REAL);
|
||||||
|
INSERT INTO user VALUES
|
||||||
|
('Alice', 'Y', 3578.27),
|
||||||
|
('Bob', 'X', 3399.99),
|
||||||
|
('Cindy', 'Z', 699.10),
|
||||||
|
('Dave', 'Y', 3078.27),
|
||||||
|
('Emma', 'Z', 2319.99),
|
||||||
|
('Fred', 'Y', 539.99),
|
||||||
|
('Gina', 'X', 2320.49),
|
||||||
|
('Hank', 'W', 24.99),
|
||||||
|
('Irma', 'W', 24.99),
|
||||||
|
('Jake', 'X', 2234.99),
|
||||||
|
('Kim', 'Y', 4319.99),
|
||||||
|
('Liam', 'X', 4968.59),
|
||||||
|
('Mia', 'W', 59.53),
|
||||||
|
('Nate', 'W', 23.50);
|
||||||
|
}
|
||||||
|
do_execsql_test percentile-5.1 {
|
||||||
|
SELECT name, class, cost,
|
||||||
|
percentile(cost, 0) OVER w1 AS 'P0',
|
||||||
|
percentile(cost, 25) OVER w1 AS 'P1',
|
||||||
|
percentile(cost, 50) OVER w1 AS 'P2',
|
||||||
|
percentile(cost, 75) OVER w1 AS 'P3',
|
||||||
|
percentile(cost, 100) OVER w1 AS 'P4'
|
||||||
|
FROM user
|
||||||
|
WINDOW w1 AS (PARTITION BY class)
|
||||||
|
ORDER BY class, cost;
|
||||||
|
} {
|
||||||
|
Nate W 23.5 23.5 24.6175 24.99 33.625 59.53
|
||||||
|
Hank W 24.99 23.5 24.6175 24.99 33.625 59.53
|
||||||
|
Irma W 24.99 23.5 24.6175 24.99 33.625 59.53
|
||||||
|
Mia W 59.53 23.5 24.6175 24.99 33.625 59.53
|
||||||
|
Jake X 2234.99 2234.99 2299.115 2860.24 3792.14 4968.59
|
||||||
|
Gina X 2320.49 2234.99 2299.115 2860.24 3792.14 4968.59
|
||||||
|
Bob X 3399.99 2234.99 2299.115 2860.24 3792.14 4968.59
|
||||||
|
Liam X 4968.59 2234.99 2299.115 2860.24 3792.14 4968.59
|
||||||
|
Fred Y 539.99 539.99 2443.7 3328.27 3763.7 4319.99
|
||||||
|
Dave Y 3078.27 539.99 2443.7 3328.27 3763.7 4319.99
|
||||||
|
Alice Y 3578.27 539.99 2443.7 3328.27 3763.7 4319.99
|
||||||
|
Kim Y 4319.99 539.99 2443.7 3328.27 3763.7 4319.99
|
||||||
|
Cindy Z 699.1 699.1 1104.3225 1509.545 1914.7675 2319.99
|
||||||
|
Emma Z 2319.99 699.1 1104.3225 1509.545 1914.7675 2319.99
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fuzzer find.
|
||||||
|
do_execsql_test percentile-6.0 {
|
||||||
|
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<12)
|
||||||
|
SELECT median(iif(n%2,0.1,1.0)) FROM c;
|
||||||
|
} 0.55
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -1279,10 +1279,15 @@ proc finalize_testing {} {
|
|||||||
out of $nTest tests"
|
out of $nTest tests"
|
||||||
} else {
|
} else {
|
||||||
set cpuinfo {}
|
set cpuinfo {}
|
||||||
if {[catch {exec hostname} hname]==0} {set cpuinfo [string trim $hname]}
|
if {[catch {exec hostname} hname]==0} {
|
||||||
|
regsub {\.local$} $hname {} hname
|
||||||
|
set cpuinfo [string trim $hname]
|
||||||
|
}
|
||||||
append cpuinfo " $::tcl_platform(os)"
|
append cpuinfo " $::tcl_platform(os)"
|
||||||
append cpuinfo " [expr {$::tcl_platform(pointerSize)*8}]-bit"
|
append cpuinfo " [expr {$::tcl_platform(pointerSize)*8}]-bit"
|
||||||
append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
|
if {[string match big* $::tcl_platform(byteOrder)]} {
|
||||||
|
append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
|
||||||
|
}
|
||||||
output2 "SQLite [sqlite3 -sourceid]"
|
output2 "SQLite [sqlite3 -sourceid]"
|
||||||
output2 "$nErr errors out of $nTest tests on $cpuinfo"
|
output2 "$nErr errors out of $nTest tests on $cpuinfo"
|
||||||
}
|
}
|
||||||
|
190
test/testrunner.tcl
Normal file → Executable file
190
test/testrunner.tcl
Normal file → Executable file
@@ -1,3 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Script to runs tests for SQLite. Run with option "help" for more info. \
|
||||||
|
exec tclsh "$0" "$@"
|
||||||
|
|
||||||
set dir [pwd]
|
set dir [pwd]
|
||||||
set testdir [file normalize [file dirname $argv0]]
|
set testdir [file normalize [file dirname $argv0]]
|
||||||
@@ -14,8 +17,14 @@ cd $dir
|
|||||||
# recommend that the user build one.
|
# recommend that the user build one.
|
||||||
#
|
#
|
||||||
proc find_interpreter {} {
|
proc find_interpreter {} {
|
||||||
|
global dir
|
||||||
set interpreter [file tail [info nameofexec]]
|
set interpreter [file tail [info nameofexec]]
|
||||||
set rc [catch { package require sqlite3 }]
|
set rc [catch { package require sqlite3 }]
|
||||||
|
if {$rc} {
|
||||||
|
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
|
||||||
|
set rc [catch { package require sqlite3 }]
|
||||||
|
}
|
||||||
|
}
|
||||||
if {$rc} {
|
if {$rc} {
|
||||||
if { [string match -nocase testfixture* $interpreter]==0
|
if { [string match -nocase testfixture* $interpreter]==0
|
||||||
&& [file executable ./testfixture]
|
&& [file executable ./testfixture]
|
||||||
@@ -28,8 +37,30 @@ proc find_interpreter {} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if {$rc} {
|
if {$rc} {
|
||||||
puts stderr "Failed to find tcl package sqlite3"
|
puts "Cannot find tcl package sqlite3: Trying to build it now..."
|
||||||
puts stderr "Run \"make testfixture\" and then try again..."
|
if {$::tcl_platform(platform)=="windows"} {
|
||||||
|
set bat [open make-tcl-extension.bat w]
|
||||||
|
puts $bat "nmake /f Makefile.msc tclextension"
|
||||||
|
close $bat
|
||||||
|
catch {exec -ignorestderr -- make-tcl-extension.bat}
|
||||||
|
} else {
|
||||||
|
catch {exec make tclextension}
|
||||||
|
}
|
||||||
|
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
|
||||||
|
set rc [catch { package require sqlite3 }]
|
||||||
|
}
|
||||||
|
if {$rc==0} {
|
||||||
|
puts "The SQLite tcl extension was successfully built and loaded."
|
||||||
|
puts "Run \"make tclextension-install\" to avoid having to rebuild\
|
||||||
|
it in the future."
|
||||||
|
} else {
|
||||||
|
puts "Unable to build the SQLite tcl extension"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {$rc} {
|
||||||
|
puts stderr "Cannot find a working instance of the SQLite tcl extension."
|
||||||
|
puts stderr "Run \"make tclextension\" or \"make testfixture\" and\
|
||||||
|
try again..."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,8 +85,9 @@ proc usage {} {
|
|||||||
Usage:
|
Usage:
|
||||||
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
|
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
|
||||||
$a0 PERMUTATION FILE
|
$a0 PERMUTATION FILE
|
||||||
$a0 errors ?-v|--verbose?
|
$a0 errors ?-v|--verbose? ?-s|--summary? ?PATTERN?
|
||||||
$a0 help
|
$a0 help
|
||||||
|
$a0 joblist ?PATTERN?
|
||||||
$a0 njob ?NJOB?
|
$a0 njob ?NJOB?
|
||||||
$a0 script ?-msvc? CONFIG
|
$a0 script ?-msvc? CONFIG
|
||||||
$a0 status ?-d SECS? ?--cls?
|
$a0 status ?-d SECS? ?--cls?
|
||||||
@@ -112,10 +144,12 @@ The "script" command outputs the script used to build a configuration.
|
|||||||
Add the "-msvc" option for a Windows-compatible script. For a list of
|
Add the "-msvc" option for a Windows-compatible script. For a list of
|
||||||
available configurations enter "$a0 script help".
|
available configurations enter "$a0 script help".
|
||||||
|
|
||||||
The "errors" commands shows the output of all tests that failed in the
|
The "errors" commands shows the output of tests that failed in the
|
||||||
most recent run. Complete output is shown if the -v or --verbose options
|
most recent run. Complete output is shown if the -v or --verbose options
|
||||||
are used. Otherwise, an attempt is made to minimize the output to show
|
are used. Otherwise, an attempt is made to minimize the output to show
|
||||||
only the parts that contain the error messages.
|
only the parts that contain the error messages. The --summary option just
|
||||||
|
shows the jobs that failed. If PATTERN are provided, the error information
|
||||||
|
is only provided for jobs that match PATTERN.
|
||||||
|
|
||||||
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
|
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
|
||||||
}]]
|
}]]
|
||||||
@@ -284,6 +318,8 @@ set TRG(schema) {
|
|||||||
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
|
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
|
||||||
ntest INT, -- Number of test cases run
|
ntest INT, -- Number of test cases run
|
||||||
nerr INT, -- Number of errors reported
|
nerr INT, -- Number of errors reported
|
||||||
|
svers TEXT, -- Reported SQLite version
|
||||||
|
pltfm TEXT, -- Host platform reported
|
||||||
output TEXT -- test output
|
output TEXT -- test output
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -356,8 +392,8 @@ if {([llength $argv]==2 || [llength $argv]==1)
|
|||||||
sqlite3 mydb $TRG(dbname)
|
sqlite3 mydb $TRG(dbname)
|
||||||
if {[llength $argv]==2} {
|
if {[llength $argv]==2} {
|
||||||
set param [lindex $argv 1]
|
set param [lindex $argv 1]
|
||||||
if {[string is integer $param]==0 || $param<1 || $param>128} {
|
if {[string is integer $param]==0 || $param<0 || $param>128} {
|
||||||
puts stderr "parameter must be an integer between 1 and 128"
|
puts stderr "parameter must be an integer between 0 and 128"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,13 +512,22 @@ proc show_status {db cls} {
|
|||||||
$ne errors, $nt tests"]
|
$ne errors, $nt tests"]
|
||||||
|
|
||||||
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
||||||
set nrun 0
|
set line "Running: $S(running) (max: $nJob)"
|
||||||
puts [format %-79s "Running: $S(running) (max: $nJob)"]
|
if {$S(running)>0 && $fin>100 && $fin>0.05*$total} {
|
||||||
|
# Only estimate the time remaining after completing at least 100
|
||||||
|
# jobs amounting to 10% of the total. Never estimate less than
|
||||||
|
# 2% of the total time used so far.
|
||||||
|
set tmleft [expr {($tm/$fin)*($total-$fin)}]
|
||||||
|
if {$tmleft<0.02*$tm} {
|
||||||
|
set tmleft [expr {$tm*0.02}]
|
||||||
|
}
|
||||||
|
append line " est time left [elapsetime $tmleft]"
|
||||||
|
}
|
||||||
|
puts [format %-79.79s $line]
|
||||||
if {$S(running)>0} {
|
if {$S(running)>0} {
|
||||||
$db eval {
|
$db eval {
|
||||||
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
|
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
|
||||||
} job {
|
} job {
|
||||||
incr nrun
|
|
||||||
display_job [array get job] $now
|
display_job [array get job] $now
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,44 +613,80 @@ if {[llength $argv]>=1
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
# Check if this is the "joblist" command:
|
||||||
|
#
|
||||||
|
if {[llength $argv]>=1
|
||||||
|
&& [string compare -nocase "joblist" [lindex $argv 0]]==0
|
||||||
|
} {
|
||||||
|
set pattern {}
|
||||||
|
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
|
||||||
|
set a0 [lindex $argv $ii]
|
||||||
|
if {$pattern==""} {
|
||||||
|
set pattern [string trim $a0 *]
|
||||||
|
} else {
|
||||||
|
puts "unknown option: \"$a0\""
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set SQL {SELECT displaytype, displayname, state FROM jobs}
|
||||||
|
if {$pattern!=""} {
|
||||||
|
regsub -all {[^a-zA-Z0-9*.-/]} $pattern ? pattern
|
||||||
|
append SQL " WHERE displayname GLOB '*$pattern*'"
|
||||||
|
}
|
||||||
|
append SQL " ORDER BY starttime"
|
||||||
|
|
||||||
|
if {![file readable $TRG(dbname)]} {
|
||||||
|
puts "Database missing: $TRG(dbname)"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
sqlite3 mydb $TRG(dbname)
|
||||||
|
mydb timeout 2000
|
||||||
|
|
||||||
|
mydb eval $SQL {
|
||||||
|
set label UNKNOWN
|
||||||
|
switch -- $state {
|
||||||
|
ready {set label READY}
|
||||||
|
done {set label DONE}
|
||||||
|
failed {set label FAILED}
|
||||||
|
omit {set label OMIT}
|
||||||
|
running {set label RUNNING}
|
||||||
|
}
|
||||||
|
puts [format {%-7s %-5s %s} $label $displaytype $displayname]
|
||||||
|
}
|
||||||
|
mydb close
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
# Scan the output of all jobs looking for the summary lines that
|
# Scan the output of all jobs looking for the summary lines that
|
||||||
# report the number of test cases and the number of errors.
|
# report the number of test cases and the number of errors.
|
||||||
# Aggregate these numbers and return them.
|
# Aggregate these numbers and return them.
|
||||||
#
|
#
|
||||||
proc aggregate_test_counts {db} {
|
proc aggregate_test_counts {db} {
|
||||||
set ncase 0
|
set ne 0
|
||||||
set nerr 0
|
set nt 0
|
||||||
$db eval {SELECT output FROM jobs WHERE displaytype IN ('tcl','fuzz')} {
|
$db eval {SELECT sum(nerr) AS ne, sum(ntest) as nt FROM jobs} break
|
||||||
set n 0
|
return [list $ne $nt]
|
||||||
set m 0
|
|
||||||
if {[regexp {(\d+) errors out of (\d+) tests} $output all n m]
|
|
||||||
&& [string is integer -strict $n]
|
|
||||||
&& [string is integer -strict $m]} {
|
|
||||||
incr ncase $m
|
|
||||||
incr nerr $n
|
|
||||||
} elseif {[regexp {sessionfuzz.*: *(\d+) cases, (\d+) crash} $output \
|
|
||||||
all m n]
|
|
||||||
&& [string is integer -strict $m]
|
|
||||||
&& [string is integer -strict $n]} {
|
|
||||||
incr ncase $m
|
|
||||||
incr nerr $n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [list $nerr $ncase]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
# Check if this is the "errors" command:
|
# Check if this is the "errors" command:
|
||||||
#
|
#
|
||||||
if {[llength $argv]>=1 && [llength $argv]<=2
|
if {[llength $argv]>=1
|
||||||
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
|
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
|
||||||
[string match err* [lindex $argv 0]]==1)
|
[string match err* [lindex $argv 0]]==1)
|
||||||
} {
|
} {
|
||||||
set verbose 0
|
set verbose 0
|
||||||
|
set pattern {}
|
||||||
|
set summary 0
|
||||||
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
|
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
|
||||||
set a0 [lindex $argv $ii]
|
set a0 [lindex $argv $ii]
|
||||||
if {$a0=="-v" || $a0=="--verbose" || $a0=="-verbose"} {
|
if {$a0=="-v" || $a0=="--verbose" || $a0=="-verbose"} {
|
||||||
set verbose 1
|
set verbose 1
|
||||||
|
} elseif {$a0=="-s" || $a0=="--summary" || $a0=="-summary"} {
|
||||||
|
set summary 1
|
||||||
|
} elseif {$pattern==""} {
|
||||||
|
set pattern *[string trim $a0 *]*
|
||||||
} else {
|
} else {
|
||||||
puts "unknown option: \"$a0\"". Use --help for more info."
|
puts "unknown option: \"$a0\"". Use --help for more info."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -613,9 +694,22 @@ if {[llength $argv]>=1 && [llength $argv]<=2
|
|||||||
}
|
}
|
||||||
set cnt 0
|
set cnt 0
|
||||||
sqlite3 mydb $TRG(dbname)
|
sqlite3 mydb $TRG(dbname)
|
||||||
mydb timeout 2000
|
mydb timeout 5000
|
||||||
mydb eval {SELECT displaytype, displayname, output
|
if {$summary} {
|
||||||
FROM jobs WHERE state='failed'} {
|
set sql "SELECT displayname FROM jobs WHERE state='failed'"
|
||||||
|
} else {
|
||||||
|
set sql "SELECT displaytype, displayname, output FROM jobs \
|
||||||
|
WHERE state='failed'"
|
||||||
|
}
|
||||||
|
if {$pattern!=""} {
|
||||||
|
regsub -all {[^a-zA-Z0-9*/ ?]} $pattern . pattern
|
||||||
|
append sql " AND displayname GLOB '$pattern'"
|
||||||
|
}
|
||||||
|
mydb eval $sql {
|
||||||
|
if {$summary} {
|
||||||
|
puts "FAILED: $displayname"
|
||||||
|
continue
|
||||||
|
}
|
||||||
puts "**** $displayname ****"
|
puts "**** $displayname ****"
|
||||||
if {$verbose || $displaytype!="tcl"} {
|
if {$verbose || $displaytype!="tcl"} {
|
||||||
puts $output
|
puts $output
|
||||||
@@ -628,9 +722,13 @@ if {[llength $argv]>=1 && [llength $argv]<=2
|
|||||||
}
|
}
|
||||||
incr cnt
|
incr cnt
|
||||||
}
|
}
|
||||||
set summary [aggregate_test_counts mydb]
|
if {$pattern==""} {
|
||||||
mydb close
|
set summary [aggregate_test_counts mydb]
|
||||||
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
|
mydb close
|
||||||
|
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
|
||||||
|
} else {
|
||||||
|
mydb close
|
||||||
|
}
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,6 +1194,7 @@ proc add_jobs_from_cmdline {patternlist} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
devtest -
|
||||||
mdevtest {
|
mdevtest {
|
||||||
set config_set {
|
set config_set {
|
||||||
ReuseSchema-O0
|
ReuseSchema-O0
|
||||||
@@ -1184,10 +1283,13 @@ proc mark_job_as_finished {jobid output state endtm} {
|
|||||||
set ntest 1
|
set ntest 1
|
||||||
set nerr 0
|
set nerr 0
|
||||||
if {$endtm>0} {
|
if {$endtm>0} {
|
||||||
if {[regexp {\y(\d+) errors out of (\d+) tests} $output all a b]} {
|
set re {\y(\d+) errors out of (\d+) tests( on [^\n]+\n)?}
|
||||||
|
if {[regexp $re $output all a b pltfm]} {
|
||||||
set nerr $a
|
set nerr $a
|
||||||
set ntest $b
|
set ntest $b
|
||||||
}
|
}
|
||||||
|
regexp {\ySQLite \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [0-9a-fA-F]+} \
|
||||||
|
$output svers
|
||||||
}
|
}
|
||||||
r_write_db {
|
r_write_db {
|
||||||
if {$state=="failed"} {
|
if {$state=="failed"} {
|
||||||
@@ -1196,10 +1298,11 @@ proc mark_job_as_finished {jobid output state endtm} {
|
|||||||
} else {
|
} else {
|
||||||
set childstate ready
|
set childstate ready
|
||||||
}
|
}
|
||||||
|
if {[info exists pltfm]} {set pltfm [string trim $pltfm]}
|
||||||
trdb eval {
|
trdb eval {
|
||||||
UPDATE jobs
|
UPDATE jobs
|
||||||
SET output=$output, state=$state, endtime=$endtm,
|
SET output=$output, state=$state, endtime=$endtm,
|
||||||
ntest=$ntest, nerr=$nerr
|
ntest=$ntest, nerr=$nerr, svers=$svers, pltfm=$pltfm
|
||||||
WHERE jobid=$jobid;
|
WHERE jobid=$jobid;
|
||||||
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
|
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
|
||||||
}
|
}
|
||||||
@@ -1452,7 +1555,16 @@ proc run_testset {} {
|
|||||||
FROM jobs WHERE endtime>0
|
FROM jobs WHERE endtime>0
|
||||||
} break;
|
} break;
|
||||||
set et [elapsetime $totaltime]
|
set et [elapsetime $totaltime]
|
||||||
puts "$totalerr errors out of $totaltest tests in about $et"
|
set pltfm {}
|
||||||
|
trdb eval {
|
||||||
|
SELECT pltfm, count(*) FROM jobs WHERE pltfm IS NOT NULL
|
||||||
|
ORDER BY 2 DESC LIMIT 1
|
||||||
|
} break
|
||||||
|
puts "$totalerr errors out of $totaltest tests in $et $pltfm"
|
||||||
|
trdb eval {
|
||||||
|
SELECT DISTINCT substr(svers,1,79) as v1 FROM jobs WHERE svers IS NOT NULL
|
||||||
|
} {puts $v1}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Handle the --buildonly option, if it was specified.
|
# Handle the --buildonly option, if it was specified.
|
||||||
|
@@ -88,6 +88,7 @@ namespace eval trd {
|
|||||||
--disable-amalgamation --disable-shared
|
--disable-amalgamation --disable-shared
|
||||||
--enable-session
|
--enable-session
|
||||||
-DSQLITE_ENABLE_RBU
|
-DSQLITE_ENABLE_RBU
|
||||||
|
-DSQLITE_ENABLE_STMT_SCANSTATUS
|
||||||
}
|
}
|
||||||
|
|
||||||
# These two are used by [testrunner.tcl mdevtest] (All-O0) and
|
# These two are used by [testrunner.tcl mdevtest] (All-O0) and
|
||||||
@@ -95,6 +96,7 @@ namespace eval trd {
|
|||||||
#
|
#
|
||||||
set build(All-Debug) {
|
set build(All-Debug) {
|
||||||
--enable-debug --enable-all
|
--enable-debug --enable-all
|
||||||
|
-DSQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
}
|
}
|
||||||
set build(All-O0) {
|
set build(All-O0) {
|
||||||
-O0 --enable-all
|
-O0 --enable-all
|
||||||
|
@@ -127,6 +127,17 @@ foreach tn {1a 1b 1c 1d 1e 1f} {
|
|||||||
db3 close
|
db3 close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# These over-length file and directory names are difficult to delete.
|
||||||
|
# The "file delete -force" might not work, depending on the TCL build
|
||||||
|
# being used. So first try to delete using the windows rmdir command.
|
||||||
|
#
|
||||||
|
set fd [open cleanup.bat w]
|
||||||
|
puts $fd "rmdir /q /s $longPath(1)"
|
||||||
|
close $fd
|
||||||
|
if {[catch {exec cleanup.bat} msg]} {
|
||||||
|
puts "Command \[cleanup.bat\] returns $msg"
|
||||||
|
}
|
||||||
|
|
||||||
file delete -force $fileName
|
file delete -force $fileName
|
||||||
file delete -force $longPath(3)
|
file delete -force $longPath(3)
|
||||||
file delete -force $longPath(2)
|
file delete -force $longPath(2)
|
||||||
|
@@ -159,6 +159,7 @@ set boolean_defnil_options {
|
|||||||
SQLITE_ENABLE_MULTIPLEX
|
SQLITE_ENABLE_MULTIPLEX
|
||||||
SQLITE_ENABLE_NORMALIZE
|
SQLITE_ENABLE_NORMALIZE
|
||||||
SQLITE_ENABLE_NULL_TRIM
|
SQLITE_ENABLE_NULL_TRIM
|
||||||
|
SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
SQLITE_ENABLE_OFFSET_SQL_FUNC
|
SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||||
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||||
SQLITE_ENABLE_PREUPDATE_HOOK
|
SQLITE_ENABLE_PREUPDATE_HOOK
|
||||||
|
@@ -164,6 +164,11 @@ struct Keyword {
|
|||||||
#else
|
#else
|
||||||
# define RETURNING 0x00400000
|
# define RETURNING 0x00400000
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||||
|
# define ORDERSET 0
|
||||||
|
#else
|
||||||
|
# define ORDERSET 0x00800000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -316,6 +321,7 @@ static Keyword aKeywordTable[] = {
|
|||||||
{ "WHERE", "TK_WHERE", ALWAYS, 10 },
|
{ "WHERE", "TK_WHERE", ALWAYS, 10 },
|
||||||
{ "WINDOW", "TK_WINDOW", WINDOWFUNC, 3 },
|
{ "WINDOW", "TK_WINDOW", WINDOWFUNC, 3 },
|
||||||
{ "WITH", "TK_WITH", CTE, 4 },
|
{ "WITH", "TK_WITH", CTE, 4 },
|
||||||
|
{ "WITHIN", "TK_WITHIN", ORDERSET, 1 },
|
||||||
{ "WITHOUT", "TK_WITHOUT", ALWAYS, 1 },
|
{ "WITHOUT", "TK_WITHOUT", ALWAYS, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,370 +1,220 @@
|
|||||||
# Documentation for this script. This may be output to stderr
|
#!/usr/bin/tclsh
|
||||||
|
#
|
||||||
|
# Documentation for this script. This may be output to
|
||||||
# if the script is invoked incorrectly.
|
# if the script is invoked incorrectly.
|
||||||
|
#
|
||||||
set ::USAGE_MESSAGE {
|
set ::USAGE_MESSAGE {
|
||||||
This Tcl script is used to test the various compile time options
|
This Tcl script is used to test the various compile time options
|
||||||
available for omitting code (the SQLITE_OMIT_xxx options). It
|
available for building SQLite, especially options taht omit
|
||||||
should be invoked as follows:
|
features (the SQLITE_OMIT_xxx options). It should be invoked as follows:
|
||||||
|
|
||||||
<script> ?test-symbol? ?-makefile PATH-TO-MAKEFILE? ?-skip_run?
|
./configure CFLAGS=-O0
|
||||||
|
tclsh test/omittest.tcl
|
||||||
|
|
||||||
The default value for ::MAKEFILE is "../Makefile.linux.gcc".
|
|
||||||
|
|
||||||
If -skip_run option is given then only the compile part is attempted.
|
|
||||||
|
|
||||||
This script builds the testfixture program and runs the SQLite test suite
|
|
||||||
once with each SQLITE_OMIT_ option defined and then once with all options
|
|
||||||
defined together. Each run is performed in a seperate directory created
|
|
||||||
as a sub-directory of the current directory by the script. The output
|
|
||||||
of the build is saved in <sub-directory>/build.log. The output of the
|
|
||||||
test-suite is saved in <sub-directory>/test.log.
|
|
||||||
|
|
||||||
Almost any SQLite makefile (except those generated by configure - see below)
|
|
||||||
should work. The following properties are required:
|
|
||||||
|
|
||||||
* The makefile should support the "testfixture" target.
|
|
||||||
* The makefile should support the "test" target.
|
|
||||||
* The makefile should support the variable "OPTS" as a way to pass
|
|
||||||
options from the make command line to lemon and the C compiler.
|
|
||||||
|
|
||||||
More precisely, the following two invocations must be supported:
|
|
||||||
|
|
||||||
$::MAKEBIN -f $::MAKEFILE testfixture OPTS="-DSQLITE_OMIT_ALTERTABLE=1"
|
|
||||||
$::MAKEBIN -f $::MAKEFILE test
|
|
||||||
|
|
||||||
Makefiles generated by the sqlite configure program cannot be used as
|
|
||||||
they do not respect the OPTS variable.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# List of all options to be tested.
|
||||||
# Build a testfixture executable and run quick.test using it. The first
|
|
||||||
# parameter is the name of the directory to create and use to run the
|
|
||||||
# test in. The second parameter is a list of OMIT symbols to define
|
|
||||||
# when doing so. For example:
|
|
||||||
#
|
#
|
||||||
# run_quick_test /tmp/testdir {SQLITE_OMIT_TRIGGER SQLITE_OMIT_VIEW}
|
set CompileOptionsToTest {
|
||||||
|
SQLITE_OMIT_ALTERTABLE
|
||||||
|
SQLITE_OMIT_ANALYZE
|
||||||
|
SQLITE_OMIT_ATTACH
|
||||||
|
SQLITE_OMIT_AUTHORIZATION
|
||||||
|
SQLITE_OMIT_AUTOINCREMENT
|
||||||
|
SQLITE_OMIT_AUTOINIT
|
||||||
|
SQLITE_OMIT_AUTOMATIC_INDEX
|
||||||
|
SQLITE_OMIT_AUTORESET
|
||||||
|
SQLITE_OMIT_AUTOVACUUM
|
||||||
|
SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS
|
||||||
|
SQLITE_OMIT_BETWEEN_OPTIMIZATION
|
||||||
|
SQLITE_OMIT_BLOB_LITERAL
|
||||||
|
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
|
||||||
|
SQLITE_OMIT_CAST
|
||||||
|
SQLITE_OMIT_CHECK
|
||||||
|
SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||||
|
SQLITE_OMIT_COMPLETE
|
||||||
|
SQLITE_OMIT_COMPOUND_SELECT
|
||||||
|
SQLITE_OMIT_CONFLICT_CLAUSE
|
||||||
|
SQLITE_OMIT_CTE
|
||||||
|
SQLITE_OMIT_DATETIME_FUNCS
|
||||||
|
SQLITE_OMIT_DECLTYPE
|
||||||
|
SQLITE_OMIT_DEPRECATED
|
||||||
|
SQLITE_OMIT_DESERIALIZE
|
||||||
|
SQLITE_OMIT_DISKIO
|
||||||
|
SQLITE_OMIT_EXPLAIN
|
||||||
|
SQLITE_OMIT_FLAG_PRAGMAS
|
||||||
|
SQLITE_OMIT_FLOATING_POINT
|
||||||
|
SQLITE_OMIT_FOREIGN_KEY
|
||||||
|
SQLITE_OMIT_GENERATED_COLUMNS
|
||||||
|
SQLITE_OMIT_GET_TABLE
|
||||||
|
SQLITE_OMIT_HEX_INTEGER
|
||||||
|
SQLITE_OMIT_INCRBLOB
|
||||||
|
SQLITE_OMIT_INTEGRITY_CHECK
|
||||||
|
SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||||
|
SQLITE_OMIT_JSON
|
||||||
|
SQLITE_OMIT_LIKE_OPTIMIZATION
|
||||||
|
SQLITE_OMIT_LOAD_EXTENSION
|
||||||
|
SQLITE_OMIT_LOCALTIME
|
||||||
|
SQLITE_OMIT_LOOKASIDE
|
||||||
|
SQLITE_OMIT_MEMORYDB
|
||||||
|
SQLITE_OMIT_OR_OPTIMIZATION
|
||||||
|
SQLITE_OMIT_PAGER_PRAGMAS
|
||||||
|
SQLITE_OMIT_PARSER_TRACE
|
||||||
|
SQLITE_OMIT_POPEN
|
||||||
|
SQLITE_OMIT_PRAGMA
|
||||||
|
SQLITE_OMIT_PROGRESS_CALLBACK
|
||||||
|
SQLITE_OMIT_QUICKBALANCE
|
||||||
|
SQLITE_OMIT_RANDOMNESS
|
||||||
|
SQLITE_OMIT_REINDEX
|
||||||
|
SQLITE_OMIT_SCHEMA_PRAGMAS
|
||||||
|
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
|
||||||
|
SQLITE_OMIT_SHARED_CACHE
|
||||||
|
SQLITE_OMIT_SHUTDOWN_DIRECTORIES
|
||||||
|
SQLITE_OMIT_SUBQUERY
|
||||||
|
SQLITE_OMIT_TCL_VARIABLE
|
||||||
|
SQLITE_OMIT_TEMPDB
|
||||||
|
SQLITE_OMIT_TEST_CONTROL
|
||||||
|
SQLITE_OMIT_TRACE
|
||||||
|
SQLITE_OMIT_TRIGGER
|
||||||
|
SQLITE_OMIT_TRUNCATE_OPTIMIZATION
|
||||||
|
SQLITE_OMIT_TWOSIZE_LOOKASIDE
|
||||||
|
SQLITE_OMIT_UPSERT
|
||||||
|
SQLITE_OMIT_UTF
|
||||||
|
SQLITE_OMIT_VACUUM
|
||||||
|
SQLITE_OMIT_VIEW
|
||||||
|
SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
SQLITE_OMIT_WAL
|
||||||
|
SQLITE_OMIT_WINDOWFUNC
|
||||||
|
SQLITE_OMIT_WSD
|
||||||
|
SQLITE_OMIT_XFER_OPT
|
||||||
|
SQLITE_ALLOW_ROWID_IN_VIEW
|
||||||
|
SQLITE_DISABLE_DIRSYNC
|
||||||
|
SQLITE_DISABLE_FTS
|
||||||
|
SQLITE_DISABLE_INTRINSIC
|
||||||
|
SQLITE_DISABLE_LFS
|
||||||
|
SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||||
|
SQLITE_DISABLE_SKIPAHEAD_DISTINCT
|
||||||
|
SQLITE_ENABLE_API_ARMOR
|
||||||
|
SQLITE_ENABLE_ATOMIC_WRITE
|
||||||
|
SQLITE_ENABLE_BATCH_ATOMIC_WRITE
|
||||||
|
SQLITE_ENABLE_BYTECODE_VTAB
|
||||||
|
SQLITE_ENABLE_CEROD
|
||||||
|
SQLITE_ENABLE_COLUMN_METADATA
|
||||||
|
SQLITE_ENABLE_COLUMN_USED_MASK
|
||||||
|
SQLITE_ENABLE_COMMENTS
|
||||||
|
SQLITE_ENABLE_CORRUPT_PGNO
|
||||||
|
SQLITE_ENABLE_COSTMULT
|
||||||
|
SQLITE_ENABLE_CURSOR_HINTS
|
||||||
|
SQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
|
SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||||
|
SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||||
|
SQLITE_ENABLE_FTS
|
||||||
|
SQLITE_ENABLE_GEOPOLY
|
||||||
|
SQLITE_ENABLE_HIDDEN_COLUMNS
|
||||||
|
SQLITE_ENABLE_ICU
|
||||||
|
SQLITE_ENABLE_ICU_COLLATIONS
|
||||||
|
SQLITE_ENABLE_INTERNAL_FUNCTIONS
|
||||||
|
SQLITE_ENABLE_IOTRACE
|
||||||
|
SQLITE_ENABLE_LOAD_EXTENSION
|
||||||
|
SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
SQLITE_ENABLE_MATH_FUNCTIONS
|
||||||
|
SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||||
|
SQLITE_ENABLE_MEMSYS
|
||||||
|
SQLITE_ENABLE_MODULE_COMMENTS
|
||||||
|
SQLITE_ENABLE_MULTIPLEX
|
||||||
|
SQLITE_ENABLE_MULTITHREADED_CHECKS
|
||||||
|
SQLITE_ENABLE_NORMALIZE
|
||||||
|
SQLITE_ENABLE_NULL_TRIM
|
||||||
|
SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||||
|
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||||
|
SQLITE_ENABLE_PREUPDATE_HOOK
|
||||||
|
SQLITE_ENABLE_QPSG
|
||||||
|
SQLITE_ENABLE_RBU
|
||||||
|
SQLITE_ENABLE_RTREE
|
||||||
|
SQLITE_ENABLE_SELECTTRACE
|
||||||
|
SQLITE_ENABLE_SESSION
|
||||||
|
SQLITE_ENABLE_SETLK_TIMEOUT
|
||||||
|
SQLITE_ENABLE_SNAPSHOT
|
||||||
|
SQLITE_ENABLE_SORTER_MMAP
|
||||||
|
SQLITE_ENABLE_SORTER_REFERENCE
|
||||||
|
SQLITE_ENABLE_SORTER_REFERENCES
|
||||||
|
SQLITE_ENABLE_SQLLOG
|
||||||
|
SQLITE_ENABLE_STAT
|
||||||
|
SQLITE_ENABLE_STMT_SCANSTATUS
|
||||||
|
SQLITE_ENABLE_STMTVTAB
|
||||||
|
SQLITE_ENABLE_TREETRACE
|
||||||
|
SQLITE_ENABLE_UNKNOWN_FUNCTION
|
||||||
|
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||||
|
SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
|
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||||
|
SQLITE_ENABLE_URI_00_ERROR
|
||||||
|
SQLITE_ENABLE_VFSTRACE
|
||||||
|
SQLITE_ENABLE_WHERETRACE
|
||||||
|
SQLITE_ENABLE_ZIPVFS
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command-line options.
|
||||||
#
|
#
|
||||||
|
for {set i 0} {$i<[llength $argv]} {incr i} {
|
||||||
|
set arg [lindex $argv $i]
|
||||||
|
switch -- $arg {
|
||||||
|
-start -
|
||||||
|
--start {
|
||||||
|
incr i
|
||||||
|
set startat [lindex $argv $i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Additional options required for some settings.
|
||||||
#
|
#
|
||||||
proc run_quick_test {dir omit_symbol_list} {
|
set More(SQLITE_OMIT_DISKIO) {-DSQLITE_OMIT_WAL}
|
||||||
# Compile the value of the OPTS Makefile variable.
|
|
||||||
set opts ""
|
|
||||||
if {$::tcl_platform(platform)=="windows"} {
|
|
||||||
append opts "OPTS += -DSQLITE_OS_WIN=1\n"
|
|
||||||
set target "testfixture.exe"
|
|
||||||
} else {
|
|
||||||
append opts "OPTS += -DSQLITE_OS_UNIX=1\n"
|
|
||||||
}
|
|
||||||
foreach sym $omit_symbol_list {
|
|
||||||
append opts "OPTS += -D${sym}=1\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create the directory and do the build. If an error occurs return
|
# Compile-time options for Mac only
|
||||||
# early without attempting to run the test suite.
|
#
|
||||||
file mkdir $dir
|
set MacOnly(SQLITE_ENABLE_LOCKING_STYLE) 1
|
||||||
puts -nonewline "Building $dir..."
|
|
||||||
flush stdout
|
|
||||||
catch {
|
|
||||||
file copy -force ./config.h $dir
|
|
||||||
file copy -force ./libtool $dir
|
|
||||||
}
|
|
||||||
set fd [open $::MAKEFILE]
|
|
||||||
set mkfile [read $fd]
|
|
||||||
close $fd
|
|
||||||
regsub {\ninclude} $mkfile "\n$opts\ninclude" mkfile
|
|
||||||
set fd [open $dir/makefile w]
|
|
||||||
puts $fd $mkfile
|
|
||||||
close $fd
|
|
||||||
|
|
||||||
set rc [catch {
|
# Compile-time options that might fail, depending on what libraries
|
||||||
exec $::MAKEBIN -C $dir -f makefile clean $::TARGET >& $dir/build.log
|
# are installed. Failures on these tests issue a warning, but testing
|
||||||
}]
|
# continues.
|
||||||
if {$rc} {
|
#
|
||||||
puts "No good. See $dir/build.log."
|
set FailIsOk(SQLITE_ENABLE_ICU) 1
|
||||||
return
|
set FailIsOk(SQLITE_ENABLE_ICU_COLLATIONS) 1
|
||||||
} else {
|
|
||||||
puts "Ok"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create an empty file "$dir/sqlite3". This is to trick the makefile out
|
file mkdir omittest
|
||||||
# of trying to build the sqlite shell. The sqlite shell won't build
|
foreach sym $CompileOptionsToTest {
|
||||||
# with some of the OMIT options (i.e OMIT_COMPLETE).
|
if {[info exists startat]} {
|
||||||
set sqlite3_dummy $dir/sqlite3
|
if {$startat==$sym} {
|
||||||
if {$::tcl_platform(platform)=="windows"} {
|
unset startat
|
||||||
append sqlite3_dummy ".exe"
|
|
||||||
}
|
|
||||||
if {![file exists $sqlite3_dummy]} {
|
|
||||||
set wr [open $sqlite3_dummy w]
|
|
||||||
puts $wr "dummy"
|
|
||||||
close $wr
|
|
||||||
}
|
|
||||||
|
|
||||||
if {$::SKIP_RUN} {
|
|
||||||
# puts "Skip testing $dir."
|
|
||||||
} else {
|
|
||||||
# Run the test suite.
|
|
||||||
puts -nonewline "Testing $dir..."
|
|
||||||
flush stdout
|
|
||||||
set rc [catch {
|
|
||||||
exec $::MAKEBIN -C $dir -f makefile test >& $dir/test.log
|
|
||||||
}]
|
|
||||||
if {$rc} {
|
|
||||||
puts "No good. See $dir/test.log."
|
|
||||||
} else {
|
} else {
|
||||||
puts "Ok"
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if {[info exists MacOnly($sym)] && $tcl_platform(os)!="Darwin"} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
# This proc processes the command line options passed to this script.
|
set logfile "omittest/$sym.log"
|
||||||
# Currently the only option supported is "-makefile", default
|
if {[info exists More($sym)]} {
|
||||||
# "../Makefile.linux-gcc". Set the ::MAKEFILE variable to the value of this
|
append opts "OPT_FEATURE_FLAGS=-D$sym $More($sym)"
|
||||||
# option.
|
|
||||||
#
|
|
||||||
proc process_options {argv} {
|
|
||||||
set ::MAKEBIN make ;# Default value
|
|
||||||
if {$::tcl_platform(platform)=="windows"} {
|
|
||||||
set ::MAKEFILE ./Makefile ;# Default value on Windows
|
|
||||||
} else {
|
} else {
|
||||||
set ::MAKEFILE ./Makefile.linux-gcc ;# Default value
|
set opts OPT_FEATURE_FLAGS=-D$sym
|
||||||
}
|
}
|
||||||
set ::SKIP_RUN 1 ;# Default to attempt test
|
puts "make tidy sqlite3.lo $opts"
|
||||||
set ::TARGET testfixture ;# Default thing to build
|
if {[catch {exec make tidy sqlite3.lo $opts >& $logfile}]} {
|
||||||
|
puts "BUILD FAILED: see $logfile for details"
|
||||||
for {set i 0} {$i < [llength $argv]} {incr i} {
|
if {[info exists FailIsOk($sym)]} {
|
||||||
switch -regexp -- [lindex $argv $i] {
|
set Failure($sym) 1
|
||||||
-{1,2}makefile {
|
} else {
|
||||||
incr i
|
puts "Note: After fixes, continue the test using:\n"
|
||||||
set ::MAKEFILE [lindex $argv $i]
|
puts " [info nameofexe] $argv0 --start $sym\n"
|
||||||
}
|
exit 1
|
||||||
|
|
||||||
-{1,2}nmake {
|
|
||||||
set ::MAKEBIN nmake
|
|
||||||
set ::MAKEFILE ./Makefile.msc
|
|
||||||
}
|
|
||||||
|
|
||||||
-{1,2}target {
|
|
||||||
incr i
|
|
||||||
set ::TARGET [lindex $argv $i]
|
|
||||||
}
|
|
||||||
|
|
||||||
-{1,2}skip_run {
|
|
||||||
set ::SKIP_RUN 1
|
|
||||||
}
|
|
||||||
-{1,2}run {
|
|
||||||
set ::SKIP_RUN 0
|
|
||||||
}
|
|
||||||
|
|
||||||
-{1,2}help {
|
|
||||||
puts $::USAGE_MESSAGE
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
-.* {
|
|
||||||
puts stderr "Unknown option: [lindex $argv i]"
|
|
||||||
puts stderr $::USAGE_MESSAGE
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
default {
|
|
||||||
if {[info exists ::SYMBOL]} {
|
|
||||||
puts stderr [string trim $::USAGE_MESSAGE]
|
|
||||||
exit -1
|
|
||||||
}
|
|
||||||
set ::SYMBOL [lindex $argv $i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set ::MAKEFILE [file normalize $::MAKEFILE]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main routine.
|
|
||||||
#
|
|
||||||
|
|
||||||
proc main {argv} {
|
|
||||||
# List of SQLITE_OMIT_XXX symbols supported by SQLite.
|
|
||||||
set ::OMIT_SYMBOLS [list \
|
|
||||||
SQLITE_OMIT_ALTERTABLE \
|
|
||||||
SQLITE_OMIT_ANALYZE \
|
|
||||||
SQLITE_OMIT_ATTACH \
|
|
||||||
SQLITE_OMIT_AUTHORIZATION \
|
|
||||||
SQLITE_OMIT_AUTOINCREMENT \
|
|
||||||
SQLITE_OMIT_AUTOINIT \
|
|
||||||
SQLITE_OMIT_AUTOMATIC_INDEX \
|
|
||||||
SQLITE_OMIT_AUTORESET \
|
|
||||||
SQLITE_OMIT_AUTOVACUUM \
|
|
||||||
SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS \
|
|
||||||
SQLITE_OMIT_BETWEEN_OPTIMIZATION \
|
|
||||||
SQLITE_OMIT_BLOB_LITERAL \
|
|
||||||
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
|
|
||||||
SQLITE_OMIT_CAST \
|
|
||||||
SQLITE_OMIT_CHECK \
|
|
||||||
SQLITE_OMIT_COMPILEOPTION_DIAGS \
|
|
||||||
SQLITE_OMIT_COMPLETE \
|
|
||||||
SQLITE_OMIT_COMPOUND_SELECT \
|
|
||||||
SQLITE_OMIT_CONFLICT_CLAUSE \
|
|
||||||
SQLITE_OMIT_CTE \
|
|
||||||
SQLITE_OMIT_DATETIME_FUNCS \
|
|
||||||
SQLITE_OMIT_DECLTYPE \
|
|
||||||
SQLITE_OMIT_DEPRECATED \
|
|
||||||
SQLITE_OMIT_DESERIALIZE \
|
|
||||||
SQLITE_OMIT_DISKIO \
|
|
||||||
SQLITE_OMIT_EXPLAIN \
|
|
||||||
SQLITE_OMIT_FLAG_PRAGMAS \
|
|
||||||
SQLITE_OMIT_FLOATING_POINT \
|
|
||||||
SQLITE_OMIT_FOREIGN_KEY \
|
|
||||||
SQLITE_OMIT_GENERATED_COLUMNS \
|
|
||||||
SQLITE_OMIT_GET_TABLE \
|
|
||||||
SQLITE_OMIT_HEX_INTEGER \
|
|
||||||
SQLITE_OMIT_INCRBLOB \
|
|
||||||
SQLITE_OMIT_INTEGRITY_CHECK \
|
|
||||||
SQLITE_OMIT_INTROSPECTION_PRAGMAS \
|
|
||||||
SQLITE_OMIT_JSON \
|
|
||||||
SQLITE_OMIT_LIKE_OPTIMIZATION \
|
|
||||||
SQLITE_OMIT_LOAD_EXTENSION \
|
|
||||||
SQLITE_OMIT_LOCALTIME \
|
|
||||||
SQLITE_OMIT_LOOKASIDE \
|
|
||||||
SQLITE_OMIT_MEMORYDB \
|
|
||||||
SQLITE_OMIT_OR_OPTIMIZATION \
|
|
||||||
SQLITE_OMIT_PAGER_PRAGMAS \
|
|
||||||
SQLITE_OMIT_PARSER_TRACE \
|
|
||||||
SQLITE_OMIT_POPEN \
|
|
||||||
SQLITE_OMIT_PRAGMA \
|
|
||||||
SQLITE_OMIT_PROGRESS_CALLBACK \
|
|
||||||
SQLITE_OMIT_QUICKBALANCE \
|
|
||||||
SQLITE_OMIT_RANDOMNESS \
|
|
||||||
SQLITE_OMIT_REINDEX \
|
|
||||||
SQLITE_OMIT_SCHEMA_PRAGMAS \
|
|
||||||
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
|
|
||||||
SQLITE_OMIT_SHARED_CACHE \
|
|
||||||
SQLITE_OMIT_SHUTDOWN_DIRECTORIES \
|
|
||||||
SQLITE_OMIT_SUBQUERY \
|
|
||||||
SQLITE_OMIT_TCL_VARIABLE \
|
|
||||||
SQLITE_OMIT_TEMPDB \
|
|
||||||
SQLITE_OMIT_TEST_CONTROL \
|
|
||||||
SQLITE_OMIT_TRACE \
|
|
||||||
SQLITE_OMIT_TRIGGER \
|
|
||||||
SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
|
|
||||||
SQLITE_OMIT_TWOSIZE_LOOKASIDE \
|
|
||||||
SQLITE_OMIT_UPSERT \
|
|
||||||
SQLITE_OMIT_UTF \
|
|
||||||
SQLITE_OMIT_VACUUM \
|
|
||||||
SQLITE_OMIT_VIEW \
|
|
||||||
SQLITE_OMIT_VIRTUALTABLE \
|
|
||||||
SQLITE_OMIT_WAL \
|
|
||||||
SQLITE_OMIT_WINDOWFUNC \
|
|
||||||
SQLITE_OMIT_WSD \
|
|
||||||
SQLITE_OMIT_XFER_OPT \
|
|
||||||
]
|
|
||||||
|
|
||||||
set ::ENABLE_SYMBOLS [list \
|
|
||||||
SQLITE_ALLOW_ROWID_IN_VIEW \
|
|
||||||
SQLITE_DISABLE_DIRSYNC \
|
|
||||||
SQLITE_DISABLE_FTS \
|
|
||||||
SQLITE_DISABLE_INTRINSIC \
|
|
||||||
SQLITE_DISABLE_LFS \
|
|
||||||
SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS \
|
|
||||||
SQLITE_DISABLE_SKIPAHEAD_DISTINCT \
|
|
||||||
SQLITE_ENABLE_API_ARMOR \
|
|
||||||
SQLITE_ENABLE_ATOMIC_WRITE \
|
|
||||||
SQLITE_ENABLE_BATCH_ATOMIC_WRITE \
|
|
||||||
SQLITE_ENABLE_BYTECODE_VTAB \
|
|
||||||
SQLITE_ENABLE_CEROD \
|
|
||||||
SQLITE_ENABLE_COLUMN_METADATA \
|
|
||||||
SQLITE_ENABLE_COLUMN_USED_MASK \
|
|
||||||
SQLITE_ENABLE_COMMENTS \
|
|
||||||
SQLITE_ENABLE_CORRUPT_PGNO \
|
|
||||||
SQLITE_ENABLE_COSTMULT \
|
|
||||||
SQLITE_ENABLE_CURSOR_HINTS \
|
|
||||||
SQLITE_ENABLE_DBPAGE_VTAB \
|
|
||||||
SQLITE_ENABLE_DBSTAT_VTAB \
|
|
||||||
SQLITE_ENABLE_EXPENSIVE_ASSERT \
|
|
||||||
SQLITE_ENABLE_EXPLAIN_COMMENTS \
|
|
||||||
SQLITE_ENABLE_FTS \
|
|
||||||
SQLITE_ENABLE_GEOPOLY \
|
|
||||||
SQLITE_ENABLE_HIDDEN_COLUMNS \
|
|
||||||
SQLITE_ENABLE_ICU \
|
|
||||||
SQLITE_ENABLE_ICU_COLLATIONS \
|
|
||||||
SQLITE_ENABLE_INTERNAL_FUNCTIONS \
|
|
||||||
SQLITE_ENABLE_IOTRACE \
|
|
||||||
SQLITE_ENABLE_LOAD_EXTENSION \
|
|
||||||
SQLITE_ENABLE_LOCKING_STYLE \
|
|
||||||
SQLITE_ENABLE_MATH_FUNCTIONS \
|
|
||||||
SQLITE_ENABLE_MEMORY_MANAGEMENT \
|
|
||||||
SQLITE_ENABLE_MEMSYS \
|
|
||||||
SQLITE_ENABLE_MODULE_COMMENTS \
|
|
||||||
SQLITE_ENABLE_MULTIPLEX \
|
|
||||||
SQLITE_ENABLE_MULTITHREADED_CHECKS \
|
|
||||||
SQLITE_ENABLE_NORMALIZE \
|
|
||||||
SQLITE_ENABLE_NULL_TRIM \
|
|
||||||
SQLITE_ENABLE_OFFSET_SQL_FUNC \
|
|
||||||
SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
|
|
||||||
SQLITE_ENABLE_PREUPDATE_HOOK \
|
|
||||||
SQLITE_ENABLE_QPSG \
|
|
||||||
SQLITE_ENABLE_RBU \
|
|
||||||
SQLITE_ENABLE_RTREE \
|
|
||||||
SQLITE_ENABLE_SELECTTRACE \
|
|
||||||
SQLITE_ENABLE_SESSION \
|
|
||||||
SQLITE_ENABLE_SETLK_TIMEOUT \
|
|
||||||
SQLITE_ENABLE_SNAPSHOT \
|
|
||||||
SQLITE_ENABLE_SORTER_MMAP\
|
|
||||||
SQLITE_ENABLE_SORTER_REFERENCE \
|
|
||||||
SQLITE_ENABLE_SORTER_REFERENCES \
|
|
||||||
SQLITE_ENABLE_SQLLOG\
|
|
||||||
SQLITE_ENABLE_STAT \
|
|
||||||
SQLITE_ENABLE_STMT_SCANSTATUS \
|
|
||||||
SQLITE_ENABLE_STMTVTAB \
|
|
||||||
SQLITE_ENABLE_TREETRACE \
|
|
||||||
SQLITE_ENABLE_UNKNOWN_FUNCTION \
|
|
||||||
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \
|
|
||||||
SQLITE_ENABLE_UNLOCK_NOTIFY \
|
|
||||||
SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
|
|
||||||
SQLITE_ENABLE_URI_00_ERROR \
|
|
||||||
SQLITE_ENABLE_VFSTRACE \
|
|
||||||
SQLITE_ENABLE_WHERETRACE \
|
|
||||||
SQLITE_ENABLE_ZIPVFS \
|
|
||||||
]
|
|
||||||
|
|
||||||
# Process any command line options.
|
|
||||||
process_options $argv
|
|
||||||
|
|
||||||
if {[info exists ::SYMBOL] } {
|
|
||||||
set sym $::SYMBOL
|
|
||||||
|
|
||||||
if {[lsearch $::OMIT_SYMBOLS $sym]<0 && [lsearch $::ENABLE_SYMBOLS $sym]<0} {
|
|
||||||
puts stderr "No such symbol: $sym"
|
|
||||||
exit -1
|
|
||||||
}
|
|
||||||
|
|
||||||
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
|
|
||||||
run_quick_test $dirname $sym
|
|
||||||
} else {
|
|
||||||
# First try a test with all OMIT symbols except SQLITE_OMIT_FLOATING_POINT
|
|
||||||
# and SQLITE_OMIT_PRAGMA defined. The former doesn't work (causes segfaults)
|
|
||||||
# and the latter is currently incompatible with the test suite (this should
|
|
||||||
# be fixed, but it will be a lot of work).
|
|
||||||
set allsyms [list]
|
|
||||||
foreach s $::OMIT_SYMBOLS {
|
|
||||||
if {$s!="SQLITE_OMIT_FLOATING_POINT" && $s!="SQLITE_OMIT_PRAGMA"} {
|
|
||||||
lappend allsyms $s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run_quick_test test_OMIT_EVERYTHING $allsyms
|
|
||||||
|
|
||||||
# Now try one quick.test with each of the OMIT symbols defined. Included
|
|
||||||
# are the OMIT_FLOATING_POINT and OMIT_PRAGMA symbols, even though we
|
|
||||||
# know they will fail. It's good to be reminded of this from time to time.
|
|
||||||
foreach sym $::OMIT_SYMBOLS {
|
|
||||||
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
|
|
||||||
run_quick_test $dirname $sym
|
|
||||||
}
|
|
||||||
|
|
||||||
# Try the ENABLE/DISABLE symbols one at a time.
|
|
||||||
# We don't do them all at once since some are conflicting.
|
|
||||||
foreach sym $::ENABLE_SYMBOLS {
|
|
||||||
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
|
|
||||||
run_quick_test $dirname $sym
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if {[llength [array names Failure]]>0} {
|
||||||
main $argv
|
puts "BUILD FAILED on the following:"
|
||||||
|
foreach sym [array names Failure] {
|
||||||
|
puts " * $sym"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user