mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge the latest trunk enhancements into the begin-concurrent branch.
FossilOrigin-Name: cb5e024b6aed12cb109b481e87d2a5457b5f4f5fc090571e5eef2bd8cf04aaf7
This commit is contained in:
@@ -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
|
||||
|
@@ -391,6 +391,21 @@ static void renderDbSqlForCLI(
|
||||
if( nSql>0 && zSql[nSql-1]!='\n' ) fprintf(out, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** 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.
|
||||
@@ -1847,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"
|
||||
@@ -1873,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"
|
||||
@@ -1887,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 */
|
||||
@@ -1934,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();
|
||||
@@ -1954,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
|
||||
@@ -2044,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;
|
||||
@@ -2062,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]);
|
||||
@@ -2093,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++;
|
||||
@@ -2163,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++){
|
||||
@@ -2452,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 */
|
||||
@@ -2510,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 ){
|
||||
@@ -2616,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;
|
||||
@@ -2634,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 ){
|
||||
|
Binary file not shown.
@@ -1228,7 +1228,7 @@ do_test shell1-8.1 {
|
||||
FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
|
||||
}
|
||||
} {0 47.49000000000000198951966012828052043914794921875}
|
||||
do_test shell1-8.2 {
|
||||
do_test_with_ansi_output shell1-8.2 {
|
||||
catchcmd :memory: {
|
||||
.mode box
|
||||
SELECT ieee754(47.49) AS x;
|
||||
@@ -1238,7 +1238,7 @@ SELECT ieee754(47.49) AS x;
|
||||
├───────────────────────────────┤
|
||||
│ ieee754(6683623321994527,-47) │
|
||||
└───────────────────────────────┘}}
|
||||
do_test shell1-8.3 {
|
||||
do_test_with_ansi_output shell1-8.3 {
|
||||
catchcmd ":memory: --box" {
|
||||
select ieee754(6683623321994527,-47) as x;
|
||||
}
|
||||
@@ -1254,7 +1254,7 @@ do_test shell1-8.4 {
|
||||
+------------------+-----+
|
||||
| 6683623321994527 | -47 |
|
||||
+------------------+-----+}}
|
||||
do_test shell1-8.5 {
|
||||
do_test_with_ansi_output shell1-8.5 {
|
||||
catchcmd ":memory: --box" {
|
||||
create table t(a text, b int);
|
||||
insert into t values ('too long for one line', 1), ('shorter', NULL);
|
||||
|
@@ -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
|
||||
|
@@ -140,7 +140,7 @@ do_test shell4-3.1 {
|
||||
close $fd
|
||||
exec $::CLI_ONLY :memory: --interactive ".read t1.txt"
|
||||
} {squirrel}
|
||||
do_test shell4-3.2 {
|
||||
do_test_with_ansi_output shell4-3.2 {
|
||||
set fd [open t1.txt wb]
|
||||
puts $fd "SELECT 'pound: \302\243';"
|
||||
close $fd
|
||||
|
@@ -553,7 +553,7 @@ Columns renamed during .import shell5.csv due to duplicates:
|
||||
# Tests for preserving utf-8 that is not also ASCII.
|
||||
#
|
||||
|
||||
do_test shell5-6.1 {
|
||||
do_test_with_ansi_output shell5-6.1 {
|
||||
set out [open shell5.csv w]
|
||||
fconfigure $out -translation lf
|
||||
puts $out {あい,うえお}
|
||||
@@ -566,7 +566,7 @@ SELECT * FROM t1;}
|
||||
} {0 { あい = 1
|
||||
うえお = 2}}
|
||||
|
||||
do_test shell5-6.2 {
|
||||
do_test_with_ansi_output shell5-6.2 {
|
||||
set out [open shell5.csv w]
|
||||
fconfigure $out -translation lf
|
||||
puts $out {1,2}
|
||||
|
@@ -35,7 +35,7 @@ do_execsql_test shellA-1.0 {
|
||||
# Initial verification that the database created correctly
|
||||
# and that our calls to the CLI are working.
|
||||
#
|
||||
do_test shellA-1.2 {
|
||||
do_test_with_ansi_output shellA-1.2 {
|
||||
exec {*}$CLI test.db {.mode box --escape symbol} {SELECT * FROM t1;}
|
||||
} {
|
||||
┌───┬──────────────────────────┐
|
||||
@@ -67,7 +67,7 @@ do_test shellA-1.3 {
|
||||
} {
|
||||
^[[31mVT-100 codes^[[0m
|
||||
}
|
||||
do_test shellA-1.4 {
|
||||
do_test_with_ansi_output shellA-1.4 {
|
||||
exec {*}$CLI test.db --escape symbol {SELECT x FROM t1 WHERE a=2;}
|
||||
} {
|
||||
␛[31mVT-100 codes␛[0m
|
||||
@@ -77,7 +77,7 @@ do_test shellA-1.5 {
|
||||
} {
|
||||
^[[31mVT-100 codes^[[0m
|
||||
}
|
||||
do_test shellA-1.6 {
|
||||
do_test_with_ansi_output shellA-1.6 {
|
||||
exec {*}$CLI test.db {.mode list --escape symbol} {SELECT x FROM t1 WHERE a=2;}
|
||||
} {
|
||||
␛[31mVT-100 codes␛[0m
|
||||
@@ -134,7 +134,7 @@ do_test shellA-2.4 {
|
||||
|
||||
# ".mode line"
|
||||
#
|
||||
do_test shellA-3.1 {
|
||||
do_test_with_ansi_output shellA-3.1 {
|
||||
exec {*}$CLI test.db --line --escape symbol \
|
||||
{SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
|
||||
} {
|
||||
@@ -177,7 +177,7 @@ line
|
||||
|
||||
# ".mode box"
|
||||
#
|
||||
do_test shellA-4.1 {
|
||||
do_test_with_ansi_output shellA-4.1 {
|
||||
exec {*}$CLI test.db --box --escape ascii \
|
||||
{SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
|
||||
} {
|
||||
@@ -196,7 +196,7 @@ do_test shellA-4.1 {
|
||||
│ 8 │ last line │
|
||||
└───┴──────────────────────────┘
|
||||
}
|
||||
do_test shellA-4.2 {
|
||||
do_test_with_ansi_output shellA-4.2 {
|
||||
exec {*}$CLI test.db {.mode qbox} {SELECT a, x FROM t1 WHERE a IN (1,2,6,7,8)}
|
||||
} {
|
||||
┌───┬───────────────────────────────────────────┐
|
||||
|
@@ -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);
|
||||
@@ -383,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
|
||||
|
@@ -809,6 +809,15 @@ proc do_test {name cmd expected} {
|
||||
flush stdout
|
||||
}
|
||||
|
||||
# Like do_test except the test is not run in a slave interpreter
|
||||
# on Windows because of issues with ANSI and UTF8 I/O on Win11.
|
||||
#
|
||||
proc do_test_with_ansi_output {name cmd expected} {
|
||||
if {![info exists ::SLAVE] || $::tcl_platform(platform)!="windows"} {
|
||||
uplevel 1 [list do_test $name $cmd $expected]
|
||||
}
|
||||
}
|
||||
|
||||
proc dumpbytes {s} {
|
||||
set r ""
|
||||
for {set i 0} {$i < [string length $s]} {incr i} {
|
||||
|
19
test/vt100-a.sql
Normal file
19
test/vt100-a.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
** Run this script using the "sqlite3" command-line shell
|
||||
** test test formatting of output text that contains
|
||||
** vt100 escape sequences.
|
||||
*/
|
||||
.mode box -escape off
|
||||
CREATE TEMP TABLE t1(a,b,c);
|
||||
INSERT INTO t1 VALUES
|
||||
('one','twotwotwo','thirty-three'),
|
||||
(unistr('\u001b[91mRED\u001b[0m'),'fourfour','fifty-five'),
|
||||
('six','seven','eighty-eight');
|
||||
.print With -escape off
|
||||
SELECT * FROM t1;
|
||||
.mode box -escape ascii
|
||||
.print With -escape ascii
|
||||
SELECT * FROM t1;
|
||||
.mode box -escape symbol
|
||||
.print With -escape symbol
|
||||
SELECT * FROM t1;
|
Reference in New Issue
Block a user