aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/bloom1.test41
-rw-r--r--test/fuzzcheck.c96
-rw-r--r--test/shell2.test12
-rw-r--r--test/tabfunc01.test30
4 files changed, 160 insertions, 19 deletions
diff --git a/test/bloom1.test b/test/bloom1.test
index 151f364ae..f8efcc184 100644
--- a/test/bloom1.test
+++ b/test/bloom1.test
@@ -183,6 +183,47 @@ do_execsql_test 4.3 {
do_execsql_test 4.4 {
SELECT * FROM t0 LEFT JOIN t1 LEFT JOIN t2 ON (b NOTNULL)==(c IN ()) WHERE c;
} {xyz {} 7.0}
+
+reset_db
+do_execsql_test 5.0 {
+ CREATE TABLE t1 (c1);
+ INSERT INTO t1 VALUES (101);
+ CREATE TABLE t2 ( x );
+ INSERT INTO t2 VALUES(404);
+}
+
+do_execsql_test 5.1 {
+ SELECT 'val' in (
+ select 'val' from ( select 'valueB' from t1 order by 1 )
+ union all
+ select 'val'
+ );
+} {1}
+
+do_execsql_test 5.2 {
+ select * from t2
+ where 'val' in (
+ select 'val' from ( select 'valueB' from t1 order by 1 )
+ union all
+ select 'val'
+ );
+} {404}
+
+do_execsql_test 5.3 {
+ SELECT subq_1.c_0 as c_0
+ FROM ( SELECT 0 as c_0) as subq_1
+ WHERE (subq_1.c_0) IN (
+ SELECT subq_2.c_0 as c_0
+ FROM (
+ SELECT 0 as c_0
+ FROM t1 as ref_1
+ WHERE (ref_1.c1) = (2)
+ ORDER BY c_0 desc
+ ) as subq_2
+ UNION ALL
+ SELECT 0 as c_0
+ );
+} {0}
finish_test
diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c
index 140ad6944..09898d7b3 100644
--- a/test/fuzzcheck.c
+++ b/test/fuzzcheck.c
@@ -88,6 +88,11 @@
#include "sqlite3recover.h"
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define FLEXARRAY
+#else
+# define FLEXARRAY 1
+#endif
#ifdef __unix__
@@ -129,9 +134,12 @@ struct Blob {
int id; /* Id of this Blob */
int seq; /* Sequence number */
int sz; /* Size of this Blob in bytes */
- unsigned char a[1]; /* Blob content. Extra space allocated as needed. */
+ unsigned char a[FLEXARRAY]; /* Blob content. Allocated as needed. */
};
+/* Size in bytes of a Blob object sufficient to store N byte of content */
+#define SZ_BLOB(N) (offsetof(Blob,a) + (((N)+7)&~7))
+
/*
** Maximum number of files in the in-memory virtual filesystem.
*/
@@ -384,6 +392,21 @@ static void renderDbSqlForCLI(
}
/*
+** Find the tail (the last component) of a pathname.
+*/
+static const char *pathTail(const char *zPath){
+ const char *zTail = zPath;
+ while( zPath[0] ){
+ if( zPath[0]=='/' && zPath[1]!=0 ) zTail = &zPath[1];
+#ifndef __unix__
+ if( zPath[0]=='\\' && zPath[1]!=0 ) zTail = &zPath[1];
+#endif
+ zPath++;
+ }
+ return zTail;
+}
+
+/*
** Read the complete content of a file into memory. Add a 0x00 terminator
** and return a pointer to the result.
**
@@ -512,13 +535,15 @@ static void blobListLoadFromDb(
int *pN, /* OUT: Write number of blobs loaded here */
Blob **ppList /* OUT: Write the head of the blob list here */
){
- Blob head;
+ Blob *head;
Blob *p;
sqlite3_stmt *pStmt;
int n = 0;
int rc;
char *z2;
+ unsigned char tmp[SZ_BLOB(8)];
+ head = (Blob*)tmp;
if( firstId>0 ){
z2 = sqlite3_mprintf("%s WHERE rowid BETWEEN %d AND %d", zSql,
firstId, lastId);
@@ -528,11 +553,11 @@ static void blobListLoadFromDb(
rc = sqlite3_prepare_v2(db, z2, -1, &pStmt, 0);
sqlite3_free(z2);
if( rc ) fatalError("%s", sqlite3_errmsg(db));
- head.pNext = 0;
- p = &head;
+ head->pNext = 0;
+ p = head;
while( SQLITE_ROW==sqlite3_step(pStmt) ){
int sz = sqlite3_column_bytes(pStmt, 1);
- Blob *pNew = safe_realloc(0, sizeof(*pNew)+sz );
+ Blob *pNew = safe_realloc(0, SZ_BLOB(sz+1));
pNew->id = sqlite3_column_int(pStmt, 0);
pNew->sz = sz;
pNew->seq = n++;
@@ -544,7 +569,7 @@ static void blobListLoadFromDb(
}
sqlite3_finalize(pStmt);
*pN = n;
- *ppList = head.pNext;
+ *ppList = head->pNext;
}
/*
@@ -1837,6 +1862,7 @@ static void showHelp(void){
"Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
"each database, checking for crashes and memory leaks.\n"
"Options:\n"
+" --brief Output only a summary of results at the end\n"
" --cell-size-check Set the PRAGMA cell_size_check=ON\n"
" --dbid M..N Use only the databases where dbid between M and N\n"
" \"M..\" for M and afterwards. Just \"M\" for M only\n"
@@ -1863,6 +1889,7 @@ static void showHelp(void){
" --result-trace Show the results of each SQL command\n"
" --script Output CLI script instead of running tests\n"
" --skip N Skip the first N test cases\n"
+" --slice M N Run only the M-th out of each group of N tests\n"
" --spinner Use a spinner to show progress\n"
" --sqlid M..N Use only SQL where sqlid between M..N\n"
" \"M..\" for M and afterwards. Just \"M\" for M only\n"
@@ -1877,6 +1904,7 @@ static void showHelp(void){
int main(int argc, char **argv){
sqlite3_int64 iBegin; /* Start time of this program */
int quietFlag = 0; /* True if --quiet or -q */
+ int briefFlag = 0; /* Output summary report at the end */
int verboseFlag = 0; /* True if --verbose or -v */
char *zInsSql = 0; /* SQL statement for --load-db or --load-sql */
int iFirstInsArg = 0; /* First argv[] for --load-db or --load-sql */
@@ -1924,6 +1952,8 @@ int main(int argc, char **argv){
int nV; /* How much to increase verbosity with -vvvv */
sqlite3_int64 tmStart; /* Start of each test */
int iEstTime = 0; /* LPF for the time-to-go */
+ int iSliceSz = 0; /* Divide the test space into this many pieces */
+ int iSliceIdx = 0; /* Only run the piece with this index */
sqlite3_config(SQLITE_CONFIG_URI,1);
registerOomSimulator();
@@ -1944,6 +1974,12 @@ int main(int argc, char **argv){
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
+ if( strcmp(z,"brief")==0 ){
+ briefFlag = 1;
+ quietFlag = 1;
+ verboseFlag = 1;
+ eVerbosity = 0;
+ }else
if( strcmp(z,"cell-size-check")==0 ){
cellSzCkFlag = 1;
}else
@@ -2034,6 +2070,7 @@ int main(int argc, char **argv){
g.uRandom = atoi(argv[++i]);
}else
if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
+ briefFlag = 0;
quietFlag = 1;
verboseFlag = 0;
eVerbosity = 0;
@@ -2052,12 +2089,19 @@ int main(int argc, char **argv){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
nSkip = atoi(argv[++i]);
}else
+ if( strcmp(z,"slice")==0 ){
+ if( i>=argc-2 ) fatalError("missing arguments on %s", argv[i]);
+ iSliceIdx = integerValue(argv[++i]);
+ iSliceSz = integerValue(argv[++i]);
+ /* --slice implices --brief */
+ briefFlag = 1;
+ quietFlag = 1;
+ verboseFlag = 1;
+ eVerbosity = 0;
+ }else
if( strcmp(z,"spinner")==0 ){
bSpinner = 1;
}else
- if( strcmp(z,"timer")==0 ){
- bTimer = 1;
- }else
if( strcmp(z,"sqlid")==0 ){
const char *zDotDot;
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
@@ -2083,10 +2127,14 @@ int main(int argc, char **argv){
fatalError("timeout is not available on non-unix systems");
#endif
}else
+ if( strcmp(z,"timer")==0 ){
+ bTimer = 1;
+ }else
if( strcmp(z,"vdbe-debug")==0 ){
bVdbeDebug = 1;
}else
if( strcmp(z,"verbose")==0 ){
+ briefFlag = 0;
quietFlag = 0;
verboseFlag++;
eVerbosity++;
@@ -2153,6 +2201,12 @@ int main(int argc, char **argv){
fatalError("cannot import into more than one database");
}
}
+ if( iSliceSz<=iSliceIdx
+ || iSliceSz<=0
+ || iSliceIdx<0
+ ){
+ iSliceSz = iSliceIdx = 0;
+ }
/* Process each source database separately */
for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
@@ -2442,6 +2496,10 @@ int main(int argc, char **argv){
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
tmStart = timeOfDay();
if( isDbSql(pSql->a, pSql->sz) ){
+ if( iSliceSz>0 && (nTest%iSliceSz)!=iSliceIdx ){
+ nTest++;
+ continue;
+ }
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
if( bScript ){
/* No progress output */
@@ -2500,6 +2558,10 @@ int main(int argc, char **argv){
for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){
int openFlags;
const char *zVfs = "inmem";
+ if( iSliceSz>0 && (nTest%iSliceSz)!=iSliceIdx ){
+ nTest++;
+ continue;
+ }
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
pSql->id, pDb->id);
if( bScript ){
@@ -2606,7 +2668,20 @@ int main(int argc, char **argv){
}
}
}
- if( bScript ){
+ if( briefFlag ){
+ sqlite3_int64 iElapse = timeOfDay() - iBegin;
+ if( iSliceSz>0 ){
+ printf("%s %s: slice %d/%d of %d tests, %d.%03d seconds\n",
+ pathTail(argv[0]), pathTail(g.zDbFile),
+ iSliceIdx, iSliceSz, nTest,
+ (int)(iElapse/1000), (int)(iElapse%1000));
+ }else{
+ printf("%s %s: 0 errors, %d tests, %d.%03d seconds\n",
+ pathTail(argv[0]), pathTail(g.zDbFile), nTest,
+ (int)(iElapse/1000), (int)(iElapse%1000));
+ }
+ iBegin = timeOfDay();
+ }else if( bScript ){
/* No progress output */
}else if( bSpinner ){
int nTotal = g.nDb*g.nSql;
@@ -2624,6 +2699,7 @@ int main(int argc, char **argv){
} /* End loop over all source databases */
+
if( !quietFlag && !bScript ){
sqlite3_int64 iElapse = timeOfDay() - iBegin;
if( g.nInvariant ){
diff --git a/test/shell2.test b/test/shell2.test
index ee5ae4bdd..3f9fec9ef 100644
--- a/test/shell2.test
+++ b/test/shell2.test
@@ -224,24 +224,24 @@ do_test shell2-1.4.10 {
set res [catchcmd :memory: [string trim {
SELECT * FROM generate_series(9223372036854775807,9223372036854775807,1);
SELECT * FROM generate_series(9223372036854775807,9223372036854775807,-1);
- SELECT avg(rowid),min(value),max(value) FROM generate_series(
+ SELECT avg(value),min(value),max(value) FROM generate_series(
-9223372036854775808,9223372036854775807,1085102592571150095);
SELECT * FROM generate_series(-9223372036854775808,9223372036854775807,
9223372036854775807);
- SELECT value,rowid FROM generate_series(-4611686018427387904,
+ SELECT value FROM generate_series(-4611686018427387904,
4611686018427387904, 4611686018427387904) ORDER BY value DESC;
SELECT * FROM generate_series(0,-2,-1);
SELECT * FROM generate_series(0,-2);
SELECT * FROM generate_series(0,2) LIMIT 3;}]]
} {0 {9223372036854775807
9223372036854775807
-9.5|-9223372036854775808|9223372036854775807
+-0.5|-9223372036854775808|9223372036854775807
-9223372036854775808
-1
9223372036854775806
-4611686018427387904|3
-0|2
--4611686018427387904|1
+4611686018427387904
+0
+-4611686018427387904
0
-1
-2
diff --git a/test/tabfunc01.test b/test/tabfunc01.test
index b6797171e..c16fb9bec 100644
--- a/test/tabfunc01.test
+++ b/test/tabfunc01.test
@@ -61,10 +61,10 @@ do_execsql_test tabfunc01-1.8 {
} {30 25 20 15 10 5 0}
do_execsql_test tabfunc01-1.9 {
SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC;
-} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
+} {30 30 25 25 20 20 15 15 10 10 5 5 0 0}
do_execsql_test tabfunc01-1.10 {
SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC;
-} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
+} {30 30 25 25 20 20 15 15 10 10 5 5 0 0}
do_execsql_test tabfunc01-1.20 {
CREATE VIEW v1(a,b) AS VALUES(1,2),(3,4);
@@ -181,6 +181,19 @@ do_execsql_test tabfunc01-4.4 {
SELECT * FROM (generate_series(1,5,2)) AS x LIMIT 10;
} {1 3 5}
+# 2025-03-13 forum post bf2dc8e909983511
+#
+do_execsql_test tabfunc01-5.1 {
+ SELECT value
+ FROM generate_series(60,73,6)
+ WHERE value=66;
+} 66
+do_execsql_test tabfunc01-5.2 {
+ SELECT value
+ FROM generate_series(73,60,-6)
+ WHERE value=67;
+} 67
+
# The next series of tests is verifying that virtual table are able
# to optimize the IN operator, even on terms that are not marked "omit".
# When the generate_series virtual table is compiled for the testfixture,
@@ -370,7 +383,18 @@ do_execsql_test 1100 {
where (ref_3.value) in (select 1);
} {1}
-
+# 2025-03-18 /forumpost/1e17219c88
+# The generate_series() table-valued function is modified so that its
+# rowid is always its value. That way it can be used on the RHS of a
+# RIGHT JOIN.
+#
+do_execsql_test 1200 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(value INT);
+ INSERT INTO t1 VALUES (1),(2),(3);
+ SELECT t1.value, t2.value
+ FROM t1 RIGHT JOIN generate_series(1,3,1) AS t2 USING(value);
+} {1 1 2 2 3 3}
# Free up memory allocations
intarray_addr