aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/analyzer1.test5
-rw-r--r--test/corruptI.test2
-rw-r--r--test/e_walauto.test1
-rw-r--r--test/extraquick.test16
-rw-r--r--test/filectrl.test1
-rw-r--r--test/fts3d.test2
-rw-r--r--test/fts4incr.test4
-rw-r--r--test/fts4unicode.test14
-rw-r--r--test/fuzzcheck.c44
-rw-r--r--test/fuzzdata1.dbbin4199424 -> 4398080 bytes
-rw-r--r--test/fuzzdata3.dbbin10724352 -> 11777024 bytes
-rw-r--r--test/in.test20
-rw-r--r--test/index5.test6
-rw-r--r--test/index6.test19
-rw-r--r--test/join.test26
-rw-r--r--test/permutations.test17
-rw-r--r--test/progress.test1
-rw-r--r--test/releasetest.tcl7
-rw-r--r--test/select7.test20
-rw-r--r--test/select8.test1
-rw-r--r--test/shared4.test1
-rw-r--r--test/speedtest1.c20
-rw-r--r--test/sqldiff1.test5
-rw-r--r--test/table.test16
-rw-r--r--test/tester.tcl220
-rw-r--r--test/vtab1.test3
-rw-r--r--test/whereG.test37
27 files changed, 415 insertions, 93 deletions
diff --git a/test/analyzer1.test b/test/analyzer1.test
index 7da564ea2..ac46704fb 100644
--- a/test/analyzer1.test
+++ b/test/analyzer1.test
@@ -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
diff --git a/test/corruptI.test b/test/corruptI.test
index 2d4a481c7..64323d960 100644
--- a/test/corruptI.test
+++ b/test/corruptI.test
@@ -204,7 +204,7 @@ do_execsql_test 6.0 {
} {}
do_test 6.1 {
db close
- hexio_write test.db 616 EAFFFFFF0202
+ hexio_write test.db 616 8FFFFFFF7F02
sqlite3 db test.db
breakpoint
execsql { DELETE FROM t1 WHERE rowid=2 }
diff --git a/test/e_walauto.test b/test/e_walauto.test
index a1f4eb707..093b13f94 100644
--- a/test/e_walauto.test
+++ b/test/e_walauto.test
@@ -171,7 +171,6 @@ foreach {tn code} {
#
set ::busy_callback_count 0
proc busy_callback {args} {
- puts Hello
incr ::busy_callback_count
return 0
}
diff --git a/test/extraquick.test b/test/extraquick.test
new file mode 100644
index 000000000..f453564e7
--- /dev/null
+++ b/test/extraquick.test
@@ -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
diff --git a/test/filectrl.test b/test/filectrl.test
index 1d878bf96..28fecee92 100644
--- a/test/filectrl.test
+++ b/test/filectrl.test
@@ -39,7 +39,6 @@ do_test filectrl-1.5 {
do_test filectrl-1.6 {
sqlite3 db test.db
set fn [file_control_tempfilename db]
- puts -nonewline \[$fn\]
set fn
} {/etilqs_/}
db close
diff --git a/test/fts3d.test b/test/fts3d.test
index 5c04ead0a..83af4d2a3 100644
--- a/test/fts3d.test
+++ b/test/fts3d.test
@@ -213,7 +213,7 @@ do_test fts3d-4.matches {
{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \
{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}]
-puts [db eval {SELECT c FROM t1 } ]
+db eval {SELECT c FROM t1 }
check_terms_all fts3d-4.1 {a four is test that this was}
check_doclist_all fts3d-4.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist_all fts3d-4.1.2 four {}
diff --git a/test/fts4incr.test b/test/fts4incr.test
index 17212efce..92104888b 100644
--- a/test/fts4incr.test
+++ b/test/fts4incr.test
@@ -47,7 +47,9 @@ foreach {tn q res} {
do_execsql_test 2.$tn.$s $q $res
set t($s) [lindex [time [list execsql $q] 100] 0]
}
- puts "with optimization: $t(0) without: $t(1)"
+ if {0} {
+ puts "with optimization: $t(0) without: $t(1)"
+ }
}
do_test 2.1 {
diff --git a/test/fts4unicode.test b/test/fts4unicode.test
index f237119a1..500cfcdca 100644
--- a/test/fts4unicode.test
+++ b/test/fts4unicode.test
@@ -362,11 +362,17 @@ ifcapable icu { lappend tokenizers icu }
# Some tests to check that the tokenizers can both identify white-space
# codepoints. All codepoints tested below are of type "Zs" in the
# UnicodeData.txt file.
+#
+# Note that codepoint 6158 has changed from Zs to Cf in recent versions
+# of UnicodeData.txt. So take that into account for the "icu" tests.
+#
foreach T $tokenizers {
do_isspace_test 6.$T.1 $T 32
do_isspace_test 6.$T.2 $T 160
do_isspace_test 6.$T.3 $T 5760
- do_isspace_test 6.$T.4 $T 6158
+ if {$T!="icu"} {
+ do_isspace_test 6.$T.4 $T 6158
+ }
do_isspace_test 6.$T.5 $T 8192
do_isspace_test 6.$T.6 $T 8193
do_isspace_test 6.$T.7 $T 8194
@@ -382,7 +388,11 @@ foreach T $tokenizers {
do_isspace_test 6.$T.17 $T 8287
do_isspace_test 6.$T.18 $T 12288
- do_isspace_test 6.$T.19 $T {32 160 5760 6158}
+ if {$T!="icu"} {
+ do_isspace_test 6.$T.19 $T {32 160 5760 6158}
+ } else {
+ do_isspace_test 6.$T.19 $T {32 160 5760 8192}
+ }
do_isspace_test 6.$T.20 $T {8192 8193 8194 8195}
do_isspace_test 6.$T.21 $T {8196 8197 8198 8199}
do_isspace_test 6.$T.22 $T {8200 8201 8202 8239}
diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c
index 6dc2a6e7f..f637e6463 100644
--- a/test/fuzzcheck.c
+++ b/test/fuzzcheck.c
@@ -10,8 +10,8 @@
**
*************************************************************************
**
-** This is a utility program designed to aid running regressions tests
-** on SQLite library using data from an external fuzzer, such as American
+** This is a utility program designed to aid running regressions tests on
+** the SQLite library using data from an external fuzzer, such as American
** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
**
** This program reads content from an SQLite database file with the following
@@ -25,16 +25,44 @@
** sqlid INTEGER PRIMARY KEY, -- SQL script id
** sqltext TEXT -- Text of SQL statements to run
** );
+** CREATE TABLE IF NOT EXISTS readme(
+** msg TEXT -- Human-readable description of this test collection
+** );
**
** For each database file in the DB table, the SQL text in the XSQL table
-** is run against that database. This program is looking for crashes,
-** assertion faults, and/or memory leaks. No attempt is made to verify
-** the output. The assumption is that either all of the database files
-** or all of the SQL statements are malformed inputs, generated by a fuzzer,
-** that need to be checked to make sure they do not present a security risk.
+** is run against that database. All README.MSG values are printed prior
+** to the start of the test (unless the --quiet option is used). If the
+** DB table is empty, then all entries in XSQL are run against an empty
+** in-memory database.
+**
+** This program is looking for crashes, assertion faults, and/or memory leaks.
+** No attempt is made to verify the output. The assumption is that either all
+** of the database files or all of the SQL statements are malformed inputs,
+** generated by a fuzzer, that need to be checked to make sure they do not
+** present a security risk.
**
** This program also includes some command-line options to help with
-** creation and maintenance of the source content database.
+** creation and maintenance of the source content database. The command
+**
+** ./fuzzcheck database.db --load-sql FILE...
+**
+** Loads all FILE... arguments into the XSQL table. The --load-db option
+** works the same but loads the files into the DB table. The -m option can
+** be used to initialize the README table. The "database.db" file is created
+** if it does not previously exist. Example:
+**
+** ./fuzzcheck new.db --load-sql *.sql
+** ./fuzzcheck new.db --load-db *.db
+** ./fuzzcheck new.db -m 'New test cases'
+**
+** The three commands above will create the "new.db" file and initialize all
+** tables. Then do "./fuzzcheck new.db" to run the tests.
+**
+** DEBUGGING HINTS:
+**
+** If fuzzcheck does crash, it can be run in the debugger and the content
+** of the global variable g.zTextName[] will identify the specific XSQL and
+** DB values that were running when the crash occurred.
*/
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/fuzzdata1.db b/test/fuzzdata1.db
index 222e598a4..4b4a6b574 100644
--- a/test/fuzzdata1.db
+++ b/test/fuzzdata1.db
Binary files differ
diff --git a/test/fuzzdata3.db b/test/fuzzdata3.db
index 376459f2d..34ff5f975 100644
--- a/test/fuzzdata3.db
+++ b/test/fuzzdata3.db
Binary files differ
diff --git a/test/in.test b/test/in.test
index de38c2245..3a42e84b9 100644
--- a/test/in.test
+++ b/test/in.test
@@ -450,28 +450,42 @@ do_test in-12.10 {
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
);
}
-} {1 {only a single result allowed for a SELECT that is part of an expression}}
+} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
do_test in-12.11 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION SELECT a, b FROM t2
);
}
-} {1 {only a single result allowed for a SELECT that is part of an expression}}
+} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_test in-12.12 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
);
}
-} {1 {only a single result allowed for a SELECT that is part of an expression}}
+} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}}
do_test in-12.13 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
);
}
+} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
+do_test in-12.14 {
+ catchsql {
+ SELECT * FROM t2 WHERE a IN (
+ SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2
+ );
+ }
} {1 {only a single result allowed for a SELECT that is part of an expression}}
+do_test in-12.15 {
+ catchsql {
+ SELECT * FROM t2 WHERE a IN (
+ SELECT a, b FROM t3 UNION ALL SELECT a FROM t2
+ );
+ }
+} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
}; #ifcapable compound
diff --git a/test/index5.test b/test/index5.test
index e369d7571..4c0aa0431 100644
--- a/test/index5.test
+++ b/test/index5.test
@@ -67,8 +67,10 @@ do_test 1.3 {
}
set iPrev $iNext
}
- puts -nonewline \
- " (forward=$nForward, back=$nBackward, noncontiguous=$nNoncont)"
+ if {0} {
+ puts -nonewline \
+ " (forward=$nForward, back=$nBackward, noncontiguous=$nNoncont)"
+ }
expr {$nForward > 2*($nBackward + $nNoncont)}
} {1}
diff --git a/test/index6.test b/test/index6.test
index 69fae49fe..e15820290 100644
--- a/test/index6.test
+++ b/test/index6.test
@@ -327,4 +327,23 @@ do_execsql_test index6-8.2 {
3 three value 3
}
+# 2015-06-11. Assertion fault found by AFL
+#
+do_execsql_test index6-9.1 {
+ CREATE TABLE t9(a int, b int, c int);
+ CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
+ INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5),(NULL,7,3);
+ UPDATE t9 SET b=c WHERE a in (10,12,20);
+ SELECT a,b,c,'|' FROM t9 ORDER BY a;
+} {{} 7 3 | 1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}
+do_execsql_test index6-9.2 {
+ DROP TABLE t9;
+ CREATE TABLE t9(a int, b int, c int, PRIMARY KEY(a)) WITHOUT ROWID;
+ CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
+ INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5);
+ UPDATE t9 SET b=c WHERE a in (10,12,20);
+ SELECT a,b,c,'|' FROM t9 ORDER BY a;
+} {1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}
+
+
finish_test
diff --git a/test/join.test b/test/join.test
index 4c83fa6b3..2b6951213 100644
--- a/test/join.test
+++ b/test/join.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
diff --git a/test/permutations.test b/test/permutations.test
index 05c4ff92b..9881efb71 100644
--- a/test/permutations.test
+++ b/test/permutations.test
@@ -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 {
diff --git a/test/progress.test b/test/progress.test
index 993426aa2..f6d722924 100644
--- a/test/progress.test
+++ b/test/progress.test
@@ -164,7 +164,6 @@ do_test progress-1.7 {
}
set ::res [list]
- explain {SELECT a, b, c FROM abc}
db eval {SELECT a, b, c FROM abc} {
lappend ::res $a $b $c
db progress 5 "expr 1"
diff --git a/test/releasetest.tcl b/test/releasetest.tcl
index a120ddf33..6e475c9d2 100644
--- a/test/releasetest.tcl
+++ b/test/releasetest.tcl
@@ -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} {
diff --git a/test/select7.test b/test/select7.test
index 6816b9fcb..9ed535774 100644
--- a/test/select7.test
+++ b/test/select7.test
@@ -15,6 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+set testprefix select7
ifcapable compound {
@@ -201,4 +202,23 @@ do_test select7-7.7 {
}
} {text 123}
+do_execsql_test 8.0 {
+ CREATE TABLE t01(x, y);
+ CREATE TABLE t02(x, y);
+}
+
+do_catchsql_test 8.1 {
+ SELECT * FROM (
+ SELECT * FROM t01 UNION SELECT x FROM t02
+ ) WHERE y=1
+} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
+
+do_catchsql_test 8.2 {
+ CREATE VIEW v0 as SELECT x, y FROM t01 UNION SELECT x FROM t02;
+ EXPLAIN QUERY PLAN SELECT * FROM v0 WHERE x='0' OR y;
+} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
+
+
finish_test
+
+
diff --git a/test/select8.test b/test/select8.test
index 98626641b..39b273949 100644
--- a/test/select8.test
+++ b/test/select8.test
@@ -32,7 +32,6 @@ set result [execsql {
FROM songs
GROUP BY LOWER(artist)
}]
-puts result=$result
do_test select8-1.1 {
execsql {
SELECT DISTINCT artist,sum(timesplayed) AS total
diff --git a/test/shared4.test b/test/shared4.test
index 83925b06e..88959db42 100644
--- a/test/shared4.test
+++ b/test/shared4.test
@@ -16,7 +16,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
-puts hello
# This script is only valid if we are running shared-cache mode in a
# threadsafe-capable database engine.
diff --git a/test/speedtest1.c b/test/speedtest1.c
index 8f3f57955..db343d81f 100644
--- a/test/speedtest1.c
+++ b/test/speedtest1.c
@@ -43,6 +43,9 @@ static const char zHelp[] =
#include <string.h>
#include <ctype.h>
+#if SQLITE_VERSION_NUMBER<3005000
+# define sqlite3_int64 sqlite_int64
+#endif
#ifdef SQLITE_ENABLE_OTA
# include "sqlite3ota.h"
#endif
@@ -143,6 +146,9 @@ static int integerValue(const char *zArg){
/* Return the current wall-clock time, in milliseconds */
sqlite3_int64 speedtest1_timestamp(void){
+#if SQLITE_VERSION_NUMBER<3005000
+ return 0;
+#else
static sqlite3_vfs *clockVfs = 0;
sqlite3_int64 t;
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
@@ -157,6 +163,7 @@ sqlite3_int64 speedtest1_timestamp(void){
t = (sqlite3_int64)(r*86400000.0);
}
return t;
+#endif
}
/* Return a pseudo-random unsigned integer */
@@ -306,7 +313,7 @@ static void printSql(const char *zSql){
if( g.bExplain ) printf("EXPLAIN ");
printf("%.*s;\n", n, zSql);
if( g.bExplain
-#if SQLITE_VERSION_NUMBER>=3007010
+#if SQLITE_VERSION_NUMBER>=3007017
&& ( sqlite3_strglob("CREATE *", zSql)==0
|| sqlite3_strglob("DROP *", zSql)==0
|| sqlite3_strglob("ALTER *", zSql)==0
@@ -374,12 +381,15 @@ void speedtest1_run(void){
}
}
}
+#if SQLITE_VERSION_NUMBER>=3006001
if( g.bReprepare ){
sqlite3_stmt *pNew;
sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
sqlite3_finalize(g.pStmt);
g.pStmt = pNew;
- }else{
+ }else
+#endif
+ {
sqlite3_reset(g.pStmt);
}
}
@@ -1273,6 +1283,7 @@ int main(int argc, char **argv){
fatal_error(zHelp, argv[0]);
}
#endif
+#if SQLITE_VERSION_NUMBER>=3006001
if( nHeap>0 ){
pHeap = malloc( nHeap );
if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
@@ -1296,16 +1307,19 @@ int main(int argc, char **argv){
if( nLook>0 ){
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
}
+#endif
/* Open the database and the input file */
if( sqlite3_open(zDbName, &g.db) ){
fatal_error("Cannot open database file: %s\n", zDbName);
}
+#if SQLITE_VERSION_NUMBER>=3006001
if( nLook>0 && szLook>0 ){
pLook = malloc( nLook*szLook );
rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
}
+#endif
/* Set database connection options */
sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
@@ -1387,6 +1401,7 @@ int main(int argc, char **argv){
sqlite3_close(g.db);
+#if SQLITE_VERSION_NUMBER>=3006001
/* Global memory usage statistics printed after the database connection
** has closed. Memory usage should be zero at this point. */
if( showStats ){
@@ -1407,6 +1422,7 @@ int main(int argc, char **argv){
sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
}
+#endif
/* Release memory */
free( pLook );
diff --git a/test/sqldiff1.test b/test/sqldiff1.test
index 723b7a5e1..3201fb365 100644
--- a/test/sqldiff1.test
+++ b/test/sqldiff1.test
@@ -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
diff --git a/test/table.test b/test/table.test
index faa9712bf..2aec6473e 100644
--- a/test/table.test
+++ b/test/table.test
@@ -808,4 +808,20 @@ do_execsql_test table-17.1 {
SELECT p, q, '|' FROM t3 ORDER BY p;
} {1 1 | 2 2 |}
+# 2015-06-16
+# Ticket [https://www.sqlite.org/src/tktview/873cae2b6e25b1991ce5e9b782f9cd0409b96063]
+# Make sure a CREATE TABLE AS statement correctly rolls back partial changes to the
+# sqlite_master table when the SELECT on the right-hand side aborts.
+#
+do_catchsql_test table-18.1 {
+ DROP TABLE IF EXISTS t1;
+ BEGIN;
+ CREATE TABLE t1 AS SELECT zeroblob(2e20);
+} {1 {string or blob too big}}
+do_execsql_test table-18.2 {
+ COMMIT;
+ PRAGMA integrity_check;
+} {ok}
+
+
finish_test
diff --git a/test/tester.tcl b/test/tester.tcl
index 794ea4a40..8022d6a53 100644
--- a/test/tester.tcl
+++ b/test/tester.tcl
@@ -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
}
@@ -1074,20 +1168,20 @@ proc catchsql {sql {db db}} {
# Do an VDBE code dump on the SQL given
#
proc explain {sql {db db}} {
- puts ""
- puts "addr opcode p1 p2 p3 p4 p5 #"
- puts "---- ------------ ------ ------ ------ --------------- -- -"
+ output2 ""
+ output2 "addr opcode p1 p2 p3 p4 p5 #"
+ output2 "---- ------------ ------ ------ ------ --------------- -- -"
$db eval "explain $sql" {} {
- puts [format {%-4d %-12.12s %-6d %-6d %-6d % -17s %s %s} \
+ output2 [format {%-4d %-12.12s %-6d %-6d %-6d % -17s %s %s} \
$addr $opcode $p1 $p2 $p3 $p4 $p5 $comment
]
}
}
proc explain_i {sql {db db}} {
- puts ""
- puts "addr opcode p1 p2 p3 p4 p5 #"
- puts "---- ------------ ------ ------ ------ ---------------- -- -"
+ output2 ""
+ output2 "addr opcode p1 p2 p3 p4 p5 #"
+ output2 "---- ------------ ------ ------ ------ ---------------- -- -"
# Set up colors for the different opcodes. Scheme is as follows:
@@ -1153,18 +1247,18 @@ proc explain_i {sql {db db}} {
$db eval "explain $sql" {} {
if {[info exists linebreak($addr)]} {
- puts ""
+ output2 ""
}
set I [string repeat " " $x($addr)]
set col ""
catch { set col $color($opcode) }
- puts [format {%-4d %s%s%-12.12s%s %-6d %-6d %-6d % -17s %s %s} \
+ output2 [format {%-4d %s%s%-12.12s%s %-6d %-6d %-6d % -17s %s %s} \
$addr $I $col $opcode $D $p1 $p2 $p3 $p4 $p5 $comment
]
}
- puts "---- ------------ ------ ------ ------ ---------------- -- -"
+ output2 "---- ------------ ------ ------ ------ ---------------- -- -"
}
# Show the VDBE program for an SQL statement but omit the Trace
@@ -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
}
diff --git a/test/vtab1.test b/test/vtab1.test
index cd21153f0..84de4cffa 100644
--- a/test/vtab1.test
+++ b/test/vtab1.test
@@ -56,9 +56,6 @@ ifcapable !vtab||!schema_pragmas {
# We cannot create a virtual table if the module has not been registered.
#
do_test vtab1-1.1.1 {
- explain {
- CREATE VIRTUAL TABLE t1 USING echo;
- }
catchsql {
CREATE VIRTUAL TABLE t1 USING echo;
}
diff --git a/test/whereG.test b/test/whereG.test
index c2c54db45..110ed5dbd 100644
--- a/test/whereG.test
+++ b/test/whereG.test
@@ -230,4 +230,41 @@ do_eqp_test 5.3.3 {
SELECT * FROM t1 WHERE likely(a=?)
} {0 0 0 {SCAN TABLE t1}}
+# 2015-06-18
+# Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70]
+#
+do_execsql_test 6.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(i int, x, y, z);
+ INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4);
+ DROP TABLE IF EXISTS t2;
+ CREATE TABLE t2(i int, bool char);
+ INSERT INTO t2 VALUES(1,'T'), (2,'F');
+ SELECT count(*) FROM t1 LEFT JOIN t2 ON t1.i=t2.i AND bool='T';
+ SELECT count(*) FROM t1 LEFT JOIN t2 ON likely(t1.i=t2.i) AND bool='T';
+} {4 4}
+
+# 2015-06-20
+# Crash discovered by AFL
+#
+do_execsql_test 7.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a, b, PRIMARY KEY(a,b));
+ INSERT INTO t1 VALUES(9,1),(1,2);
+ DROP TABLE IF EXISTS t2;
+ CREATE TABLE t2(x, y, PRIMARY KEY(x,y));
+ INSERT INTO t2 VALUES(3,3),(4,4);
+ SELECT likely(a), x FROM t1, t2 ORDER BY 1, 2;
+} {1 3 1 4 9 3 9 4}
+do_execsql_test 7.1 {
+ SELECT unlikely(a), x FROM t1, t2 ORDER BY 1, 2;
+} {1 3 1 4 9 3 9 4}
+do_execsql_test 7.2 {
+ SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2;
+} {1 3 1 4 9 3 9 4}
+do_execsql_test 7.3 {
+ SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2;
+} {1 3 1 4 9 3 9 4}
+
+
finish_test