Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d281889ac8 | |||
| a955ec806a | |||
| b5df31d15f | |||
| b9a6e42a55 | |||
| 1c30df3598 | |||
| ca447020ae | |||
| 7aa01a0ffc | |||
| 5d5d6194c9 | |||
| c97ad9b4e1 | |||
| 41155d8885 | |||
| df2d14b86e | |||
| a239ece378 | |||
| c1042cd133 | |||
| 65b1244781 | |||
| 49af3dfbf4 | |||
| a5315a6ece | |||
| f138110dfd | |||
| ad8ec9db63 | |||
| 129767958a | |||
| 90fa4c7b2c | |||
| 3196c349d1 | |||
| 0337b9a628 | |||
| 6cb12337b9 | |||
| c589d5ab06 | |||
| 28db1a68ba | |||
| 11397ce104 | |||
| 494ba30c9b | |||
| 6a18c9e06a | |||
| ccd34894e1 | |||
| c1547d1f7a | |||
| 50ca8af6f2 | |||
| 8db3fc5488 | |||
| ba5994b181 | |||
| 3341f5ce85 | |||
| d6b56d65a8 | |||
| 4f2f91bf08 | |||
| 242e064978 | |||
| 4a90f81a6d | |||
| a88d61824d | |||
| af43eddc23 | |||
| b5b4ca2a11 | |||
| c3c645ef46 | |||
| f5a9b58c8b | |||
| ce018f5bb3 |
+54
-43
@@ -83,9 +83,13 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
|
||||
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
|
||||
# The same set of OMIT and ENABLE flags should be passed to the
|
||||
# LEMON parser generator and the mkkeywordhash tool as well.
|
||||
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
|
||||
#
|
||||
# Add OPTIONS=... on the command line to append additional options
|
||||
# to the OPT_FEATURE_FLAGS.
|
||||
#
|
||||
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS)
|
||||
|
||||
TCC += $(OPT_FEATURE_FLAGS)
|
||||
TCC += $(OPT_FEATURE_FLAGS)
|
||||
|
||||
# Add in any optional parameters specified on the make commane line
|
||||
# ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
|
||||
@@ -646,6 +650,7 @@ FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
|
||||
FUZZCHECK_SRC += $(TOP)/test/vt02.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c
|
||||
FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c
|
||||
DBFUZZ_OPT =
|
||||
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
|
||||
@@ -1178,6 +1183,7 @@ SHELL_DEP = \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
$(TOP)/ext/misc/memtrace.c \
|
||||
$(TOP)/ext/misc/pcachetrace.c \
|
||||
$(TOP)/ext/misc/percentile.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
$(TOP)/ext/misc/series.c \
|
||||
$(TOP)/ext/misc/shathree.c \
|
||||
@@ -1363,9 +1369,14 @@ tcltest: ./testfixture$(TEXE)
|
||||
testrunner: testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl
|
||||
|
||||
# Runs both fuzztest and testrunner, consecutively.
|
||||
# This is the testing target preferred by the core SQLite developers.
|
||||
# It runs tests under a standard configuration, regardless of how
|
||||
# ./configure was run. The devs run "make devtest" prior to each
|
||||
# check-in, at a minimum. Probably other tests too, but at least this
|
||||
# one.
|
||||
#
|
||||
devtest: srctree-check testfixture$(TEXE) fuzztest testrunner
|
||||
devtest: srctree-check sourcetest
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS)
|
||||
|
||||
mdevtest: srctree-check has_tclsh85
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS)
|
||||
@@ -1381,16 +1392,19 @@ srctree-check: $(TOP)/tool/srctree-check.tcl
|
||||
|
||||
# Testing for a release
|
||||
#
|
||||
releasetest: srctree-check testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
|
||||
releasetest: srctree-check has_tclsh85 verify-source
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes
|
||||
#
|
||||
quicktest: ./testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS)
|
||||
|
||||
# This is the common case. Run many tests that do not take too long,
|
||||
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
|
||||
# Try to run tests on whatever options are specified by the
|
||||
# ./configure. The developers seldom use this target. Instead
|
||||
# they use "make devtest" which runs tests on a standard set of
|
||||
# options regardless of how SQLite is configured. This "test"
|
||||
# target is provided for legacy only.
|
||||
#
|
||||
test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest
|
||||
|
||||
@@ -1407,8 +1421,8 @@ valgrindtest: $(TESTPROGS) valgrindfuzz
|
||||
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
|
||||
|
||||
shelltest: $(TESTPROGS)
|
||||
./testfixture$(TEXT) $(TOP)/test/permutations.test shell
|
||||
shelltest:
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85
|
||||
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
|
||||
@@ -1594,43 +1608,40 @@ tclextension-uninstall:
|
||||
tclextension-list:
|
||||
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info
|
||||
|
||||
clean:
|
||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
||||
rm -f sqlite3.h opcodes.*
|
||||
rm -rf .libs .deps
|
||||
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
|
||||
rm -f mkkeywordhash$(BEXE) keywordhash.h
|
||||
rm -f mksourceid$(BEXE)
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf tsrc .target_source
|
||||
rm -f tclsqlite3$(TEXE)
|
||||
rm -f testfixture$(TEXE) test.db
|
||||
|
||||
# Remove build products sufficient so that subsequent makes will recompile
|
||||
# everything from scratch. Do not remove:
|
||||
#
|
||||
# * test results and test logs
|
||||
# * output from ./configure
|
||||
#
|
||||
tidy:
|
||||
rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
|
||||
rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h
|
||||
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 showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
||||
rm -f wordcount$(TEXE) changeset$(TEXE)
|
||||
rm -f version-info$(TEXT)
|
||||
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
|
||||
rm -f sqlite3.c
|
||||
rm -f sqlite3rc.h
|
||||
rm -f shell.c sqlite3ext.h
|
||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
||||
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
|
||||
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
|
||||
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
|
||||
rm -f sqlite3_analyzer$(TEXE)
|
||||
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
|
||||
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
|
||||
rm -f threadtest5$(TEXE)
|
||||
rm -f src-verify has_tclsh*
|
||||
|
||||
# Removes build products and test logs. Retains ./configure outputs.
|
||||
#
|
||||
clean: tidy
|
||||
rm -rf omittest* testrunner* testdir*
|
||||
|
||||
# Clean up everything. No exceptions.
|
||||
#
|
||||
distclean: clean
|
||||
rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \
|
||||
$(TESTPROGS)
|
||||
rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL)
|
||||
|
||||
#
|
||||
# Windows section
|
||||
|
||||
+32
-5
@@ -379,6 +379,7 @@ SQLITE_TCL_DEP =
|
||||
# the Windows platform.
|
||||
#
|
||||
!IFNDEF OPT_FEATURE_FLAGS
|
||||
OPT_FEATURE_FLAGS = $(OPT_XTRA)
|
||||
!IF $(MINIMAL_AMALGAMATION)==0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1
|
||||
@@ -392,6 +393,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
!ENDIF
|
||||
|
||||
# Additional feature-options above and beyond what are normally used can be
|
||||
# be added using OPTIONS=.... on the command-line. These values are
|
||||
# appended to the OPT_FEATURE_FLAGS variable.
|
||||
#
|
||||
!IFDEF OPTIONS
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) $(OPTIONS)
|
||||
!ENDIF
|
||||
|
||||
# Should the session extension be enabled? If so, add compilation options
|
||||
# to enable it.
|
||||
#
|
||||
@@ -1758,6 +1767,7 @@ FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.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\sqlite3recover.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\percentile.c
|
||||
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
|
||||
|
||||
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
||||
@@ -2304,6 +2314,7 @@ SHELL_DEP = \
|
||||
$(TOP)\ext\misc\ieee754.c \
|
||||
$(TOP)\ext\misc\memtrace.c \
|
||||
$(TOP)\ext\misc\pcachetrace.c \
|
||||
$(TOP)\ext\misc\percentile.c \
|
||||
$(TOP)\ext\misc\regexp.c \
|
||||
$(TOP)\ext\misc\series.c \
|
||||
$(TOP)\ext\misc\shathree.c \
|
||||
@@ -2535,6 +2546,13 @@ queryplantest: testfixture.exe shell
|
||||
fuzztest: fuzzcheck.exe
|
||||
.\fuzzcheck.exe $(FUZZDATA)
|
||||
|
||||
# Legacy testing target for third-party integrators. The SQLite
|
||||
# developers seldom use this target themselves. Instead
|
||||
# they use "nmake /f Makefile.msc devtest" which runs tests on
|
||||
# a standard set of options
|
||||
#
|
||||
test: $(TESTPROGS) sourcetest fuzztest tcltest
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes (on a fast machine)
|
||||
#
|
||||
quicktest: testfixture.exe sourcetest
|
||||
@@ -2544,7 +2562,6 @@ quicktest: testfixture.exe sourcetest
|
||||
# This is the common case. Run many tests that do not take too long,
|
||||
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
|
||||
#
|
||||
test: $(TESTPROGS) sourcetest fuzztest tcltest
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
#
|
||||
@@ -2558,17 +2575,27 @@ tcltest: testfixture.exe
|
||||
testrunner: testfixture.exe
|
||||
.\testfixture.exe $(TOP)\test\testrunner.tcl
|
||||
|
||||
# Runs both fuzztest and testrunner, consecutively.
|
||||
# This is the testing target preferred by the core SQLite developers.
|
||||
# It runs tests under a standard configuration. The devs run
|
||||
# "nmake /f Makefile.msc devtest" prior to each check-in, at a minimum.
|
||||
# Probably other tests too, but at least this one.
|
||||
#
|
||||
devtest: testfixture.exe fuzztest testrunner
|
||||
devtest: srctree-check sourcetest
|
||||
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
|
||||
|
||||
mdevtest:
|
||||
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
|
||||
|
||||
# Validate that various generated files in the source tree
|
||||
# are up-to-date.
|
||||
#
|
||||
srctree-check: $(TOP)\tool\srctree-check.tcl
|
||||
$(TCLSH_CMD) $(TOP)\tool\srctree-check.tcl
|
||||
|
||||
# Testing for a release
|
||||
#
|
||||
releasetest: testfixture.exe
|
||||
testfixture.exe $(TOP)\test\testrunner.tcl release
|
||||
releasetest:
|
||||
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release
|
||||
|
||||
|
||||
smoketest: $(TESTPROGS)
|
||||
|
||||
@@ -109,7 +109,7 @@ For example:
|
||||
../sqlite/configure ;# Run the configure script
|
||||
make sqlite3 ;# Builds the "sqlite3" command-line tool
|
||||
make sqlite3.c ;# Build the "amalgamation" source file
|
||||
make mdevtest ;# Run development tests (requires tcl-dev)
|
||||
make devtest ;# Run development tests (requires tcl-dev)
|
||||
make releasetest ;# Run full release tests (requires tcl-dev)
|
||||
make sqldiff ;# Builds the "sqldiff" command-line tool
|
||||
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool (requires tcl-dev)
|
||||
@@ -128,6 +128,13 @@ Almost all makefile targets require a "tclsh" TCL interpreter
|
||||
version 8.6 or later. The targets marked with "(requires tcl-dev)" also require
|
||||
the TCL development libraries.
|
||||
|
||||
On "make" command-lines, one can add "OPTIONS=..." to specify additional
|
||||
compile-time options over and above those set by ./configure. For example,
|
||||
to compile with the SQLITE_OMIT_DEPRECATED compile-time option, one could say:
|
||||
|
||||
./configure --enable-all
|
||||
make OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3
|
||||
|
||||
The configure script uses autoconf 2.61 and libtool. If the configure
|
||||
script does not work out for you, there is a generic makefile named
|
||||
"Makefile.linux-gcc" in the top directory of the source tree that you
|
||||
@@ -156,13 +163,18 @@ Build using Makefile.msc. Example:
|
||||
|
||||
nmake /f Makefile.msc sqlite3.exe
|
||||
nmake /f Makefile.msc sqlite3.c
|
||||
nmake /f Makefile.msc mdevtest
|
||||
nmake /f Makefile.msc devtest
|
||||
nmake /f Makefile.msc releasetest
|
||||
nmake /f Makefile.msc tclextension-install
|
||||
|
||||
There are many other makefile targets. See comments in Makefile.msc for
|
||||
details.
|
||||
|
||||
As with the unix Makefile, the OPTIONS=... argument can be passed on the nmake
|
||||
command-line to enable new compile-time options. For example:
|
||||
|
||||
nmake /f Makefile.msc OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3.exe
|
||||
|
||||
## Source Tree Map
|
||||
|
||||
* **src/** - This directory contains the primary source code for the
|
||||
|
||||
@@ -301,6 +301,7 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
|
||||
# the Windows platform.
|
||||
#
|
||||
!IFNDEF OPT_FEATURE_FLAGS
|
||||
OPT_FEATURE_FLAGS = $(OPT_XTRA)
|
||||
!IF $(MINIMAL_AMALGAMATION)==0
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1
|
||||
@@ -314,6 +315,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
!ENDIF
|
||||
|
||||
# Additional feature-options above and beyond what are normally used can be
|
||||
# be added using OPTIONS=.... on the command-line. These values are
|
||||
# appended to the OPT_FEATURE_FLAGS variable.
|
||||
#
|
||||
!IFDEF OPTIONS
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) $(OPTIONS)
|
||||
!ENDIF
|
||||
|
||||
# Should the session extension be enabled? If so, add compilation options
|
||||
# to enable it.
|
||||
#
|
||||
|
||||
@@ -427,8 +427,7 @@ static int fts5InitVtab(
|
||||
|
||||
/* Load the initial configuration */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
|
||||
sqlite3Fts5IndexRollback(pTab->p.pIndex);
|
||||
rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
@@ -2068,9 +2067,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
** Implementation of xBegin() method.
|
||||
*/
|
||||
static int fts5BeginMethod(sqlite3_vtab *pVtab){
|
||||
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
|
||||
fts5NewTransaction((Fts5FullTable*)pVtab);
|
||||
return SQLITE_OK;
|
||||
int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -680,11 +680,11 @@ do_test 12.0 {
|
||||
|
||||
do_catchsql_test 11.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 11.2 {
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 500);
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -1040,7 +1040,7 @@ do_test 16.0 {
|
||||
|
||||
do_catchsql_test 16.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -1126,7 +1126,7 @@ do_test 17.0 {
|
||||
|
||||
do_catchsql_test 17.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -1630,7 +1630,7 @@ do_test 20.0 {
|
||||
|
||||
do_catchsql_test 20.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -2100,7 +2100,7 @@ do_test 22.0 {
|
||||
|
||||
do_catchsql_test 22.1 {
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -3700,7 +3700,7 @@ do_catchsql_test 32.1 {
|
||||
highlight(t1, 2, '[', ']')
|
||||
FROM t1('g + h')
|
||||
WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank;
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 32.2 {
|
||||
SELECT * FROM t3;
|
||||
|
||||
@@ -32,20 +32,11 @@ sqlite3 db test.db
|
||||
|
||||
do_catchsql_test 1.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
do_catchsql_test 1.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_test 1.4 {
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
} {0}
|
||||
do_test 1.5 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_test 1.6 {
|
||||
sqlite3_db_config db DEFENSIVE -1
|
||||
} {0}
|
||||
do_execsql_test 1.7 {
|
||||
} {0 {}}
|
||||
do_execsql_test 1.4 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
|
||||
do_faultsim_test 4 -faults oom-* -body {
|
||||
db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
|
||||
} -test {
|
||||
faultsim_test_result {0 {0 {} 3}}
|
||||
faultsim_test_result {0 {0 {} 2}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -256,6 +256,27 @@ do_faultsim_test 10 -faults oom* -prep {
|
||||
faultsim_test_result {0 hello}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 11.0 {
|
||||
CREATE VIRTUAL TABLE f1 USING fts5(content);
|
||||
CREATE TABLE g1(id, content);
|
||||
INSERT INTO g1 VALUES(30000, 'a b c');
|
||||
INSERT INTO g1 VALUES(40000, 'd e f');
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 11 -faults oom* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
INSERT INTO f1(rowid, content) SELECT id, content FROM g1;
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ do_catchsql_test 1.2.2 {
|
||||
|
||||
do_catchsql_test 1.3.1 {
|
||||
SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads');
|
||||
} {1 {no such cursor: 1}}
|
||||
} {1 {no such cursor: 0}}
|
||||
|
||||
do_catchsql_test 1.3.2 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
|
||||
} {1 {no such cursor: 1}}
|
||||
} {1 {no such cursor: 0}}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
@@ -57,12 +57,12 @@ sqlite3 db test.db
|
||||
do_catchsql_test 1.3.3 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
|
||||
} {1 {no such cursor: 1}}
|
||||
} {1 {no such cursor: 0}}
|
||||
|
||||
fts5_aux_test_functions db
|
||||
do_catchsql_test 1.3.4 {
|
||||
SELECT fts5_columntext(t1) FROM t1('*reads');
|
||||
} {1 {no such cursor: 1}}
|
||||
} {1 {no such cursor: 0}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
@@ -350,7 +350,7 @@ do_execsql_test 14.3 {
|
||||
|
||||
do_execsql_test 14.4 {
|
||||
SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
|
||||
} {0 {} 3}
|
||||
} {0 {} 2}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
+319
-88
@@ -11,7 +11,7 @@
|
||||
******************************************************************************
|
||||
**
|
||||
** 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
|
||||
** exactly two arguments.
|
||||
@@ -60,31 +60,103 @@
|
||||
**
|
||||
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
|
||||
**
|
||||
** (14) A separate percentile_cond(Y,X) function is the equivalent of
|
||||
** percentile(Y,X*100.0).
|
||||
** (14) A separate percentile_cont(Y,P) function is equivalent to
|
||||
** 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"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#ifdef SQLITE_STATIC_PERCENTILE
|
||||
# include "sqlite3.h"
|
||||
#else
|
||||
# include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The following object is the session context for a single percentile()
|
||||
** function. We have to remember all input Y values until the very end.
|
||||
/* The following object is the group context for a single percentile()
|
||||
** aggregate. Remember all input Y values until the very end.
|
||||
** Those values are accumulated in the Percentile.a[] array.
|
||||
*/
|
||||
typedef struct Percentile Percentile;
|
||||
struct Percentile {
|
||||
unsigned nAlloc; /* Number of slots allocated for 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 */
|
||||
};
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
static int isInfinity(double r){
|
||||
static int percentIsInfinity(double r){
|
||||
sqlite3_uint64 u;
|
||||
assert( sizeof(u)==sizeof(r) );
|
||||
memcpy(&u, &r, sizeof(u));
|
||||
@@ -92,13 +164,77 @@ 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;
|
||||
return a>=-0.001 && a<=0.001;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Verify that the elements of the Percentile p are in fact sorted.
|
||||
** Used for testing and debugging only.
|
||||
*/
|
||||
static void percentAssertSorted(Percentile *p){
|
||||
int i;
|
||||
for(i=p->nUsed-2; i>=0 && p->a[i]<=p->a[i+1]; i--){}
|
||||
assert( i<0 );
|
||||
}
|
||||
#else
|
||||
# define percentAssertSorted(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 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 = sqlite3_mprintf(zMsg1, pFunc->zName);
|
||||
sqlite3_result_error(pCtx, zMsg2, -1);
|
||||
sqlite3_free(zMsg1);
|
||||
sqlite3_free(zMsg2);
|
||||
}
|
||||
|
||||
/*
|
||||
** The "step" function for percentile(Y,P) is called once for each
|
||||
** input row.
|
||||
@@ -112,28 +248,20 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
||||
|
||||
if( argc==1 ){
|
||||
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
|
||||
rPct = 50.0;
|
||||
}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;
|
||||
}
|
||||
rPct = 0.5;
|
||||
}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]);
|
||||
rPct = sqlite3_value_double(argv[1]);
|
||||
rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac;
|
||||
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|
||||
|| 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);
|
||||
|| rPct<0.0 || rPct>1.0
|
||||
){
|
||||
percentError(pCtx, "the fraction argument to %%s()"
|
||||
" is not between 0.0 and %.1f",
|
||||
(double)pFunc->mxFrac);
|
||||
return;
|
||||
}
|
||||
rPct *= 100.0;
|
||||
}
|
||||
|
||||
/* Allocate the session context. */
|
||||
@@ -142,11 +270,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
|
||||
** from any prior row, per Requirement (2). */
|
||||
if( p->rPct==0.0 ){
|
||||
p->rPct = rPct+1.0;
|
||||
}else if( !sameValue(p->rPct,rPct+1.0) ){
|
||||
sqlite3_result_error(pCtx, "2nd argument to percentile() is not the "
|
||||
"same for all input rows", -1);
|
||||
if( !p->bPctValid ){
|
||||
p->rPct = rPct;
|
||||
p->bPctValid = 1;
|
||||
}else if( !percentSameValue(p->rPct,rPct) ){
|
||||
percentError(pCtx, "the fraction argument to %%s()"
|
||||
" is not the same for all input rows");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,15 +286,14 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
||||
/* If not NULL, then Y must be numeric. Otherwise throw an error.
|
||||
** Requirement 4 */
|
||||
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
|
||||
sqlite3_result_error(pCtx, "1st argument to percentile() is not "
|
||||
"numeric", -1);
|
||||
percentError(pCtx, "input to %%s() is not numeric");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Throw an error if the Y value is infinity or NaN */
|
||||
y = sqlite3_value_double(argv[0]);
|
||||
if( isInfinity(y) ){
|
||||
sqlite3_result_error(pCtx, "Inf input to percentile()", -1);
|
||||
if( percentIsInfinity(y) ){
|
||||
percentError(pCtx, "Inf input to %%s()");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,50 +310,81 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
|
||||
p->nAlloc = n;
|
||||
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;
|
||||
percentAssertSorted(p);
|
||||
i = percentBinarySearch(p, y, 0);
|
||||
if( i<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){
|
||||
int iLt; /* Entries with index less than iLt are less than rPivot */
|
||||
int iGt; /* Entries with index iGt or more are greater than rPivot */
|
||||
#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
|
||||
|
||||
/*
|
||||
** 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 */
|
||||
double rPivot; /* The pivot value */
|
||||
double rTmp; /* Temporary used to swap two values */
|
||||
|
||||
if( n<2 ) return;
|
||||
if( n>5 ){
|
||||
rPivot = (a[0] + a[n/2] + a[n-1])/3.0;
|
||||
}else{
|
||||
rPivot = a[n/2];
|
||||
|
||||
assert( n>=2 );
|
||||
if( a[0]>a[n-1] ){
|
||||
SWAP_DOUBLE(a[0],a[n-1])
|
||||
}
|
||||
iLt = i = 0;
|
||||
iGt = n;
|
||||
while( i<iGt ){
|
||||
if( n==2 ) return;
|
||||
iGt = n-1;
|
||||
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( i>iLt ){
|
||||
rTmp = a[i];
|
||||
a[i] = a[iLt];
|
||||
a[iLt] = rTmp;
|
||||
}
|
||||
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
|
||||
iLt++;
|
||||
i++;
|
||||
}else if( a[i]>rPivot ){
|
||||
do{
|
||||
iGt--;
|
||||
}while( iGt>i && a[iGt]>rPivot );
|
||||
rTmp = a[i];
|
||||
a[i] = a[iGt];
|
||||
a[iGt] = rTmp;
|
||||
SWAP_DOUBLE(a[i],a[iGt])
|
||||
}else{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if( iLt>=2 ) sortDoubles(a, iLt);
|
||||
if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt);
|
||||
|
||||
}while( i<iGt );
|
||||
if( iLt>=2 ) percentSort(a, iLt);
|
||||
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
|
||||
|
||||
/* Uncomment for testing */
|
||||
#if 0
|
||||
for(i=0; i<n-1; i++){
|
||||
@@ -234,12 +393,64 @@ static void sortDoubles(double *a, int n){
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Called to compute the final output of percentile() and to clean
|
||||
** up all allocated memory.
|
||||
** The "inverse" function for percentile(Y,P) is called to remove a
|
||||
** 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;
|
||||
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;
|
||||
}else{
|
||||
percentAssertSorted(p);
|
||||
}
|
||||
p->bKeepSorted = 1;
|
||||
|
||||
/* Find and remove the row */
|
||||
i = percentBinarySearch(p, y, 1);
|
||||
if( i>=0 ){
|
||||
p->nUsed--;
|
||||
if( i<p->nUsed ){
|
||||
memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
|
||||
}
|
||||
}
|
||||
percentAssertSorted(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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;
|
||||
double v1, v2;
|
||||
double ix, vx;
|
||||
@@ -247,19 +458,38 @@ static void percentFinal(sqlite3_context *pCtx){
|
||||
if( p==0 ) return;
|
||||
if( p->a==0 ) return;
|
||||
if( p->nUsed ){
|
||||
sortDoubles(p->a, p->nUsed);
|
||||
ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
|
||||
if( p->bSorted==0 ){
|
||||
assert( p->nUsed>1 );
|
||||
percentSort(p->a, p->nUsed);
|
||||
p->bSorted = 1;
|
||||
}else{
|
||||
percentAssertSorted(p);
|
||||
}
|
||||
ix = p->rPct*(p->nUsed-1);
|
||||
i1 = (unsigned)ix;
|
||||
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);
|
||||
if( pFunc->bDiscrete ){
|
||||
vx = p->a[i1];
|
||||
}else{
|
||||
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_free(p->a);
|
||||
memset(p, 0, sizeof(*p));
|
||||
if( bIsFinal ){
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
@@ -270,20 +500,21 @@ int sqlite3_percentile_init(
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
#ifdef SQLITE_STATIC_PERCENTILE
|
||||
(void)pApi; /* Unused parameter */
|
||||
#else
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
#endif
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
rc = sqlite3_create_function(db, "percentile", 2,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
|
||||
0, percentStep, percentFinal);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "median", 1,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
|
||||
0, percentStep, percentFinal);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "percentile_cont", 2,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep,
|
||||
0, percentStep, percentFinal);
|
||||
for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){
|
||||
rc = sqlite3_create_window_function(db,
|
||||
aPercentFunc[i].zName,
|
||||
aPercentFunc[i].nArg,
|
||||
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1,
|
||||
(void*)&aPercentFunc[i],
|
||||
percentStep, percentFinal, percentValue, percentInverse, 0);
|
||||
if( rc ) break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
# build the SQLite library and testing tools.
|
||||
################################################################################
|
||||
|
||||
# If OPTIONS... is specified on the command-line, append its value to OPTS
|
||||
#
|
||||
OPTS += $(OPTIONS)
|
||||
|
||||
# This is how we compile
|
||||
#
|
||||
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
|
||||
@@ -537,6 +541,7 @@ FUZZSRC += $(TOP)/test/vt02.c
|
||||
FUZZSRC += $(TOP)/test/fuzzinvariants.c
|
||||
FUZZSRC += $(TOP)/ext/recover/dbdata.c
|
||||
FUZZSRC += $(TOP)/ext/recover/sqlite3recover.c
|
||||
FUZZSRC += $(TOP)/ext/misc/percentile.c
|
||||
FUZZSRC += $(TOP)/ext/misc/randomjson.c
|
||||
DBFUZZ_OPT =
|
||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
@@ -760,6 +765,7 @@ SHELL_DEP = \
|
||||
$(TOP)/ext/misc/ieee754.c \
|
||||
$(TOP)/ext/misc/memtrace.c \
|
||||
$(TOP)/ext/misc/pcachetrace.c \
|
||||
$(TOP)/ext/misc/percentile.c \
|
||||
$(TOP)/ext/misc/regexp.c \
|
||||
$(TOP)/ext/misc/series.c \
|
||||
$(TOP)/ext/misc/shathree.c \
|
||||
@@ -958,9 +964,14 @@ tcltest: ./testfixture$(EXE)
|
||||
testrunner: testfixture$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/testrunner.tcl
|
||||
|
||||
# Runs both fuzztest and testrunner, consecutively.
|
||||
# This is the testing target preferred by the core SQLite developers.
|
||||
# It runs tests under a standard configuration, regardless of how
|
||||
# ./configure was run. The devs run "make devtest" prior to each
|
||||
# check-in, at a minimum. Probably other tests too, but at least this
|
||||
# one.
|
||||
#
|
||||
devtest: testfixture$(EXE) fuzztest testrunner
|
||||
devtest: srctree-check sourcetest
|
||||
tclsh $(TOP)/test/testrunner.tcl mdevtest
|
||||
|
||||
mdevtest:
|
||||
tclsh $(TOP)/test/testrunner.tcl mdevtest
|
||||
@@ -971,10 +982,19 @@ mdevtest:
|
||||
quicktest: ./testfixture$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS)
|
||||
|
||||
# The default test case. Runs most of the faster standard TCL tests,
|
||||
# and fuzz tests, and sqlite3_analyzer and sqldiff tests.
|
||||
test: fuzztest sourcetest $(TESTPROGS) tcltest
|
||||
# Validate that various generated files in the source tree
|
||||
# are up-to-date.
|
||||
#
|
||||
srctree-check: $(TOP)/tool/srctree-check.tcl
|
||||
tclsh $(TOP)/tool/srctree-check.tcl
|
||||
|
||||
# Try to run tests on whatever options are specified by the
|
||||
# environment variables. The SQLite developers seldom use this target.
|
||||
# Instead# they use "make devtest" which runs tests on a standard set of
|
||||
# options regardless of how SQLite is configured. This "test"
|
||||
# target is provided for legacy only.
|
||||
#
|
||||
test: fuzztest sourcetest $(TESTPROGS) tcltest
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
@@ -1112,41 +1132,22 @@ install: sqlite3 libsqlite3.a sqlite3.h
|
||||
mv sqlite3.h /usr/include
|
||||
|
||||
clean:
|
||||
rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
|
||||
rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
|
||||
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
|
||||
rm -f $(PUBLISH)
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f amalgamation-testfixture amalgamation-testfixture.exe
|
||||
rm -f fts3-testfixture fts3-testfixture.exe
|
||||
rm -f testfixture testfixture.exe
|
||||
rm -f threadtest3 threadtest3.exe
|
||||
rm -f LogEst LogEst.exe
|
||||
rm -f fts3view fts3view.exe
|
||||
rm -f rollback-test rollback-test.exe
|
||||
rm -f showdb showdb.exe
|
||||
rm -f showjournal showjournal.exe
|
||||
rm -f showstat4 showstat4.exe
|
||||
rm -f showwal showwal.exe
|
||||
rm -f changeset changeset.exe
|
||||
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
|
||||
rm -f *.lo *.la *.o *.c *.h *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
|
||||
rm -rf .libs .deps tsrc libtool target_source testrunner_*
|
||||
rm -f lemon$(BEXE) sqlite*.tar.gz
|
||||
rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE)
|
||||
rm -f parse.* fts5parse.*
|
||||
rm -rf tsrc .target_source testrunner_bld_* testdir*
|
||||
rm -f tclsqlite3$(TEXE)
|
||||
rm -f $(TESTPROGS) testrunner.*
|
||||
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
|
||||
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
|
||||
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
|
||||
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
|
||||
rm -f sqlite3_analyzer$(TEXE)
|
||||
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
|
||||
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
|
||||
rm -f threadtest5$(TEXE)
|
||||
rm -f src-verify has_tclsh*
|
||||
|
||||
distclean: clean
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Fix\stypo\sin\sthe\sprevious\scheck-in.\s\sEnsure\sthat\s--status\sheader\slines\sdo\snot\noverflow\sand\swrap.
|
||||
D 2024-08-27T19:48:19.164
|
||||
C Improved\serror\smessages\son\spercentile\sfunctions.\s\sMore\stests\scases\sfor\npercentile\sand\sfor\sordered-set\saggregates.
|
||||
D 2024-09-02T11:17:04.726
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 101cb90f75c16ca3f8e7088364322441f9b01d6fdcef4a9c7f5fdcf78a3601a4
|
||||
F Makefile.in af5fbc3453b745daa68c7aa5dfdb945c09cb724971db3b783d6b5e1a62279e28
|
||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||
F Makefile.msc 6c3fe8b6ce60e73f34a148c957d78b4648745c8d30e792423aa1a8d8bf12d065
|
||||
F README.md 3d47ef5758e2de29d6f4e1aca714d51424baba86c8b561fef330f6ef2dc9282c
|
||||
F Makefile.msc 2c905f4c795a628d7fd892294e8fdec6d5f719fa5b252cb839fed147e64435a0
|
||||
F README.md 5b678e264236788390d11991f2c0052bd73f19790173883fc56d638bcb849154
|
||||
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
@@ -17,7 +17,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
|
||||
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
|
||||
F autoconf/Makefile.msc 7ac6c331fc3b8aa57b6782db995b8c0e49230352decd4e2662fd07c06a9ed623
|
||||
F autoconf/Makefile.msc 2aced6442addab13ed115696eba28d9ed29caa3dd604a31392c2c7a5da301492
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
|
||||
F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
|
||||
@@ -100,7 +100,7 @@ F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81c
|
||||
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
|
||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
|
||||
F ext/fts5/fts5_main.c 0dbe241c50b62e24a229a176d66d580e359b3c32cb0970c39bb6dd6b86e125d5
|
||||
F ext/fts5/fts5_main.c 1fddb53f495425d9314c74b30c5848a9dd254be0e5f445bfe38292d5ab21c288
|
||||
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
|
||||
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
@@ -148,12 +148,12 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b
|
||||
F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a
|
||||
F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb26f51ef956c8328bd
|
||||
F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4
|
||||
F ext/fts5/test/fts5corrupt3.test 621e9bca3e7299f487e1b29ff4179d9fc9560f5847dfc5b50a16010c9d2a0e5f
|
||||
F ext/fts5/test/fts5corrupt3.test 4fc3bf129f1616bea00884a23fd9d7b0e46d01791d2b57fe8d68ac36e8d3ff7c
|
||||
F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733
|
||||
F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76
|
||||
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
|
||||
F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c
|
||||
F ext/fts5/test/fts5corrupt8.test f78b6de9e4327e16ba7a7958b1ce576f9b5d886b4b97690f90b7f3cf654da458
|
||||
F ext/fts5/test/fts5corrupt8.test b81d802e41631e98100f49a1aadeeffef860e30a62d6ed7d743c2797c477239e
|
||||
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
|
||||
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
|
||||
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
|
||||
@@ -165,7 +165,7 @@ F ext/fts5/test/fts5expr.test c7e208813df7a90badc856fde3796da79569b39382e0fdb430
|
||||
F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd
|
||||
F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344
|
||||
F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522
|
||||
F ext/fts5/test/fts5fault4.test 87a10d0caee57da587c7588b0c8d25d2930197399b4812ad1e4d574c75324cee
|
||||
F ext/fts5/test/fts5fault4.test a5c0e849127c24e1751bc453a817f09a1b8d460e75f9ae4764017e216a870db3
|
||||
F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762
|
||||
F ext/fts5/test/fts5fault6.test 40f49976c6ca8927bf7d65d0b8df46009d7ea172e1d4050b294610e7ea0a2979
|
||||
F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c
|
||||
@@ -178,7 +178,7 @@ F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e
|
||||
F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1
|
||||
F ext/fts5/test/fts5faultG.test 0544411ffcb3e19b42866f757a8a5e0fb8fef3a62c06f61d14deebc571bb7ea9
|
||||
F ext/fts5/test/fts5faultH.test 2b2b5b8cb1b3fd7679f488c06e22af44107fbc6137eaf45b3e771dc7b149312d
|
||||
F ext/fts5/test/fts5faultI.test e1e8a927122a8c3be8614a59717e838cad0505ba0a6f404983da8430e7aeb14d
|
||||
F ext/fts5/test/fts5faultI.test ae4b83ac953200bd7b66d53038f7d6a4fc29cd64831b8e1795538babcea7c638
|
||||
F ext/fts5/test/fts5first.test bfd685b96905bf541d99d8644e0a7219d1d833455a08ab64e344071a613b6ba9
|
||||
F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affcf7e979df59547b
|
||||
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
||||
@@ -192,7 +192,7 @@ F ext/fts5/test/fts5locale.test 797cf6f5e017462ab11313ce884b9f1df8ff063811e74ef4
|
||||
F ext/fts5/test/fts5matchinfo.test 877520582feb86bbfd95ab780099bcba4526f18ac75ee34979144cf86ba3a5a3
|
||||
F ext/fts5/test/fts5merge.test 2654df0bcdb2d117c2d38b6aeb0168061be01c643f9e9194b36c43a2970e8082
|
||||
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
|
||||
F ext/fts5/test/fts5misc.test 60bb2be4a2d83d7a45047c1812781e2e337a27efa539d86356ef7f4acaf08eab
|
||||
F ext/fts5/test/fts5misc.test 8c3cc771f773dc4bb4973620c51e7729e324ca2cc80eb8894f1c2c605e361f0b
|
||||
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
|
||||
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
|
||||
F ext/fts5/test/fts5near.test 33d60867581066e5db7016deb5d651628125d7ff4e0233a88175aa5b65874c74
|
||||
@@ -226,7 +226,7 @@ F ext/fts5/test/fts5secure6.test 74bf04733cc523bccca519bb03d3b4e2ed6f6e3db7c59bf
|
||||
F ext/fts5/test/fts5secure7.test fd03d0868d64340a1db8615b02e5508fea409de13910114e4f19eaefc120777a
|
||||
F ext/fts5/test/fts5secure8.test 808ade9d172ed07b24b85c57dd53b6d2b1aba018b4e634d267ce572221de80e0
|
||||
F ext/fts5/test/fts5securefault.test c34a28c7cd2f31a8b8907563889e1329a97da975c08df2d951422bcef8e2ebc5
|
||||
F ext/fts5/test/fts5simple.test ed7c3815c9fa1c16166258cb98edb2e014c63c7589958d76c5487df0df913d61
|
||||
F ext/fts5/test/fts5simple.test 302cdb4f8a3350b091f4f1bccd82d05610428657f6f9e81c17703ba48267ec40
|
||||
F ext/fts5/test/fts5simple2.test d10d963a357b8ec77b99032e4c816459b4dbdb1f6eee25eada7ef3ed245cb2dc
|
||||
F ext/fts5/test/fts5simple3.test 146ec3dc8f5763d6212641c9f0a2f1cba41679353d2add7b963beceb115dc7f4
|
||||
F ext/fts5/test/fts5synonym.test becc8cea6cfc958a50b30c572c68cbfdf7455971d0fe988202ce67638d2c6cf6
|
||||
@@ -410,7 +410,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58
|
||||
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
|
||||
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
|
||||
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
|
||||
F ext/misc/percentile.c af1941dc87d45dd0c2698a3087fbfe9ee0d157e5e72da521430c4b784abcbe81
|
||||
F ext/misc/percentile.c 4e333fc78d2a7b9cf362e29f30fa3f486cdab9e69fbc9aa0f680399683aa22f7
|
||||
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
|
||||
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
|
||||
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
||||
@@ -685,7 +685,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk 9541ffdce424ddddb463e2480c3f1cb4067bbd3a6d2c84b3f083cb128a2fa721
|
||||
F main.mk 5a2e7d4a852c058373efc78407816de41595d06975148c766092b3cf0fea4298
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
|
||||
@@ -704,13 +704,13 @@ F src/auth.c 4c1ea890e0069ad73bead5d17a5b12c34cfa4f1a24175c8147ea439b64be271c
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
|
||||
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||
F src/btree.c 8b42fc7d9efdb2df05c30e8f91ff6cfbd979724ae24bf90269028468b7a13333
|
||||
F src/btree.c 8c5592c618741c5fc9733e7efe3927bfafad3e999d15b0a0f3f1d3f3e17b919e
|
||||
F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0
|
||||
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
|
||||
F src/build.c 3a1840d9d171ce2d24f4c1f7acda7266ab796c664290c1acba65ff98ce2bd01e
|
||||
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
|
||||
F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
|
||||
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
@@ -718,7 +718,7 @@ F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
|
||||
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||
F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
|
||||
F src/func.c df400a1d3f4625997d4dd8a81951c303e066277c29b861d37e03cd152d7858dd
|
||||
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
@@ -728,7 +728,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
|
||||
F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||
F src/main.c a520c325c7400b249242945f2c602acb19662c40f5db1c04d88664cfaa8b85ac
|
||||
F src/main.c e7b53893f9fb3ad76baa8513f85c167b34d5c8e25ce64608db440f5637d0fe9e
|
||||
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
|
||||
@@ -754,7 +754,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
|
||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||
F src/parse.y 5972b7d00af4c8d96fdad781af1ea1d5d51fc3b907ad61bda60e49503274e5ed
|
||||
F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61
|
||||
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
|
||||
@@ -767,10 +767,10 @@ F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||
F src/shell.c.in 40de636c1d90fb8a9ca7f49dc8f50d930f1b60736e73aca5eb37c4c7d0e47f9d
|
||||
F src/sqlite.h.in f07bff4225a1244efd604a0ffef81ed69f29d3dbaed7e22f906f26229ba3ca9e
|
||||
F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 28c878bdf528879afefe1994ac007d094f8061f2fdacdc55d6055d7e9341151e
|
||||
F src/sqliteInt.h 889cd632f4386bbd8619b166abb7d25f1c8ce6514e90cb7f22f63bd530fc6107
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -790,7 +790,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97
|
||||
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
|
||||
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
|
||||
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
|
||||
F src/test_config.c 46eaf39842cace9d540aeefb50fe24dd3204a622893a97952cbb49c20b2f8b21
|
||||
F src/test_config.c 345b8e383f71cecc36d0fa05f2f06639c254b188f98101c3c97749df43037086
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
|
||||
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
|
||||
@@ -841,7 +841,7 @@ F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
|
||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
|
||||
F src/vdbeaux.c 25d685cafe119ff890c94345e884ea558a6b5d823bfa52ba708eb8ff3c70aa71
|
||||
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
|
||||
F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
|
||||
F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
|
||||
F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
@@ -1266,7 +1266,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c 6e87c27df3d95c556870187987dff6efdc712b5cea60abedc8ab9215f471907a
|
||||
F test/fuzzcheck.c 20be6c96bd0da2e91d25f089a037c1b3f8142211c97104f20629bf15610019e6
|
||||
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1517,7 +1517,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
|
||||
F test/percentile.test 74e383216a075251512d6ba98beb9dccd6da465e3f73817fc438379e3a628de7
|
||||
F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd
|
||||
F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
|
||||
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
|
||||
F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
|
||||
@@ -1626,10 +1626,10 @@ F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 490bf9d0c7c9564fea318c46d49369f4690b825b584c9a544dbdccf61bc0babc
|
||||
F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026
|
||||
F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
|
||||
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
|
||||
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
|
||||
F test/shell5.test bafa4c0b67b7a8027e729970a625c9225cb7ef854acc4e52624c45074faaaddf
|
||||
F test/shell5.test 0e5f8ce08206b9998a778cfe1989e20e47839153c05af2da29198150172e22fc
|
||||
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
|
||||
F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
|
||||
F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd
|
||||
@@ -1714,8 +1714,8 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 2c203a2dd664298f239f0ec3ce22fbc65b5f021c1e09edbae8452af8a694e052
|
||||
F test/testrunner.tcl c27905c57f54450411be922037d227fee65b08928d09715d784380a398b0e758
|
||||
F test/testrunner_data.tcl 6a0facfbff26f2f8573ebaeb209426bbb59809d5c0f6925f983bd030ab5248cd
|
||||
F test/testrunner.tcl 662af46f1f0a41eb197f17583698853dd130ff3d47cf136dd519c3aecd9a9d7d
|
||||
F test/testrunner_data.tcl d64e69aba227492fc459eb0f6a88c3e1b252bd9323847b7e8bcf5e1faa358714
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -2070,7 +2070,7 @@ F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af
|
||||
F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf
|
||||
F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2
|
||||
F test/windowD.test 65cf5a765fb8072450e8a0de2979ce7f09a38d87724fe1280c6444073e3da49b
|
||||
F test/windowE.test c98507e0b0d95980ad25845db758557757be2d7054198ccf522c7d277057a3df
|
||||
F test/windowE.test d045a5fbaaf50ecac9483e1249dd317ba4f9d189c405a730ba6effdefb87b94f
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c
|
||||
@@ -2131,8 +2131,8 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
|
||||
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x
|
||||
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
|
||||
F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x
|
||||
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
|
||||
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
|
||||
@@ -2149,7 +2149,7 @@ F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617
|
||||
F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a
|
||||
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
||||
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
|
||||
F tool/omittest.tcl e99c9fecc3f7a8ca2fa75d8ec8bdbb5acce33dc69f0c280aae53064693387f65
|
||||
F tool/omittest.tcl 5ca5e4e01716d5f35b48b00fd351d929f01fbb98169a5a3cd00baf3d2e2019a9
|
||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||
F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a
|
||||
@@ -2211,8 +2211,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7c195f132cb48ee44124eb4af3532937493429f7c45f6ac611f7a9b128799ad7
|
||||
R 15868716c90b102057036239341d8066
|
||||
P 3b1cdddf8339cc339ec74cd8be2bfa42e62b500048a444eb9e5d9817bc4702ae
|
||||
R a80c34160df19b1603ad0e7833a0d0c3
|
||||
U drh
|
||||
Z fde036223228b7af985cf94952c295a1
|
||||
Z baa1dd0d6096edf0ada0dc3da2ddafed
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2eaea67495fd9961b7145d829789889bf1d8fa7a834d40d1be43e7c74c233bc2
|
||||
e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce
|
||||
|
||||
+1
-1
@@ -5989,7 +5989,7 @@ int sqlite3BtreeIndexMoveto(
|
||||
&& indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
|
||||
&& pIdxKey->errCode==SQLITE_OK
|
||||
){
|
||||
pCur->curFlags &= ~BTCF_ValidOvfl;
|
||||
pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
|
||||
if( !pCur->pPage->isInit ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
@@ -295,6 +295,9 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
"ENABLE_OFFSET_SQL_FUNC",
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||
"ENABLE_ORDERED_SET_AGGREGATES",
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
"ENABLE_OVERSIZE_CELL_CHECK",
|
||||
#endif
|
||||
|
||||
+6
-2
@@ -2049,7 +2049,11 @@ static void minMaxFinalize(sqlite3_context *context){
|
||||
** group_concat(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
|
||||
** SEPARATOR were appended after EXPR. And the order is undocumented,
|
||||
** 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
|
||||
** run first to initialize it */
|
||||
if( ALWAYS(pGCC) ){
|
||||
int nVS;
|
||||
int nVS; /* Number of characters to remove */
|
||||
/* Must call sqlite3_value_text() to convert the argument into text prior
|
||||
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
|
||||
(void)sqlite3_value_text(argv[0]);
|
||||
|
||||
+2
-1
@@ -1926,7 +1926,8 @@ int sqlite3CreateFunc(
|
||||
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
|
||||
assert( SQLITE_FUNC_DIRECT==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);
|
||||
|
||||
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
|
||||
|
||||
+71
-1
@@ -264,6 +264,9 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
|
||||
CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
|
||||
EXCLUDE GROUPS OTHERS TIES
|
||||
%endif SQLITE_OMIT_WINDOWFUNC
|
||||
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||
WITHIN
|
||||
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
|
||||
GENERATED ALWAYS
|
||||
%endif
|
||||
@@ -1179,6 +1182,65 @@ expr(A) ::= idj(X) LP STAR RP. {
|
||||
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
|
||||
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
|
||||
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);
|
||||
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). {
|
||||
A = sqlite3ExprFunction(pParse, 0, &OP, 0);
|
||||
|
||||
@@ -5615,6 +5615,15 @@ int sqlite3_create_window_function(
|
||||
** [sqlite3_result_subtype()] should avoid setting this property, as the
|
||||
** purpose of this property is to disable certain optimizations that are
|
||||
** 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>
|
||||
** </dl>
|
||||
*/
|
||||
@@ -5623,6 +5632,7 @@ int sqlite3_create_window_function(
|
||||
#define SQLITE_SUBTYPE 0x000100000
|
||||
#define SQLITE_INNOCUOUS 0x000200000
|
||||
#define SQLITE_RESULT_SUBTYPE 0x001000000
|
||||
#define SQLITE_SELFORDER1 0x002000000
|
||||
|
||||
/*
|
||||
** CAPI3REF: Deprecated Functions
|
||||
|
||||
@@ -658,6 +658,8 @@
|
||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||
# define double sqlite_int64
|
||||
# define float sqlite_int64
|
||||
# define fabs(X) ((X)<0?-(X):(X))
|
||||
# define sqlite3IsOverflow(X) 0
|
||||
# define LONGDOUBLE_TYPE sqlite_int64
|
||||
# ifndef SQLITE_BIG_DBL
|
||||
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
|
||||
|
||||
@@ -189,6 +189,14 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","0",TCL_GLOBAL_ONLY);
|
||||
#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
|
||||
Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -341,6 +349,14 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "0", TCL_GLOBAL_ONLY);
|
||||
#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
|
||||
Tcl_SetVar2(interp, "sqlite_options", "oversize_cell_check", "1",
|
||||
TCL_GLOBAL_ONLY);
|
||||
|
||||
@@ -167,6 +167,11 @@ int sqlite3_blob_open(
|
||||
pTab = 0;
|
||||
sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
|
||||
}
|
||||
if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){
|
||||
pTab = 0;
|
||||
sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s",
|
||||
zTable);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
if( pTab && IsView(pTab) ){
|
||||
pTab = 0;
|
||||
|
||||
+4
-2
@@ -159,10 +159,11 @@ static struct GlobalVars {
|
||||
} 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_randomjson_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
|
||||
|
||||
/*
|
||||
@@ -1329,7 +1330,8 @@ int runCombinedDbSqlInput(
|
||||
/* Add the vt02 virtual table */
|
||||
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);
|
||||
|
||||
/* Add support for sqlite_dbdata and sqlite_dbptr virtual tables used
|
||||
|
||||
+425
-61
@@ -9,7 +9,8 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
# 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]
|
||||
@@ -25,35 +26,65 @@ do_test percentile-1.0 {
|
||||
}
|
||||
execsql {SELECT percentile(x,0) FROM t1}
|
||||
} {1.0}
|
||||
foreach {in out} {
|
||||
100 11.0
|
||||
50 8.0
|
||||
12.5 4.0
|
||||
15 4.4
|
||||
20 5.2
|
||||
80 11.0
|
||||
89 11.0
|
||||
foreach {in out disc} {
|
||||
100 11.0 11.0
|
||||
50 8.0 8.0
|
||||
12.5 4.0 4.0
|
||||
15 4.4 4.0
|
||||
20 5.2 4.0
|
||||
80 11.0 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}
|
||||
} $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 {
|
||||
SELECT median(x) FROM t1;
|
||||
} 8.0
|
||||
|
||||
foreach {in out} {
|
||||
1.0 11.0
|
||||
0.5 8.0
|
||||
0.125 4.0
|
||||
0.15 4.4
|
||||
0.2 5.2
|
||||
0.8 11.0
|
||||
0.89 11.0
|
||||
} {
|
||||
do_test percentile-1.1b-$in {
|
||||
execsql {SELECT percentile_cont(x,$in) FROM t1}
|
||||
} $out
|
||||
ifcapable ordered_set_aggregates {
|
||||
do_execsql_test percentile-1.1.median {
|
||||
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
|
||||
} 8.0
|
||||
do_execsql_test percentile-1.1.distinct.1 {
|
||||
SELECT median(DISTINCT x) FROM t1;
|
||||
} 7.0
|
||||
do_catchsql_test percentile-1.1.distinct.2 {
|
||||
SELECT percentile(DISTINCT 50) WITHIN GROUP (ORDER BY x) FROM t1;
|
||||
} {1 {DISTINCT not allowed on ordered-set aggregate percentile()}}
|
||||
} else {
|
||||
do_catchsql_test percentile-1.1.median {
|
||||
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
|
||||
} {1 {near "(": syntax error}}
|
||||
}
|
||||
|
||||
# Add some NULL values.
|
||||
@@ -61,28 +92,69 @@ foreach {in out} {
|
||||
do_test percentile-1.2 {
|
||||
execsql {INSERT INTO t1 VALUES(NULL),(NULL);}
|
||||
} {}
|
||||
foreach {in out} {
|
||||
100 11.0
|
||||
50 8.0
|
||||
12.5 4.0
|
||||
15 4.4
|
||||
20 5.2
|
||||
80 11.0
|
||||
89 11.0
|
||||
foreach {in out disc} {
|
||||
100 11.0 11.0
|
||||
50 8.0 8.0
|
||||
12.5 4.0 4.0
|
||||
15 4.4 4.0
|
||||
20 5.2 4.0
|
||||
80 11.0 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}
|
||||
} $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.
|
||||
#
|
||||
do_test percentile-1.4 {
|
||||
do_test percentile-1.4.1 {
|
||||
catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1}
|
||||
} {0 4.4}
|
||||
do_test percentile-1.5 {
|
||||
catchsql {SELECT round(percentile(x, 15+0.1*rowid),1) FROM t1}
|
||||
} {1 {2nd argument to percentile() is not the same for all input rows}}
|
||||
do_test percentile-1.4.2 {
|
||||
catchsql {SELECT round(percentile_cont(x,(15+0.000001*rowid)*0.01),1) FROM t1}
|
||||
} {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
|
||||
#
|
||||
@@ -92,65 +164,152 @@ do_test percentile-1.6 {
|
||||
INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random();
|
||||
}
|
||||
} {}
|
||||
foreach {in out} {
|
||||
100 11.0
|
||||
50 8.0
|
||||
12.5 4.0
|
||||
15 4.4
|
||||
20 5.2
|
||||
80 11.0
|
||||
89 11.0
|
||||
foreach {in out disc} {
|
||||
100 11.0 11.0
|
||||
50 8.0 8.0
|
||||
12.5 4.0 4.0
|
||||
15 4.4 4.0
|
||||
20 5.2 4.0
|
||||
80 11.0 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}
|
||||
} $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
|
||||
#
|
||||
do_test percentile-1.8 {
|
||||
do_test percentile-1.8.1 {
|
||||
catchsql {SELECT percentile(x,0,1) FROM t1}
|
||||
} {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}
|
||||
} {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
|
||||
#
|
||||
do_test percentile-1.10 {
|
||||
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 {
|
||||
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 {
|
||||
catchsql {SELECT percentile(x,x'3530') FROM t1}
|
||||
} {1 {2nd argument to percentile() is not a number 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}}
|
||||
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||
|
||||
# Second argument is out of range
|
||||
#
|
||||
do_test percentile-1.13 {
|
||||
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 {
|
||||
catchsql {SELECT percentile(x,100.0000001) FROM t1}
|
||||
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
|
||||
do_test percentile-1.14b {
|
||||
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
|
||||
do_test percentile-1.14.2 {
|
||||
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
|
||||
#
|
||||
do_test percentile-1.15 {
|
||||
do_test percentile-1.15.1 {
|
||||
catchsql {
|
||||
BEGIN;
|
||||
UPDATE t1 SET x='50' WHERE x IS NULL;
|
||||
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 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
@@ -158,7 +317,7 @@ do_test percentile-1.16 {
|
||||
UPDATE t1 SET x=x'3530' WHERE x IS NULL;
|
||||
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 {
|
||||
catchsql {
|
||||
ROLLBACK;
|
||||
@@ -186,7 +345,7 @@ do_test percentile-1.19 {
|
||||
|
||||
# Infinity as an input
|
||||
#
|
||||
do_test percentile-1.20 {
|
||||
do_test percentile-1.20.1 {
|
||||
catchsql {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 SELECT x+0.0 FROM t2;
|
||||
@@ -194,6 +353,43 @@ do_test percentile-1.20 {
|
||||
SELECT percentile(x,50) from t1;
|
||||
}
|
||||
} {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 {
|
||||
catchsql {
|
||||
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
|
||||
|
||||
@@ -217,6 +217,7 @@ do_test shell2-1.4.9 {
|
||||
done
|
||||
2}}
|
||||
|
||||
ifcapable vtab {
|
||||
# Verify that generate_series stays sane near 64-bit range boundaries.
|
||||
# See overflow report at https://sqlite.org/forum/forumpost/5d34ce5280
|
||||
do_test shell2-1.4.10 {
|
||||
@@ -247,7 +248,9 @@ do_test shell2-1.4.10 {
|
||||
0
|
||||
1
|
||||
2}}
|
||||
} ;# ifcapable vtab
|
||||
|
||||
ifcapable vtab {
|
||||
# Bug discovered while messing around, .import hangs with
|
||||
# bit 7 set in column separator.
|
||||
do_test shell2-1.4.11 {
|
||||
@@ -262,6 +265,7 @@ do_test shell2-1.4.11 {
|
||||
.import dummy.csv t
|
||||
SELECT count(*) FROM t;}]]
|
||||
} {0 1}
|
||||
} ;# ifcapable vtab
|
||||
|
||||
# Bug from forum post 7cbe081746dd3803
|
||||
# Keywords as column names were producing an error message.
|
||||
|
||||
@@ -84,6 +84,14 @@ do_test shell5-1.4.1 {
|
||||
.import FOO t1}]
|
||||
} {1 {Error: cannot open "FOO"}}
|
||||
|
||||
# the remainder of these test cases require virtual tables.
|
||||
#
|
||||
ifcapable !vtab {
|
||||
puts "Skipping subsequent tests due to SQLITE_OMIT_VIRTUALTABLE"
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# empty import file
|
||||
do_test shell5-1.4.2 {
|
||||
forcedelete shell5.csv
|
||||
|
||||
+66
-16
@@ -470,18 +470,25 @@ proc show_status {db cls} {
|
||||
# overwrite.
|
||||
puts -nonewline "\033\[H"
|
||||
flush stdout
|
||||
set clreol "\033\[K"
|
||||
} else {
|
||||
set clreol ""
|
||||
}
|
||||
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]$clreol"]
|
||||
puts [format %-79.79s "Cores: $nJob max $S(running) active"]
|
||||
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total tasks,\
|
||||
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]"]
|
||||
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total jobs,\
|
||||
$ne errors, $nt tests"]
|
||||
|
||||
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
||||
set line "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} {
|
||||
puts "Running: "
|
||||
$db eval {
|
||||
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
|
||||
} job {
|
||||
@@ -489,15 +496,30 @@ proc show_status {db cls} {
|
||||
}
|
||||
}
|
||||
if {$S(failed)>0} {
|
||||
puts "Failures: "
|
||||
# $toshow is the number of failures to report. In $cls mode,
|
||||
# status tries to limit the number of failure reported so that
|
||||
# the status display does not overflow a 24-line terminal. It will
|
||||
# always show at least the most recent 4 failures, even if an overflow
|
||||
# is needed. No limit is imposed for a status within $cls.
|
||||
#
|
||||
if {$cls && $S(failed)>18-$S(running)} {
|
||||
set toshow [expr {18-$S(running)}]
|
||||
if {$toshow<4} {set toshow 4}
|
||||
set shown " (must recent $toshow shown)"
|
||||
} else {
|
||||
set toshow $S(failed)
|
||||
set shown ""
|
||||
}
|
||||
puts [format %-79s "Failed: $S(failed) $shown"]
|
||||
$db eval {
|
||||
SELECT * FROM jobs WHERE state='failed' ORDER BY starttime
|
||||
SELECT * FROM jobs WHERE state='failed'
|
||||
ORDER BY endtime DESC LIMIT $toshow
|
||||
} job {
|
||||
display_job [array get job]
|
||||
}
|
||||
set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
|
||||
if {$nOmit} {
|
||||
puts [format %-79s "$nOmit jobs omitted due to failures$clreol"]
|
||||
puts [format %-79s " ... $nOmit jobs omitted due to failures"]
|
||||
}
|
||||
}
|
||||
if {$cls} {
|
||||
@@ -880,7 +902,7 @@ proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
|
||||
} else {
|
||||
set p "$p*"
|
||||
}
|
||||
if {[string match $p [file tail $f]]} {
|
||||
if {[string match $p "$config [file tail $f]"]} {
|
||||
set bMatch 1
|
||||
break
|
||||
}
|
||||
@@ -1100,13 +1122,34 @@ proc add_jobs_from_cmdline {patternlist} {
|
||||
}
|
||||
|
||||
release {
|
||||
set config_set {}
|
||||
set patternlist [lrange $patternlist 1 end]
|
||||
foreach b [trd_builds $TRG(platform)] {
|
||||
if {$TRG(config)!="" && ![regexp "\\y$b\\y" $TRG(config)]} continue
|
||||
if {[regexp "\\y$b\\y" $TRG(omitconfig)]} continue
|
||||
lappend config_set $b
|
||||
set bld [add_build_job $b $TRG(testfixture)]
|
||||
foreach c [trd_configs $TRG(platform) $b] {
|
||||
add_tcl_jobs $bld $c $patternlist SHELL
|
||||
}
|
||||
|
||||
if {$patternlist==""} {
|
||||
foreach e [trd_extras $TRG(platform) $b] {
|
||||
if {$e=="fuzztest"} {
|
||||
add_fuzztest_jobs $b
|
||||
} else {
|
||||
add_make_job $bld $e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if {[trdb one "SELECT EXISTS(SELECT 1
|
||||
FROM jobs WHERE depid='SHELL')"]} {
|
||||
set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]]
|
||||
set sbldid [lindex $sbld 0]
|
||||
trdb eval {
|
||||
UPDATE jobs SET depid=$sbldid WHERE depid='SHELL'
|
||||
}
|
||||
}
|
||||
}
|
||||
add_devtest_jobs $config_set [lrange $patternlist 1 end]
|
||||
}
|
||||
|
||||
list {
|
||||
@@ -1448,7 +1491,14 @@ proc explain_layer {indent depid} {
|
||||
puts "${indent}$displayname in $dirname"
|
||||
explain_layer "${indent} " $jobid
|
||||
} elseif {$showtests} {
|
||||
puts "${indent}[lindex $displayname end]"
|
||||
set tail [lindex $displayname end]
|
||||
set e1 [lindex $displayname 1]
|
||||
if {[string match config=* $e1]} {
|
||||
set cfg [string range $e1 7 end]
|
||||
puts "${indent}($cfg) $tail"
|
||||
} else {
|
||||
puts "${indent}$tail"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1463,7 +1513,7 @@ if {$TRG(explain)} {
|
||||
explain_tests
|
||||
} else {
|
||||
if {$TRG(nJob)>1} {
|
||||
puts "splitting work across $TRG(nJob) jobs"
|
||||
puts "splitting work across $TRG(nJob) cores"
|
||||
}
|
||||
puts "built testset in [expr $tm/1000]ms.."
|
||||
handle_buildonly
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace eval trd {
|
||||
#
|
||||
set build(All-Debug) {
|
||||
--enable-debug --enable-all
|
||||
-DSQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||
}
|
||||
set build(All-O0) {
|
||||
-O0 --enable-all
|
||||
@@ -218,7 +219,7 @@ namespace eval trd {
|
||||
-DSQLITE_MAX_PAGE_SIZE=4096
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLEx=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLE=1
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DSQLITE_TEMP_STORE=3
|
||||
}
|
||||
|
||||
@@ -73,6 +73,38 @@ do_catchsql_test 2.2 {
|
||||
WINDOW w1 AS (PARTITION BY x OVER w1);
|
||||
} {1 {near "OVER": syntax error}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t2(c1 INT, c2 REAL);
|
||||
INSERT INTO t2 VALUES
|
||||
(447,0.0), (448,0.0), (449,0.0), (452,0.0), (453,0.0), (454,0.0), (455,0.0),
|
||||
(456,0.0), (459,0.0), (460,0.0), (462,0.0), (463,0.0), (466,0.0), (467,0.0),
|
||||
(468,0.0), (469,0.0), (470,0.0), (473,0.0), (474,0.0), (475,0.0), (476,0.0),
|
||||
(477,0.0), (480,0.0), (481,0.0), (482,0.0), (483,0.0), (484,0.0), (487,0.0),
|
||||
(488,0.0), (489,0.0), (490,0.0), (491,0.0), (494,0.0), (495,0.0), (496,0.0),
|
||||
(497,0.0), (498,0.0), (501,0.0), (502,0.0), (503,0.0), (504,0.0), (505,0.0),
|
||||
(508,0.0), (509,0.0), (510,0.0), (511,0.0), (512,0.0), (515,0.0), (516,0.0),
|
||||
(517,0.0), (518,0.0), (519,0.0), (522,0.0), (523,0.0), (524,0.0), (525,0.0),
|
||||
(526,0.0), (529,0.0), (530,0.0), (531,0.0), (532,0.0), (533,0.0), (536,0.0),
|
||||
(537,1.0), (538,0.0), (539,0.0), (540,0.0), (543,0.0), (544,0.0);
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
select c1, max(c2) over (order by c1 range 366.0 preceding) from t2;
|
||||
} {
|
||||
447 0.0 448 0.0 449 0.0 452 0.0 453 0.0 454 0.0 455 0.0 456 0.0 459 0.0
|
||||
460 0.0 462 0.0 463 0.0 466 0.0 467 0.0 468 0.0 469 0.0 470 0.0 473 0.0
|
||||
474 0.0 475 0.0 476 0.0 477 0.0 480 0.0 481 0.0 482 0.0 483 0.0 484 0.0
|
||||
487 0.0 488 0.0 489 0.0 490 0.0 491 0.0 494 0.0 495 0.0 496 0.0 497 0.0
|
||||
498 0.0 501 0.0 502 0.0 503 0.0 504 0.0 505 0.0 508 0.0 509 0.0 510 0.0
|
||||
511 0.0 512 0.0 515 0.0 516 0.0 517 0.0 518 0.0 519 0.0 522 0.0 523 0.0
|
||||
524 0.0 525 0.0 526 0.0 529 0.0 530 0.0 531 0.0 532 0.0 533 0.0 536 0.0
|
||||
537 1.0 538 1.0 539 1.0 540 1.0 543 1.0 544 1.0
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ set boolean_defnil_options {
|
||||
SQLITE_ENABLE_MULTIPLEX
|
||||
SQLITE_ENABLE_NORMALIZE
|
||||
SQLITE_ENABLE_NULL_TRIM
|
||||
SQLITE_ENABLE_ORDERED_SET_AGGREGATES
|
||||
SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
|
||||
SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
@@ -448,6 +449,7 @@ if {[catch {set cfd [open $destfile w]}]!=0} {
|
||||
puts stderr "File '$destfile' unwritable."
|
||||
exit 1;
|
||||
}
|
||||
fconfigure $cfd -translation binary
|
||||
|
||||
puts $cfd $::headWarning;
|
||||
puts $cfd $::headCode;
|
||||
|
||||
@@ -164,6 +164,11 @@ struct Keyword {
|
||||
#else
|
||||
# define RETURNING 0x00400000
|
||||
#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 },
|
||||
{ "WINDOW", "TK_WINDOW", WINDOWFUNC, 3 },
|
||||
{ "WITH", "TK_WITH", CTE, 4 },
|
||||
{ "WITHIN", "TK_WITHIN", ORDERSET, 1 },
|
||||
{ "WITHOUT", "TK_WITHOUT", ALWAYS, 1 },
|
||||
};
|
||||
|
||||
|
||||
+201
-351
@@ -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.
|
||||
#
|
||||
set ::USAGE_MESSAGE {
|
||||
This Tcl script is used to test the various compile time options
|
||||
available for omitting code (the SQLITE_OMIT_xxx options). It
|
||||
should be invoked as follows:
|
||||
available for building SQLite, especially options taht omit
|
||||
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.
|
||||
}
|
||||
|
||||
|
||||
# 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:
|
||||
# List of all options to be tested.
|
||||
#
|
||||
# run_quick_test /tmp/testdir {SQLITE_OMIT_TRIGGER SQLITE_OMIT_VIEW}
|
||||
#
|
||||
#
|
||||
proc run_quick_test {dir omit_symbol_list} {
|
||||
# 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"
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
# Create the directory and do the build. If an error occurs return
|
||||
# early without attempting to run the test suite.
|
||||
file mkdir $dir
|
||||
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 {
|
||||
exec $::MAKEBIN -C $dir -f makefile clean $::TARGET >& $dir/build.log
|
||||
}]
|
||||
if {$rc} {
|
||||
puts "No good. See $dir/build.log."
|
||||
return
|
||||
} else {
|
||||
puts "Ok"
|
||||
}
|
||||
|
||||
# Create an empty file "$dir/sqlite3". This is to trick the makefile out
|
||||
# of trying to build the sqlite shell. The sqlite shell won't build
|
||||
# with some of the OMIT options (i.e OMIT_COMPLETE).
|
||||
set sqlite3_dummy $dir/sqlite3
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
append sqlite3_dummy ".exe"
|
||||
}
|
||||
if {![file exists $sqlite3_dummy]} {
|
||||
set wr [open $sqlite3_dummy w]
|
||||
puts $wr "dummy"
|
||||
close $wr
|
||||
# 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]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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."
|
||||
# Additional options required for some settings.
|
||||
#
|
||||
set More(SQLITE_OMIT_DISKIO) {-DSQLITE_OMIT_WAL}
|
||||
|
||||
# Compile-time options for Mac only
|
||||
#
|
||||
set MacOnly(SQLITE_ENABLE_LOCKING_STYLE) 1
|
||||
|
||||
# Compile-time options that might fail, depending on what libraries
|
||||
# are installed. Failures on these tests issue a warning, but testing
|
||||
# continues.
|
||||
#
|
||||
set FailIsOk(SQLITE_ENABLE_ICU) 1
|
||||
set FailIsOk(SQLITE_ENABLE_ICU_COLLATIONS) 1
|
||||
|
||||
file mkdir omittest
|
||||
foreach sym $CompileOptionsToTest {
|
||||
if {[info exists startat]} {
|
||||
if {$startat==$sym} {
|
||||
unset startat
|
||||
} else {
|
||||
puts "Ok"
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# This proc processes the command line options passed to this script.
|
||||
# Currently the only option supported is "-makefile", default
|
||||
# "../Makefile.linux-gcc". Set the ::MAKEFILE variable to the value of this
|
||||
# option.
|
||||
#
|
||||
proc process_options {argv} {
|
||||
set ::MAKEBIN make ;# Default value
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
set ::MAKEFILE ./Makefile ;# Default value on Windows
|
||||
if {[info exists MacOnly($sym)] && $tcl_platform(os)!="Darwin"} {
|
||||
continue
|
||||
}
|
||||
set logfile "omittest/$sym.log"
|
||||
if {[info exists More($sym)]} {
|
||||
append opts "OPT_FEATURE_FLAGS=-D$sym $More($sym)"
|
||||
} else {
|
||||
set ::MAKEFILE ./Makefile.linux-gcc ;# Default value
|
||||
set opts OPT_FEATURE_FLAGS=-D$sym
|
||||
}
|
||||
set ::SKIP_RUN 1 ;# Default to attempt test
|
||||
set ::TARGET testfixture ;# Default thing to build
|
||||
|
||||
for {set i 0} {$i < [llength $argv]} {incr i} {
|
||||
switch -regexp -- [lindex $argv $i] {
|
||||
-{1,2}makefile {
|
||||
incr i
|
||||
set ::MAKEFILE [lindex $argv $i]
|
||||
}
|
||||
|
||||
-{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
|
||||
puts "make tidy sqlite3.lo $opts"
|
||||
if {[catch {exec make tidy sqlite3.lo $opts >& $logfile}]} {
|
||||
puts "BUILD FAILED: see $logfile for details"
|
||||
if {[info exists FailIsOk($sym)]} {
|
||||
set Failure($sym) 1
|
||||
} else {
|
||||
puts "Note: After fixes, continue the test using:\n"
|
||||
puts " [info nameofexe] $argv0 --start $sym\n"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main $argv
|
||||
if {[llength [array names Failure]]>0} {
|
||||
puts "BUILD FAILED on the following:"
|
||||
foreach sym [array names Failure] {
|
||||
puts " * $sym"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user