Merge enhancements from trunk.
FossilOrigin-Name: 0e23a079bd648f9778c857ec51e39acfd30a4040
This commit is contained in:
+21
-10
@@ -535,6 +535,10 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata2.db \
|
||||
$(TOP)/test/fuzzdata3.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
@@ -993,39 +997,46 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS)
|
||||
|
||||
# Really really long testing
|
||||
soaktest: $(TESTPROGS)
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS)
|
||||
|
||||
# Do extra testing but not everything.
|
||||
fulltestonly: $(TESTPROGS)
|
||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||
|
||||
# Fuzz testing
|
||||
fuzztest: fuzzcheck$(TEXE)
|
||||
fuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
./fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
|
||||
# This is the common case. Run many tests but not those that take
|
||||
# a really long time.
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --quiet $(FUZZDATA)
|
||||
|
||||
# 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.
|
||||
#
|
||||
test: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: $(TESTPROGS) fuzzcheck$(TEXE)
|
||||
valgrind -v ./fuzzcheck$(TEXE) --cell-size-check --quiet $(FUZZDATA)
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
||||
valgrindtest: $(TESTPROGS) valgrindfuzz
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
echo "#define TCLSH 2" > $@
|
||||
|
||||
+17
-6
@@ -1203,6 +1203,9 @@ FUZZDATA = \
|
||||
$(TOP)\test\fuzzdata2.db \
|
||||
$(TOP)\test\fuzzdata3.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
@@ -1677,28 +1680,36 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
extensiontest: testfixture.exe testloadext.dll
|
||||
.\testfixture.exe $(TOP)\test\loadext.test
|
||||
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
|
||||
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\all.test
|
||||
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
|
||||
|
||||
soaktest: $(TESTPROGS)
|
||||
.\testfixture.exe $(TOP)\test\all.test -soak=1
|
||||
.\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS)
|
||||
|
||||
fulltestonly: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\full.test
|
||||
|
||||
queryplantest: testfixture.exe sqlite3.exe
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
|
||||
|
||||
fuzztest: fuzzcheck.exe
|
||||
.\fuzzcheck.exe $(FUZZDATA)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes (on a fast machine)
|
||||
#
|
||||
quicktest: .\testfixture.exe
|
||||
.\testfixture.exe $(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.
|
||||
#
|
||||
test: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
|
||||
|
||||
smoketest: $(TESTPROGS)
|
||||
.\testfixture.exe $(TOP)\test\main.test
|
||||
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
||||
|
||||
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||
echo #define TCLSH 2 > $@
|
||||
|
||||
@@ -269,5 +269,88 @@ ifcapable rtree {
|
||||
db close
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Test that queries featuring LEFT or CROSS JOINS are handled correctly.
|
||||
# Handled correctly in this case means:
|
||||
#
|
||||
# * Terms with prereqs that appear to the left of a LEFT JOIN against
|
||||
# the virtual table are always available to xBestIndex.
|
||||
#
|
||||
# * Terms with prereqs that appear to the right of a LEFT JOIN against
|
||||
# the virtual table are never available to xBestIndex.
|
||||
#
|
||||
# And the same behaviour for CROSS joins.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
CREATE TABLE xdir(x1);
|
||||
CREATE TABLE ydir(y1);
|
||||
CREATE VIRTUAL TABLE rt USING rtree_i32(id, xmin, xmax, ymin, ymax);
|
||||
|
||||
INSERT INTO xdir VALUES(5);
|
||||
INSERT INTO ydir VALUES(10);
|
||||
|
||||
INSERT INTO rt VALUES(1, 2, 7, 12, 14); -- Not a hit
|
||||
INSERT INTO rt VALUES(2, 2, 7, 8, 12); -- A hit!
|
||||
INSERT INTO rt VALUES(3, 7, 11, 8, 12); -- Not a hit!
|
||||
INSERT INTO rt VALUES(4, 5, 5, 10, 10); -- A hit!
|
||||
|
||||
}
|
||||
|
||||
proc do_eqp_execsql_test {tn sql res} {
|
||||
set query "EXPLAIN QUERY PLAN $sql ; $sql "
|
||||
uplevel [list do_execsql_test $tn $query $res]
|
||||
}
|
||||
|
||||
do_eqp_execsql_test 7.1 {
|
||||
SELECT id FROM xdir, rt, ydir
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 2 {SCAN TABLE ydir}
|
||||
0 2 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1}
|
||||
2 4
|
||||
}
|
||||
|
||||
do_eqp_execsql_test 7.2 {
|
||||
SELECT * FROM xdir, rt LEFT JOIN ydir
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
|
||||
5 1 2 7 12 14 {}
|
||||
5 2 2 7 8 12 10
|
||||
5 4 5 5 10 10 10
|
||||
}
|
||||
|
||||
do_eqp_execsql_test 7.3 {
|
||||
SELECT id FROM xdir, rt CROSS JOIN ydir
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 0 {SCAN TABLE xdir}
|
||||
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
2 4
|
||||
}
|
||||
|
||||
do_eqp_execsql_test 7.4 {
|
||||
SELECT id FROM rt, xdir CROSS JOIN ydir
|
||||
ON (y1 BETWEEN ymin AND ymax)
|
||||
WHERE (x1 BETWEEN xmin AND xmax);
|
||||
} {
|
||||
0 0 1 {SCAN TABLE xdir}
|
||||
0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
|
||||
0 2 2 {SCAN TABLE ydir}
|
||||
2 4
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -416,6 +416,10 @@ FUZZDATA = \
|
||||
$(TOP)/test/fuzzdata2.db \
|
||||
$(TOP)/test/fuzzdata3.db
|
||||
|
||||
# Standard options to testfixture
|
||||
#
|
||||
TESTOPTS = --verbose=file --output=test-out.txt
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
@@ -668,36 +672,48 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test
|
||||
./testfixture$(EXE) $(TOP)/test/all.test $(TESTOPTS)
|
||||
|
||||
soaktest: $(TESTPROGS)
|
||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS)
|
||||
|
||||
fulltestonly: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/full.test
|
||||
./testfixture$(EXE) $(TOP)/test/full.test $(TESTOPTS)
|
||||
|
||||
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)
|
||||
|
||||
fuzztest: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
./fuzzcheck$(EXE) $(FUZZDATA)
|
||||
|
||||
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
valgrind ./fuzzcheck$(EXE) --cell-size-check --quiet $(FUZZDATA)
|
||||
|
||||
# A very quick test using only testfixture and omitting all the slower
|
||||
# tests. Designed to run in under 3 minutes on a workstation.
|
||||
#
|
||||
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: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
||||
./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS)
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: $(TESTPROGS) fuzzcheck$(EXE) $(FUZZDATA)
|
||||
valgrind -v ./fuzzcheck$(EXE) --cell-size-check --quiet $(FUZZDATA)
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind
|
||||
valgrindtest: $(TESTPROGS) valgrindfuzz
|
||||
OMIT_MISUSE=1 valgrind -v \
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS)
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: $(TESTPROGS) fuzzcheck$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/main.test
|
||||
./testfixture$(EXE) $(TOP)/test/main.test $(TESTOPTS)
|
||||
|
||||
# The next two rules are used to support the "threadtest" target. Building
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
C Resolve\sFROM-clause\ssubqueries\safter\squery\splanning\sinstead\sof\sbefore.\nGreatly\sreduce\sthe\sestimated\scost\sof\sautomatic\sindexes\sfor\sVIEWs\sand\nephemeral\stables\ssince\sperformance\sproblems\sthere\scannot\sbe\smitigated\nvia\sa\sCREATE\sINDEX.
|
||||
D 2015-06-10T17:20:42.577
|
||||
C Merge\senhancements\sfrom\strunk.
|
||||
D 2015-06-10T20:00:49.246
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in a7b384855b72378fd860425b128ea5f75296e9d6
|
||||
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 5438dc167466f51349ab0c4497aef547d0c9352c
|
||||
F Makefile.msc 5a8418c81f736dfa953c809af1a48398017b3610
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION ce0ae95abd7121c534f6917c1c8f2b70d9acd4db
|
||||
@@ -156,7 +156,7 @@ F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
|
||||
F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea
|
||||
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
||||
F ext/rtree/rtreeC.test 90aaaffe2fd4f0dcd12289cad5515f6d41f45ffd
|
||||
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
|
||||
F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb
|
||||
F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4
|
||||
@@ -171,7 +171,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk dc931768b88e4417bc2f8b2d45dba385ad29f727
|
||||
F main.mk 68f86c21505d6b66765a13c193f00a53dde6a212
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -246,7 +246,7 @@ F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
|
||||
F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc
|
||||
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
|
||||
F src/printf.c 9889e8826f8e2bd8c2718d7d3faa761bef8eac79
|
||||
F src/printf.c db11b5960105ee661dcac690f2ae6276e49bf251
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
@@ -327,7 +327,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 6a42bd33c17e8866c5f70c3e74eace4c2e106301
|
||||
F src/where.c aa26f4b0a3ad9c586f3315cb499d2dc813e14f01
|
||||
F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047
|
||||
F src/wherecode.c 3f3152ecf4224413bd0491ea4210883b85fe95d1
|
||||
F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652
|
||||
@@ -357,7 +357,7 @@ F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2
|
||||
F test/analyzer1.test e3bccac3be49382050464952998a631bf51e3ce1
|
||||
F test/analyzer1.test 498e2ff4b62740c2751c3a2f8b744fe26689fae9
|
||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
@@ -526,6 +526,7 @@ F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
|
||||
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
|
||||
@@ -709,7 +710,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/join.test 52d4d49f86d0cf46926672878c4eaf0da399104a
|
||||
F test/join.test f9d4a28dec81c6e9dc21b73518e024d73b5ebf57
|
||||
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
@@ -824,7 +825,7 @@ F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 32e2b82e0dfbe5c6b6b38a5c1f4cac194298ad4e
|
||||
F test/permutations.test 6b0f339a4d5f00041555a986dde8fbe8f54c25bc
|
||||
F test/pragma.test be7195f0aa72bdb8a512133e9640ac40f15b57a2
|
||||
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
@@ -843,7 +844,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl 3e906a8bbd047b8e1f035984fbdc96df4caaea47
|
||||
F test/releasetest.tcl 2aaffa548a8f8d10053b20bcf68a1b5a01081e51
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
|
||||
@@ -929,7 +930,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 9f1b745c24886cced3f70ffc666300152a39013c
|
||||
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
||||
F test/sqldiff1.test e5ecfe95b3a2ff6380f0db6ea8bec246b675e122
|
||||
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
|
||||
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
||||
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
@@ -949,7 +950,7 @@ F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl c18dbf42f4b0c1fb889b0efeb8a59d5143dd9828
|
||||
F test/tester.tcl ca396a3f867c1bd3603400ca8f17bbffd87985b7
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1285,7 +1286,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P cabf218716e3ba584dc27781ba5e2f9f00eab74c
|
||||
R 3e14ed600c1c4d5c883f594c595505eb
|
||||
P a1eaf1718e4544c17495ad7a4e333276979b8299 6ddef2ad35ceb5822fc14c65bc7c6a2662edb63c
|
||||
R f469f404132e2683182471710f678f88
|
||||
U drh
|
||||
Z 6efad1a2bf4568abad0be136ee25ec44
|
||||
Z ba88f60c8354d22ddfa769e6c6d29dcf
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
a1eaf1718e4544c17495ad7a4e333276979b8299
|
||||
0e23a079bd648f9778c857ec51e39acfd30a4040
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
** This file contains code for a set of "printf"-like routines. These
|
||||
** routines format strings much like the printf() from the standard C
|
||||
** library, though the implementation here has enhancements to support
|
||||
** SQLlite.
|
||||
** SQLite.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
||||
+54
-14
@@ -757,6 +757,7 @@ end_auto_index_create:
|
||||
static sqlite3_index_info *allocateIndexInfo(
|
||||
Parse *pParse,
|
||||
WhereClause *pWC,
|
||||
Bitmask mUnusable, /* Ignore terms with these prereqs */
|
||||
struct SrcList_item *pSrc,
|
||||
ExprList *pOrderBy
|
||||
){
|
||||
@@ -773,6 +774,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
** to this virtual table */
|
||||
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
||||
if( pTerm->prereqRight & mUnusable ) continue;
|
||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||
testcase( pTerm->eOperator & WO_IN );
|
||||
testcase( pTerm->eOperator & WO_ISNULL );
|
||||
@@ -827,6 +829,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
u8 op;
|
||||
if( pTerm->leftCursor != pSrc->iCursor ) continue;
|
||||
if( pTerm->prereqRight & mUnusable ) continue;
|
||||
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
|
||||
testcase( pTerm->eOperator & WO_IN );
|
||||
testcase( pTerm->eOperator & WO_IS );
|
||||
@@ -2667,10 +2670,32 @@ static int whereLoopAddBtree(
|
||||
/*
|
||||
** Add all WhereLoop objects for a table of the join identified by
|
||||
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
|
||||
**
|
||||
** If there are no LEFT or CROSS JOIN joins in the query, both mExtra and
|
||||
** mUnusable are set to 0. Otherwise, mExtra is a mask of all FROM clause
|
||||
** entries that occur before the virtual table in the FROM clause and are
|
||||
** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
|
||||
** mUnusable mask contains all FROM clause entries that occur after the
|
||||
** virtual table and are separated from it by at least one LEFT or
|
||||
** CROSS JOIN.
|
||||
**
|
||||
** For example, if the query were:
|
||||
**
|
||||
** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
|
||||
**
|
||||
** then mExtra corresponds to (t1, t2) and mUnusable to (t5, t6).
|
||||
**
|
||||
** All the tables in mExtra must be scanned before the current virtual
|
||||
** table. So any terms for which all prerequisites are satisfied by
|
||||
** mExtra may be specified as "usable" in all calls to xBestIndex.
|
||||
** Conversely, all tables in mUnusable must be scanned after the current
|
||||
** virtual table, so any terms for which the prerequisites overlap with
|
||||
** mUnusable should always be configured as "not-usable" for xBestIndex.
|
||||
*/
|
||||
static int whereLoopAddVirtual(
|
||||
WhereLoopBuilder *pBuilder, /* WHERE clause information */
|
||||
Bitmask mExtra
|
||||
Bitmask mExtra, /* Tables that must be scanned before this one */
|
||||
Bitmask mUnusable /* Tables that must be scanned after this one */
|
||||
){
|
||||
WhereInfo *pWInfo; /* WHERE analysis context */
|
||||
Parse *pParse; /* The parsing context */
|
||||
@@ -2691,6 +2716,7 @@ static int whereLoopAddVirtual(
|
||||
WhereLoop *pNew;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( (mExtra & mUnusable)==0 );
|
||||
pWInfo = pBuilder->pWInfo;
|
||||
pParse = pWInfo->pParse;
|
||||
db = pParse->db;
|
||||
@@ -2699,7 +2725,7 @@ static int whereLoopAddVirtual(
|
||||
pSrc = &pWInfo->pTabList->a[pNew->iTab];
|
||||
pTab = pSrc->pTab;
|
||||
assert( IsVirtual(pTab) );
|
||||
pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
|
||||
pIdxInfo = allocateIndexInfo(pParse, pWC, mUnusable, pSrc,pBuilder->pOrderBy);
|
||||
if( pIdxInfo==0 ) return SQLITE_NOMEM;
|
||||
pNew->prereq = 0;
|
||||
pNew->rSetup = 0;
|
||||
@@ -2729,7 +2755,7 @@ static int whereLoopAddVirtual(
|
||||
if( (pTerm->eOperator & WO_IN)!=0 ){
|
||||
seenIn = 1;
|
||||
}
|
||||
if( pTerm->prereqRight!=0 ){
|
||||
if( (pTerm->prereqRight & ~mExtra)!=0 ){
|
||||
seenVar = 1;
|
||||
}else if( (pTerm->eOperator & WO_IN)==0 ){
|
||||
pIdxCons->usable = 1;
|
||||
@@ -2737,7 +2763,7 @@ static int whereLoopAddVirtual(
|
||||
break;
|
||||
case 1: /* Constants with IN operators */
|
||||
assert( seenIn );
|
||||
pIdxCons->usable = (pTerm->prereqRight==0);
|
||||
pIdxCons->usable = (pTerm->prereqRight & ~mExtra)==0;
|
||||
break;
|
||||
case 2: /* Variables without IN */
|
||||
assert( seenVar );
|
||||
@@ -2836,7 +2862,11 @@ whereLoopAddVtab_exit:
|
||||
** Add WhereLoop entries to handle OR terms. This works for either
|
||||
** btrees or virtual tables.
|
||||
*/
|
||||
static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
|
||||
static int whereLoopAddOr(
|
||||
WhereLoopBuilder *pBuilder,
|
||||
Bitmask mExtra,
|
||||
Bitmask mUnusable
|
||||
){
|
||||
WhereInfo *pWInfo = pBuilder->pWInfo;
|
||||
WhereClause *pWC;
|
||||
WhereLoop *pNew;
|
||||
@@ -2895,14 +2925,14 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pItem->pTab) ){
|
||||
rc = whereLoopAddVirtual(&sSubBuild, mExtra);
|
||||
rc = whereLoopAddVirtual(&sSubBuild, mExtra, mUnusable);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
rc = whereLoopAddBtree(&sSubBuild, mExtra);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = whereLoopAddOr(&sSubBuild, mExtra);
|
||||
rc = whereLoopAddOr(&sSubBuild, mExtra, mUnusable);
|
||||
}
|
||||
assert( rc==SQLITE_OK || sCur.n==0 );
|
||||
if( sCur.n==0 ){
|
||||
@@ -2964,33 +2994,43 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
int iTab;
|
||||
SrcList *pTabList = pWInfo->pTabList;
|
||||
struct SrcList_item *pItem;
|
||||
struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel];
|
||||
sqlite3 *db = pWInfo->pParse->db;
|
||||
int nTabList = pWInfo->nLevel;
|
||||
int rc = SQLITE_OK;
|
||||
u8 priorJoinType = 0;
|
||||
WhereLoop *pNew;
|
||||
u8 priorJointype = 0;
|
||||
|
||||
/* Loop over the tables in the join, from left to right */
|
||||
pNew = pBuilder->pNew;
|
||||
whereLoopInit(pNew);
|
||||
for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
|
||||
for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
|
||||
Bitmask mUnusable = 0;
|
||||
pNew->iTab = iTab;
|
||||
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
|
||||
if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
|
||||
if( ((pItem->jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
|
||||
/* This condition is true when pItem is the FROM clause term on the
|
||||
** right-hand-side of a LEFT or CROSS JOIN. */
|
||||
mExtra = mPrior;
|
||||
}
|
||||
priorJoinType = pItem->jointype;
|
||||
priorJointype = pItem->jointype;
|
||||
if( IsVirtual(pItem->pTab) ){
|
||||
rc = whereLoopAddVirtual(pBuilder, mExtra);
|
||||
struct SrcList_item *p;
|
||||
for(p=&pItem[1]; p<pEnd; p++){
|
||||
if( mUnusable || (p->jointype & (JT_LEFT|JT_CROSS)) ){
|
||||
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
|
||||
}
|
||||
}
|
||||
rc = whereLoopAddVirtual(pBuilder, mExtra, mUnusable);
|
||||
}else{
|
||||
rc = whereLoopAddBtree(pBuilder, mExtra);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = whereLoopAddOr(pBuilder, mExtra);
|
||||
rc = whereLoopAddOr(pBuilder, mExtra, mUnusable);
|
||||
}
|
||||
mPrior |= pNew->maskSelf;
|
||||
if( rc || db->mallocFailed ) break;
|
||||
}
|
||||
|
||||
whereLoopClear(db, pNew);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ if {$tcl_platform(platform)=="windows"} {
|
||||
} else {
|
||||
set PROG "./sqlite3_analyzer"
|
||||
}
|
||||
if {![file exe $PROG]} {
|
||||
puts "analyzer1 cannot run because $PROG is not available"
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
db close
|
||||
forcedelete test.db test.db-journal test.db-wal
|
||||
sqlite3 db test.db
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file runs most of the tests run by veryquick.test except for those
|
||||
# that take a long time.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/permutations.test
|
||||
|
||||
run_test_suite extraquick
|
||||
|
||||
finish_test
|
||||
@@ -687,4 +687,30 @@ ifcapable pragma&&compileoption_diags {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test a problem with reordering tables following a LEFT JOIN.
|
||||
#
|
||||
do_execsql_test join-13.0 {
|
||||
CREATE TABLE aa(a);
|
||||
CREATE TABLE bb(b);
|
||||
CREATE TABLE cc(c);
|
||||
|
||||
INSERT INTO aa VALUES(45);
|
||||
INSERT INTO cc VALUES(45);
|
||||
INSERT INTO cc VALUES(45);
|
||||
}
|
||||
|
||||
do_execsql_test join-13.1 {
|
||||
SELECT * FROM aa LEFT JOIN bb, cc WHERE cc.c=aa.a;
|
||||
} {45 {} 45 45 {} 45}
|
||||
|
||||
# In the following, the order of [cc] and [bb] must not be exchanged, even
|
||||
# though this would be helpful if the query used an inner join.
|
||||
do_execsql_test join-13.2 {
|
||||
CREATE INDEX ccc ON cc(c);
|
||||
SELECT * FROM aa LEFT JOIN bb, cc WHERE cc.c=aa.a;
|
||||
} {45 {} 45 45 {} 45}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+14
-3
@@ -96,7 +96,7 @@ if {$::tcl_platform(platform)!="unix"} {
|
||||
set alltests [test_set $alltests -exclude {
|
||||
all.test async.test quick.test veryquick.test
|
||||
memleak.test permutations.test soak.test fts3.test
|
||||
mallocAll.test rtree.test full.test
|
||||
mallocAll.test rtree.test full.test extraquick.test
|
||||
}]
|
||||
|
||||
set allquicktests [test_set $alltests -exclude {
|
||||
@@ -146,11 +146,22 @@ if {[info exists ::env(TEST_FAILURE)]} {
|
||||
lappend ::testsuitelist xxx
|
||||
|
||||
test_suite "veryquick" -prefix "" -description {
|
||||
"Very" quick test suite. Runs in less than 5 minutes on a workstation.
|
||||
"Very" quick test suite. Runs in minutes on a workstation.
|
||||
This test suite is the same as the "quick" tests, except that some files
|
||||
that test malloc and IO errors are omitted.
|
||||
} -files [
|
||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault*
|
||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile*
|
||||
]
|
||||
|
||||
test_suite "extraquick" -prefix "" -description {
|
||||
"Extra" quick test suite. Runs in a few minutes on a workstation.
|
||||
This test suite is the same as the "veryquick" tests, except that
|
||||
slower tests are omitted.
|
||||
} -files [
|
||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* \
|
||||
wal3.test fts4merge* sort2.test mmap1.test walcrash* \
|
||||
percentile.test where8m.test walcksum.test savepoint3.test \
|
||||
fuzzer1.test fuzzer3.test fts3expr3.test
|
||||
]
|
||||
|
||||
test_suite "mmap" -prefix "mm-" -description {
|
||||
|
||||
@@ -547,7 +547,10 @@ proc process_options {argv} {
|
||||
puts " --srcdir $::SRCDIR"
|
||||
puts " --platform [list $platform]"
|
||||
puts " --config [list $config]"
|
||||
if {$::QUICK} {puts " --quick"}
|
||||
if {$::QUICK} {
|
||||
if {$::QUICK==1} {puts " --quick"}
|
||||
if {$::QUICK==2} {puts " --veryquick"}
|
||||
}
|
||||
if {$::MSVC} {puts " --msvc"}
|
||||
if {$::BUILDONLY} {puts " --buildonly"}
|
||||
if {$::DRYRUN} {puts " --dryrun"}
|
||||
@@ -645,7 +648,7 @@ proc main {argv} {
|
||||
}
|
||||
if {$target ne "checksymbols"} {
|
||||
switch -- $::QUICK {
|
||||
1 {set target test}
|
||||
1 {set target quicktest}
|
||||
2 {set target smoketest}
|
||||
}
|
||||
if {$::BUILDONLY} {
|
||||
|
||||
@@ -19,6 +19,11 @@ if {$tcl_platform(platform)=="windows"} {
|
||||
} else {
|
||||
set PROG "./sqldiff"
|
||||
}
|
||||
if {![file exe $PROG]} {
|
||||
puts "sqldiff cannot run because $PROG is not available"
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
db close
|
||||
forcedelete test.db test2.db
|
||||
sqlite3 db test.db
|
||||
|
||||
+150
-50
@@ -81,6 +81,12 @@
|
||||
# permutation
|
||||
# presql
|
||||
#
|
||||
# Command to test whether or not --verbose=1 was specified on the command
|
||||
# line (returns 0 for not-verbose, 1 for verbose and 2 for "verbose in the
|
||||
# output file only").
|
||||
#
|
||||
# verbose
|
||||
#
|
||||
|
||||
# Set the precision of FP arithmatic used by the interpreter. And
|
||||
# configure SQLite to take database file locks on the page that begins
|
||||
@@ -388,6 +394,9 @@ if {[info exists cmdlinearg]==0} {
|
||||
# --file-retry-delay=N
|
||||
# --start=[$permutation:]$testfile
|
||||
# --match=$pattern
|
||||
# --verbose=$val
|
||||
# --output=$filename
|
||||
# --help
|
||||
#
|
||||
set cmdlinearg(soft-heap-limit) 0
|
||||
set cmdlinearg(maxerror) 1000
|
||||
@@ -399,6 +408,8 @@ if {[info exists cmdlinearg]==0} {
|
||||
set cmdlinearg(file-retry-delay) 0
|
||||
set cmdlinearg(start) ""
|
||||
set cmdlinearg(match) ""
|
||||
set cmdlinearg(verbose) ""
|
||||
set cmdlinearg(output) ""
|
||||
|
||||
set leftover [list]
|
||||
foreach a $argv {
|
||||
@@ -457,6 +468,22 @@ if {[info exists cmdlinearg]==0} {
|
||||
set ::G(match) $cmdlinearg(match)
|
||||
if {$::G(match) == ""} {unset ::G(match)}
|
||||
}
|
||||
|
||||
{^-+output=.+$} {
|
||||
foreach {dummy cmdlinearg(output)} [split $a =] break
|
||||
if {$cmdlinearg(verbose)==""} {
|
||||
set cmdlinearg(verbose) 2
|
||||
}
|
||||
}
|
||||
{^-+verbose=.+$} {
|
||||
foreach {dummy cmdlinearg(verbose)} [split $a =] break
|
||||
if {$cmdlinearg(verbose)=="file"} {
|
||||
set cmdlinearg(verbose) 2
|
||||
} elseif {[string is boolean -strict $cmdlinearg(verbose)]==0} {
|
||||
error "option --verbose= must be set to a boolean or to \"file\""
|
||||
}
|
||||
}
|
||||
|
||||
default {
|
||||
lappend leftover $a
|
||||
}
|
||||
@@ -484,6 +511,16 @@ if {[info exists cmdlinearg]==0} {
|
||||
if {$cmdlinearg(malloctrace)} {
|
||||
sqlite3_memdebug_backtrace $cmdlinearg(backtrace)
|
||||
}
|
||||
|
||||
if {$cmdlinearg(output)!=""} {
|
||||
puts "Copying output to file $cmdlinearg(output)"
|
||||
set ::G(output_fd) [open $cmdlinearg(output) w]
|
||||
fconfigure $::G(output_fd) -buffering line
|
||||
}
|
||||
|
||||
if {$cmdlinearg(verbose)==""} {
|
||||
set cmdlinearg(verbose) 1
|
||||
}
|
||||
}
|
||||
|
||||
# Update the soft-heap-limit each time this script is run. In that
|
||||
@@ -554,7 +591,7 @@ proc fail_test {name} {
|
||||
|
||||
set nFail [set_test_counter errors]
|
||||
if {$nFail>=$::cmdlinearg(maxerror)} {
|
||||
puts "*** Giving up..."
|
||||
output2 "*** Giving up..."
|
||||
finalize_testing
|
||||
}
|
||||
}
|
||||
@@ -562,7 +599,7 @@ proc fail_test {name} {
|
||||
# Remember a warning message to be displayed at the conclusion of all testing
|
||||
#
|
||||
proc warning {msg {append 1}} {
|
||||
puts "Warning: $msg"
|
||||
output2 "Warning: $msg"
|
||||
set warnList [set_test_counter warn_list]
|
||||
if {$append} {
|
||||
lappend warnList $msg
|
||||
@@ -577,6 +614,61 @@ proc incr_ntest {} {
|
||||
set_test_counter count [expr [set_test_counter count] + 1]
|
||||
}
|
||||
|
||||
# Return true if --verbose=1 was specified on the command line. Otherwise,
|
||||
# return false.
|
||||
#
|
||||
proc verbose {} {
|
||||
return $::cmdlinearg(verbose)
|
||||
}
|
||||
|
||||
# Use the following commands instead of [puts] for test output within
|
||||
# this file. Test scripts can still use regular [puts], which is directed
|
||||
# to stdout and, if one is open, the --output file.
|
||||
#
|
||||
# output1: output that should be printed if --verbose=1 was specified.
|
||||
# output2: output that should be printed unconditionally.
|
||||
# output2_if_no_verbose: output that should be printed only if --verbose=0.
|
||||
#
|
||||
proc output1 {args} {
|
||||
set v [verbose]
|
||||
if {$v==1} {
|
||||
uplevel output2 $args
|
||||
} elseif {$v==2} {
|
||||
uplevel puts [lrange $args 0 end-1] $::G(output_fd) [lrange $args end end]
|
||||
}
|
||||
}
|
||||
proc output2 {args} {
|
||||
set nArg [llength $args]
|
||||
uplevel puts $args
|
||||
}
|
||||
proc output2_if_no_verbose {args} {
|
||||
set v [verbose]
|
||||
if {$v==0} {
|
||||
uplevel output2 $args
|
||||
} elseif {$v==2} {
|
||||
uplevel puts [lrange $args 0 end-1] stdout [lrange $args end end]
|
||||
}
|
||||
}
|
||||
|
||||
# Override the [puts] command so that if no channel is explicitly
|
||||
# specified the string is written to both stdout and to the file
|
||||
# specified by "--output=", if any.
|
||||
#
|
||||
proc puts_override {args} {
|
||||
set nArg [llength $args]
|
||||
if {$nArg==1 || ($nArg==2 && [string first [lindex $args 0] -nonewline]==0)} {
|
||||
uplevel puts_original $args
|
||||
if {[info exists ::G(output_fd)]} {
|
||||
uplevel puts [lrange $args 0 end-1] $::G(output_fd) [lrange $args end end]
|
||||
}
|
||||
} else {
|
||||
# A channel was explicitly specified.
|
||||
uplevel puts_original $args
|
||||
}
|
||||
}
|
||||
rename puts puts_original
|
||||
proc puts {args} { uplevel puts_override $args }
|
||||
|
||||
|
||||
# Invoke the do_test procedure to run a single test
|
||||
#
|
||||
@@ -604,12 +696,13 @@ proc do_test {name cmd expected} {
|
||||
}
|
||||
|
||||
incr_ntest
|
||||
puts -nonewline $name...
|
||||
output1 -nonewline $name...
|
||||
flush stdout
|
||||
|
||||
if {![info exists ::G(match)] || [string match $::G(match) $name]} {
|
||||
if {[catch {uplevel #0 "$cmd;\n"} result]} {
|
||||
puts "\nError: $result"
|
||||
output2_if_no_verbose -nonewline $name...
|
||||
output2 "\nError: $result"
|
||||
fail_test $name
|
||||
} else {
|
||||
if {[regexp {^~?/.*/$} $expected]} {
|
||||
@@ -653,14 +746,15 @@ proc do_test {name cmd expected} {
|
||||
# if {![info exists ::testprefix] || $::testprefix eq ""} {
|
||||
# error "no test prefix"
|
||||
# }
|
||||
puts "\nExpected: \[$expected\]\n Got: \[$result\]"
|
||||
output2_if_no_verbose -nonewline $name...
|
||||
output2 "\nExpected: \[$expected\]\n Got: \[$result\]"
|
||||
fail_test $name
|
||||
} else {
|
||||
puts " Ok"
|
||||
output1 " Ok"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
puts " Omitted"
|
||||
output1 " Omitted"
|
||||
omit_test $name "pattern mismatch" 0
|
||||
}
|
||||
flush stdout
|
||||
@@ -837,7 +931,7 @@ proc delete_all_data {} {
|
||||
# Return the number of microseconds per statement.
|
||||
#
|
||||
proc speed_trial {name numstmt units sql} {
|
||||
puts -nonewline [format {%-21.21s } $name...]
|
||||
output2 -nonewline [format {%-21.21s } $name...]
|
||||
flush stdout
|
||||
set speed [time {sqlite3_exec_nr db $sql}]
|
||||
set tm [lindex $speed 0]
|
||||
@@ -847,13 +941,13 @@ proc speed_trial {name numstmt units sql} {
|
||||
set rate [format %20.5f [expr {1000000.0*$numstmt/$tm}]]
|
||||
}
|
||||
set u2 $units/s
|
||||
puts [format {%12d uS %s %s} $tm $rate $u2]
|
||||
output2 [format {%12d uS %s %s} $tm $rate $u2]
|
||||
global total_time
|
||||
set total_time [expr {$total_time+$tm}]
|
||||
lappend ::speed_trial_times $name $tm
|
||||
}
|
||||
proc speed_trial_tcl {name numstmt units script} {
|
||||
puts -nonewline [format {%-21.21s } $name...]
|
||||
output2 -nonewline [format {%-21.21s } $name...]
|
||||
flush stdout
|
||||
set speed [time {eval $script}]
|
||||
set tm [lindex $speed 0]
|
||||
@@ -863,7 +957,7 @@ proc speed_trial_tcl {name numstmt units script} {
|
||||
set rate [format %20.5f [expr {1000000.0*$numstmt/$tm}]]
|
||||
}
|
||||
set u2 $units/s
|
||||
puts [format {%12d uS %s %s} $tm $rate $u2]
|
||||
output2 [format {%12d uS %s %s} $tm $rate $u2]
|
||||
global total_time
|
||||
set total_time [expr {$total_time+$tm}]
|
||||
lappend ::speed_trial_times $name $tm
|
||||
@@ -875,19 +969,19 @@ proc speed_trial_init {name} {
|
||||
sqlite3 versdb :memory:
|
||||
set vers [versdb one {SELECT sqlite_source_id()}]
|
||||
versdb close
|
||||
puts "SQLite $vers"
|
||||
output2 "SQLite $vers"
|
||||
}
|
||||
proc speed_trial_summary {name} {
|
||||
global total_time
|
||||
puts [format {%-21.21s %12d uS TOTAL} $name $total_time]
|
||||
output2 [format {%-21.21s %12d uS TOTAL} $name $total_time]
|
||||
|
||||
if { 0 } {
|
||||
sqlite3 versdb :memory:
|
||||
set vers [lindex [versdb one {SELECT sqlite_source_id()}] 0]
|
||||
versdb close
|
||||
puts "CREATE TABLE IF NOT EXISTS time(version, script, test, us);"
|
||||
output2 "CREATE TABLE IF NOT EXISTS time(version, script, test, us);"
|
||||
foreach {test us} $::speed_trial_times {
|
||||
puts "INSERT INTO time VALUES('$vers', '$name', '$test', $us);"
|
||||
output2 "INSERT INTO time VALUES('$vers', '$name', '$test', $us);"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -931,75 +1025,75 @@ proc finalize_testing {} {
|
||||
}
|
||||
}
|
||||
if {$nKnown>0} {
|
||||
puts "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\
|
||||
output2 "[expr {$nErr-$nKnown}] new errors and $nKnown known errors\
|
||||
out of $nTest tests"
|
||||
} else {
|
||||
puts "$nErr errors out of $nTest tests"
|
||||
output2 "$nErr errors out of $nTest tests"
|
||||
}
|
||||
if {$nErr>$nKnown} {
|
||||
puts -nonewline "Failures on these tests:"
|
||||
output2 -nonewline "Failures on these tests:"
|
||||
foreach x [set_test_counter fail_list] {
|
||||
if {![info exists known_error($x)]} {puts -nonewline " $x"}
|
||||
if {![info exists known_error($x)]} {output2 -nonewline " $x"}
|
||||
}
|
||||
puts ""
|
||||
output2 ""
|
||||
}
|
||||
foreach warning [set_test_counter warn_list] {
|
||||
puts "Warning: $warning"
|
||||
output2 "Warning: $warning"
|
||||
}
|
||||
run_thread_tests 1
|
||||
if {[llength $omitList]>0} {
|
||||
puts "Omitted test cases:"
|
||||
output2 "Omitted test cases:"
|
||||
set prec {}
|
||||
foreach {rec} [lsort $omitList] {
|
||||
if {$rec==$prec} continue
|
||||
set prec $rec
|
||||
puts [format { %-12s %s} [lindex $rec 0] [lindex $rec 1]]
|
||||
output2 [format { %-12s %s} [lindex $rec 0] [lindex $rec 1]]
|
||||
}
|
||||
}
|
||||
if {$nErr>0 && ![working_64bit_int]} {
|
||||
puts "******************************************************************"
|
||||
puts "N.B.: The version of TCL that you used to build this test harness"
|
||||
puts "is defective in that it does not support 64-bit integers. Some or"
|
||||
puts "all of the test failures above might be a result from this defect"
|
||||
puts "in your TCL build."
|
||||
puts "******************************************************************"
|
||||
output2 "******************************************************************"
|
||||
output2 "N.B.: The version of TCL that you used to build this test harness"
|
||||
output2 "is defective in that it does not support 64-bit integers. Some or"
|
||||
output2 "all of the test failures above might be a result from this defect"
|
||||
output2 "in your TCL build."
|
||||
output2 "******************************************************************"
|
||||
}
|
||||
if {$::cmdlinearg(binarylog)} {
|
||||
vfslog finalize binarylog
|
||||
}
|
||||
if {$sqlite_open_file_count} {
|
||||
puts "$sqlite_open_file_count files were left open"
|
||||
output2 "$sqlite_open_file_count files were left open"
|
||||
incr nErr
|
||||
}
|
||||
if {[lindex [sqlite3_status SQLITE_STATUS_MALLOC_COUNT 0] 1]>0 ||
|
||||
[sqlite3_memory_used]>0} {
|
||||
puts "Unfreed memory: [sqlite3_memory_used] bytes in\
|
||||
output2 "Unfreed memory: [sqlite3_memory_used] bytes in\
|
||||
[lindex [sqlite3_status SQLITE_STATUS_MALLOC_COUNT 0] 1] allocations"
|
||||
incr nErr
|
||||
ifcapable memdebug||mem5||(mem3&&debug) {
|
||||
puts "Writing unfreed memory log to \"./memleak.txt\""
|
||||
output2 "Writing unfreed memory log to \"./memleak.txt\""
|
||||
sqlite3_memdebug_dump ./memleak.txt
|
||||
}
|
||||
} else {
|
||||
puts "All memory allocations freed - no leaks"
|
||||
output2 "All memory allocations freed - no leaks"
|
||||
ifcapable memdebug||mem5 {
|
||||
sqlite3_memdebug_dump ./memusage.txt
|
||||
}
|
||||
}
|
||||
show_memstats
|
||||
puts "Maximum memory usage: [sqlite3_memory_highwater 1] bytes"
|
||||
puts "Current memory usage: [sqlite3_memory_highwater] bytes"
|
||||
output2 "Maximum memory usage: [sqlite3_memory_highwater 1] bytes"
|
||||
output2 "Current memory usage: [sqlite3_memory_highwater] bytes"
|
||||
if {[info commands sqlite3_memdebug_malloc_count] ne ""} {
|
||||
puts "Number of malloc() : [sqlite3_memdebug_malloc_count] calls"
|
||||
output2 "Number of malloc() : [sqlite3_memdebug_malloc_count] calls"
|
||||
}
|
||||
if {$::cmdlinearg(malloctrace)} {
|
||||
puts "Writing mallocs.sql..."
|
||||
output2 "Writing mallocs.sql..."
|
||||
memdebug_log_sql
|
||||
sqlite3_memdebug_log stop
|
||||
sqlite3_memdebug_log clear
|
||||
|
||||
if {[sqlite3_memory_used]>0} {
|
||||
puts "Writing leaks.sql..."
|
||||
output2 "Writing leaks.sql..."
|
||||
sqlite3_memdebug_log sync
|
||||
memdebug_log_sql leaks.sql
|
||||
}
|
||||
@@ -1020,30 +1114,30 @@ proc show_memstats {} {
|
||||
set y [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
|
||||
set val [format {now %10d max %10d max-size %10d} \
|
||||
[lindex $x 1] [lindex $x 2] [lindex $y 2]]
|
||||
puts "Memory used: $val"
|
||||
output1 "Memory used: $val"
|
||||
set x [sqlite3_status SQLITE_STATUS_MALLOC_COUNT 0]
|
||||
set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]]
|
||||
puts "Allocation count: $val"
|
||||
output1 "Allocation count: $val"
|
||||
set x [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0]
|
||||
set y [sqlite3_status SQLITE_STATUS_PAGECACHE_SIZE 0]
|
||||
set val [format {now %10d max %10d max-size %10d} \
|
||||
[lindex $x 1] [lindex $x 2] [lindex $y 2]]
|
||||
puts "Page-cache used: $val"
|
||||
output1 "Page-cache used: $val"
|
||||
set x [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0]
|
||||
set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]]
|
||||
puts "Page-cache overflow: $val"
|
||||
output1 "Page-cache overflow: $val"
|
||||
set x [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0]
|
||||
set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]]
|
||||
puts "Scratch memory used: $val"
|
||||
output1 "Scratch memory used: $val"
|
||||
set x [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0]
|
||||
set y [sqlite3_status SQLITE_STATUS_SCRATCH_SIZE 0]
|
||||
set val [format {now %10d max %10d max-size %10d} \
|
||||
[lindex $x 1] [lindex $x 2] [lindex $y 2]]
|
||||
puts "Scratch overflow: $val"
|
||||
output1 "Scratch overflow: $val"
|
||||
ifcapable yytrackmaxstackdepth {
|
||||
set x [sqlite3_status SQLITE_STATUS_PARSER_STACK 0]
|
||||
set val [format { max %10d} [lindex $x 2]]
|
||||
puts "Parser stack depth: $val"
|
||||
output2 "Parser stack depth: $val"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1058,7 +1152,7 @@ proc execsql_timed {sql {db db}} {
|
||||
set x [uplevel [list $db eval $sql]]
|
||||
} 1]
|
||||
set tm [lindex $tm 0]
|
||||
puts -nonewline " ([expr {$tm*0.001}]ms) "
|
||||
output1 -nonewline " ([expr {$tm*0.001}]ms) "
|
||||
set x
|
||||
}
|
||||
|
||||
@@ -1595,9 +1689,9 @@ proc do_ioerr_test {testname args} {
|
||||
set nowcksum [cksum]
|
||||
set res [expr {$nowcksum==$::checksum || $nowcksum==$::goodcksum}]
|
||||
if {$res==0} {
|
||||
puts "now=$nowcksum"
|
||||
puts "the=$::checksum"
|
||||
puts "fwd=$::goodcksum"
|
||||
output2 "now=$nowcksum"
|
||||
output2 "the=$::checksum"
|
||||
output2 "fwd=$::goodcksum"
|
||||
}
|
||||
set res
|
||||
} 1
|
||||
@@ -1821,6 +1915,12 @@ proc slave_test_script {script} {
|
||||
interp eval tinterp [list set $var $value]
|
||||
}
|
||||
|
||||
# If output is being copied into a file, share the file-descriptor with
|
||||
# the interpreter.
|
||||
if {[info exists ::G(output_fd)]} {
|
||||
interp share {} $::G(output_fd) tinterp
|
||||
}
|
||||
|
||||
# The alias used to access the global test counters.
|
||||
tinterp alias set_test_counter set_test_counter
|
||||
|
||||
@@ -1889,7 +1989,7 @@ proc slave_test_file {zFile} {
|
||||
|
||||
# Add some info to the output.
|
||||
#
|
||||
puts "Time: $tail $ms ms"
|
||||
output2 "Time: $tail $ms ms"
|
||||
show_memstats
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user