1
0
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: d6f6ee5cbcd9b263bc2423ce90700ec238deea212d32888fa9302fa2479b7d99
This commit is contained in:
drh
2022-05-28 14:25:10 +00:00
62 changed files with 5346 additions and 443 deletions

View File

@@ -21,6 +21,7 @@ ifcapable !altertable {
return
}
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
@@ -47,6 +48,7 @@ do_faultsim_test 1 -prep {
faultsim_test_result {0 {}} $::TMPDBERROR
}
#-------------------------------------------------------------------------
# dbsqlfuzz e3dd84cda3848016a6a6024c7249d09bc2ef2615
#
@@ -59,6 +61,11 @@ do_execsql_test 2.0 {
SELECT a FROM cte1
), 1);
END;
CREATE TRIGGER r1 AFTER INSERT ON t2 BEGIN
UPDATE t2 SET k=1 FROM t2 AS one, t2 AS two NATURAL JOIN t2 AS three
WHERE one.k=two.v;
END;
}
faultsim_save_and_close

View File

@@ -645,7 +645,7 @@ do_execsql_test 26.5 {
} {}
do_catchsql_test 26.6 {
ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger xx: ambiguous column name: xx}}
} {1 {error in trigger xx: no such column: xx}}
#-------------------------------------------------------------------------

163
test/altertrig.test Normal file
View File

@@ -0,0 +1,163 @@
# 2022 May 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# 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.
#
#*************************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix altertrig
# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
finish_test
return
}
proc collapse_whitespace {in} {
regsub -all {[ \t\n]+} [string trim $in] { }
}
proc do_whitespace_sql_test {tn sql res} {
set got [execsql $sql]
set wgot [list]
set wres [list]
foreach g $got { lappend wgot [collapse_whitespace $g] }
foreach r $res { lappend wres [collapse_whitespace $r] }
uplevel [list do_test $tn [list set {} $wgot] $wres]
}
do_execsql_test 1.0 {
CREATE TABLE t1(x);
CREATE TABLE t2(y);
CREATE TABLE t3(z);
CREATE TABLE t4(a);
CREATE TRIGGER r1 INSERT ON t1 BEGIN
UPDATE t1 SET d='xyz' FROM t2, t3;
END;
}
do_whitespace_sql_test 1.1 {
ALTER TABLE t3 RENAME TO t5;
SELECT sql FROM sqlite_schema WHERE type='trigger';
} {{
CREATE TRIGGER r1 INSERT ON t1 BEGIN
UPDATE t1 SET d='xyz' FROM t2, "t5";
END
}}
do_execsql_test 1.2 {
DROP TRIGGER r1;
CREATE TRIGGER r1 INSERT ON t1 BEGIN
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM t5);
END;
}
do_whitespace_sql_test 1.3 {
ALTER TABLE t5 RENAME TO t3;
SELECT sql FROM sqlite_schema WHERE type='trigger';
} {{
CREATE TRIGGER r1 INSERT ON t1 BEGIN
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM "t3");
END
}}
foreach {tn alter update final} {
1 {
ALTER TABLE t3 RENAME TO t10
} {
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM t3)
} {
UPDATE t1 SET d='xyz' FROM t2, (SELECT * FROM "t10")
}
2 {
ALTER TABLE t3 RENAME TO t10
} {
UPDATE t1 SET a='xyz' FROM t3, (SELECT * FROM (SELECT e FROM t3))
} {
UPDATE t1 SET a='xyz' FROM "t10", (SELECT * FROM (SELECT e FROM "t10"))
}
3 {
ALTER TABLE t3 RENAME e TO abc
} {
UPDATE t1 SET a='xyz' FROM t3, (SELECT * FROM (SELECT e FROM t3))
} {
UPDATE t1 SET a='xyz' FROM t3, (SELECT * FROM (SELECT abc FROM t3))
}
4 {
ALTER TABLE t2 RENAME c TO abc
} {
UPDATE t1 SET a='xyz' FROM t3, (SELECT 1 FROM t2 WHERE c)
} {
UPDATE t1 SET a='xyz' FROM t3, (SELECT 1 FROM t2 WHERE abc)
}
5 {
ALTER TABLE t2 RENAME c TO abc
} {
UPDATE t1 SET a=t2.c FROM t2
} {
UPDATE t1 SET a=t2.abc FROM t2
}
6 {
ALTER TABLE t2 RENAME c TO abc
} {
UPDATE t1 SET a=t2.c FROM t2, t3
} {
UPDATE t1 SET a=t2.abc FROM t2, t3
}
7 {
ALTER TABLE t4 RENAME e TO abc
} {
UPDATE t1 SET a=1 FROM t3 NATURAL JOIN t4 WHERE t4.e=a
} {
UPDATE t1 SET a=1 FROM t3 NATURAL JOIN t4 WHERE t4.abc=a
}
8 {
ALTER TABLE t4 RENAME TO abc
} {
UPDATE t1 SET a=1 FROM t3 NATURAL JOIN t4 WHERE t4.e=a
} {
UPDATE t1 SET a=1 FROM t3 NATURAL JOIN "abc" WHERE "abc".e=a
}
} {
reset_db
do_execsql_test 2.$tn.1 {
CREATE TABLE t1(a,b);
CREATE TABLE t2(c,d);
CREATE TABLE t3(e,f);
CREATE TABLE t4(e,f);
}
do_execsql_test 2.$tn.2 "
CREATE TRIGGER r1 INSERT ON t1 BEGIN
$update;
END
"
do_execsql_test 2.$tn.3 $alter
do_whitespace_sql_test 2.$tn.4 {
SELECT sqL FROM sqlite_schema WHERE type='trigger'
} "{
CREATE TRIGGER r1 INSERT ON t1 BEGIN
$final;
END
}"
}
finish_test

View File

@@ -618,11 +618,12 @@ foreach {tn select res} {
} {
do_join_test e_select-1.7.$tn $select $res
}
# EVIDENCE-OF: R-42531-52874 If the join-operator is a "LEFT JOIN" or
# EVIDENCE-OF: R-24610-05866 If the join-operator is a "LEFT JOIN" or
# "LEFT OUTER JOIN", then after the ON or USING filtering clauses have
# been applied, an extra row is added to the output for each row in the
# original left-hand input dataset that corresponds to no rows at all in
# the composite dataset (if any).
# original left-hand input dataset that does not match any row in the
# right-hand dataset.
#
do_execsql_test e_select-1.8.0 {
CREATE TABLE t7(a, b, c);

View File

@@ -181,29 +181,53 @@ if {[working_64bit_int]} {
}
test_expr expr-1.111 {i1=NULL, i2=8} {i1 IS i2} 0
test_expr expr-1.111b {i1=NULL, i2=8} {i1 IS NOT DISTINCT FROM i2} 0
test_expr expr-1.112 {i1=NULL, i2=NULL} {i1 IS i2} 1
test_expr expr-1.112b {i1=NULL, i2=NULL} {i1 IS NOT DISTINCT FROM i2} 1
test_expr expr-1.113 {i1=6, i2=NULL} {i1 IS i2} 0
test_expr expr-1.113b {i1=6, i2=NULL} {i1 IS NOT DISTINCT FROM i2} 0
test_expr expr-1.114 {i1=6, i2=6} {i1 IS i2} 1
test_expr expr-1.114b {i1=6, i2=6} {i1 IS NOT DISTINCT FROM i2} 1
test_expr expr-1.115 {i1=NULL, i2=8} \
{CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.115b {i1=NULL, i2=8} \
{CASE WHEN i1 IS NOT DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.116 {i1=NULL, i2=NULL} \
{CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.116b {i1=NULL, i2=NULL} \
{CASE WHEN i1 IS NOT DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.117 {i1=6, i2=NULL} \
{CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.117b {i1=6, i2=NULL} \
{CASE WHEN i1 IS NOT DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.118 {i1=8, i2=8} \
{CASE WHEN i1 IS i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.118b {i1=8, i2=8} \
{CASE WHEN i1 IS NOT DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.119 {i1=NULL, i2=8} {i1 IS NOT i2} 1
test_expr expr-1.119b {i1=NULL, i2=8} {i1 IS DISTINCT FROM i2} 1
test_expr expr-1.120 {i1=NULL, i2=NULL} {i1 IS NOT i2} 0
test_expr expr-1.120b {i1=NULL, i2=NULL} {i1 IS DISTINCT FROM i2} 0
test_expr expr-1.121 {i1=6, i2=NULL} {i1 IS NOT i2} 1
test_expr expr-1.121b {i1=6, i2=NULL} {i1 IS DISTINCT FROM i2} 1
test_expr expr-1.122 {i1=6, i2=6} {i1 IS NOT i2} 0
test_expr expr-1.122b {i1=6, i2=6} {i1 IS DISTINCT FROM i2} 0
test_expr expr-1.123 {i1=NULL, i2=8} \
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.123b {i1=NULL, i2=8} \
{CASE WHEN i1 IS DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.124 {i1=NULL, i2=NULL} \
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.124b {i1=NULL, i2=NULL} \
{CASE WHEN i1 IS DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.125 {i1=6, i2=NULL} \
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.125b {i1=6, i2=NULL} \
{CASE WHEN i1 IS DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} yes
test_expr expr-1.126 {i1=8, i2=8} \
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
test_expr expr-1.126b {i1=8, i2=8} \
{CASE WHEN i1 IS DISTINCT FROM i2 THEN 'yes' ELSE 'no' END} no
do_catchsql_test expr-1.127 {
SELECT 1 IS #1;

View File

@@ -60,6 +60,12 @@ do_execsql_test func7-pg-170 {
do_execsql_test func7-pg-180 {
SELECT log10(1000.0)
} {3.0}
do_execsql_test func7-pg-181 {
SELECT format('%.30f', log10(100.0) );
} {2.000000000000000000000000000000}
do_execsql_test func7-pg-182 {
SELECT format('%.30f', ln(exp(2.0)) );
} {2.000000000000000000000000000000}
do_execsql_test func7-pg-190 {
SELECT log(2.0, 64.0)
} {6.0}

View File

@@ -798,4 +798,13 @@ do_execsql_test in-20.1 {
SELECT (1 IN (2 IS TRUE));
} {1}
# Forum post: https://sqlite.org/forum/forumpost/5782619992.
#
reset_db
do_execsql_test in-21.1 {
CREATE TABLE t0(c0);
SELECT COUNT(*) FROM t0 ORDER BY (t0.c0 IN ());
} {0}
finish_test

View File

@@ -250,6 +250,19 @@ do_test join-2.1 {
}
} {1 2 3 4 2 3 4 5 3 4 5 {}}
# EVIDENCE-OF: R-52129-05406 you can say things like "OUTER LEFT NATURAL
# JOIN" which means the same as "NATURAL LEFT OUTER JOIN".
do_test join-2.1b {
execsql {
SELECT * FROM t1 OUTER LEFT NATURAL JOIN t2;
}
} {1 2 3 4 2 3 4 5 3 4 5 {}}
do_test join-2.1c {
execsql {
SELECT * FROM t1 NATURAL LEFT OUTER JOIN t2;
}
} {1 2 3 4 2 3 4 5 3 4 5 {}}
# ticket #3522
do_test join-2.1.1 {
execsql2 {
@@ -328,6 +341,9 @@ do_test join-3.6 {
SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
}
} {1 {no such column: t3.a}}
# EVIDENCE-OF: R-47973-48020 you cannot say "INNER OUTER JOIN", because
# that would be contradictory.
do_test join-3.7 {
catchsql {
SELECT * FROM t1 INNER OUTER JOIN t2;

View File

@@ -20,6 +20,8 @@ ifcapable !vtab {
}
db null NULL
# EVIDENCE-OF: R-33754-02880 you can say "LEFT RIGHT JOIN" which is the
# same as "FULL JOIN".
do_execsql_test join8-10 {
CREATE TABLE t1(a,b,c);
CREATE TABLE t2(x,y);
@@ -226,6 +228,27 @@ do_execsql_test join8-7010 {
- - - - - - - - 305 5
- - - - - - - - 310 10
}
# EVIDENCE-OF: R-33754-02880 you can say "LEFT RIGHT JOIN" which is the
# same as "FULL JOIN".
do_execsql_test join8-7011 {
WITH t0 AS MATERIALIZED (
SELECT t1.*, t2.*, t3.*
FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0
RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0
)
SELECT * FROM t0 LEFT RIGHT JOIN t4 ON t0.a=t4.d AND t4.z>0
ORDER BY coalesce(t0.a, t0.y+200, t4.d);
} {
6 106 206 306 106 6 206 6 - -
- - - - - - 200 0 - -
- - - - - - 203 3 - -
- - - - - - 209 9 - -
- - - - - - - - 300 0
- - - - - - - - 305 5
- - - - - - - - 310 10
}
do_execsql_test join8-7020 {
EXPLAIN QUERY PLAN
WITH t0 AS MATERIALIZED (
@@ -237,4 +260,189 @@ do_execsql_test join8-7020 {
ORDER BY coalesce(t0.a, t0.y+200, t4.d);
} {/.*BLOOM FILTER ON t2.*BLOOM FILTER ON t3.*BLOOM FILTER ON t4.*/}
# 2022-05-12 Difference with PG found (by Dan) while exploring
# https://sqlite.org/forum/forumpost/677a0ab93fcd9ccd
#
reset_db
do_execsql_test join8-8000 {
CREATE TABLE t1(a INT, b INT);
CREATE TABLE t2(c INT, d INT);
CREATE TABLE t3(e INT, f INT);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t2 VALUES(3, 4);
INSERT INTO t3 VALUES(5, 6);
} {}
do_execsql_test join8-8010 {
SELECT *
FROM t3 LEFT JOIN t2 ON true
JOIN t1 ON (t3.e IS t2.c);
} {}
do_execsql_test join8-8020 {
SELECT *
FROM t3 LEFT JOIN t2 ON true
JOIN t1 ON (t3.e IS NOT DISTINCT FROM t2.c);
} {}
# 2022-05-13 The idea of reusing subquery cursors does not
# work, if the cursors are used both for scanning and lookups.
#
reset_db
db null -
do_execsql_test join8-9000 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d REAL);
INSERT INTO t1 VALUES(1,'E','bb',NULL),(2,NULL,NULL,NULL);
SELECT * FROM t1 NATURAL RIGHT JOIN t1 AS t2 WHERE (a,b) IN (SELECT a+0, b FROM t1);
} {1 E bb -}
# 2022-05-14 https://sqlite.org/forum/forumpost/c06b10ad7e
#
reset_db
db null -
do_execsql_test join8-10000 {
CREATE TABLE t1(c0 INT UNIQUE);
CREATE TABLE t2(c0);
CREATE TABLE t2i(c0 INT);
CREATE TABLE t3(c0 INT);
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);
INSERT INTO t2i VALUES(2);
INSERT INTO t3 VALUES(3);
} {}
do_execsql_test join8-10010 {
SELECT DISTINCT t1.c0, t3.c0
FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10020 {
SELECT t1.c0, t3.c0
FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10030 {
SELECT DISTINCT t1.c0, t3.c0
FROM t2 NATURAL CROSS JOIN t1 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10040 {
SELECT t1.c0, t3.c0
FROM t1 NATURAL CROSS JOIN t2 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10050 {
SELECT DISTINCT t1.c0, t3.c0
FROM t2i NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10060 {
SELECT DISTINCT +t1.c0, t3.c0
FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10070 {
SELECT DISTINCT +t1.c0, t3.c0
FROM t1 NATURAL CROSS JOIN t2 RIGHT JOIN t3 ON t1.c0;
} {- 3}
do_execsql_test join8-10080 {
SELECT DISTINCT t1.c0, t3.c0
FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0<>0;
} {- 3}
# 2022-05-14
# index-on-expr scan on a RIGHT JOIN
# dbsqlfuzz 39ee60004ff027a9e2846cf76e02cd5ac0953739
#
reset_db
db null -
do_execsql_test join8-11000 {
CREATE TABLE t1(a);
CREATE TABLE t2(b);
INSERT INTO t2 VALUES(0),(1),(2);
SELECT * FROM t1 RIGHT JOIN t2 ON (a=b) WHERE 99+(b+1)!=99;
} {- 0 - 1 - 2}
do_execsql_test join8-11010 {
CREATE INDEX t2b ON t2(b+1) WHERE b IS NOT NULL;
SELECT * FROM t1 RIGHT JOIN t2 ON (a=b) WHERE 99+(b+1)!=99;
} {- 0 - 1 - 2}
do_execsql_test join8-11020 {
DROP TABLE t1;
DROP TABLE t2;
CREATE TABLE t1(a);
CREATE TABLE t2(b, c, d);
INSERT INTO t2 VALUES(1, 3, 'not-4');
SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
} {1 not-4}
do_execsql_test join8-11030 {
CREATE INDEX i2 ON t2((b+0), d);
SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
} {1 not-4}
do_execsql_test join8-11040 {
DROP INDEX i2;
CREATE INDEX i2 ON t2((b+0), d) WHERE d IS NOT NULL;
SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
} {1 not-4}
# 2022-05-23
# NATURAL JOIN name resolution is more forgiving with LEFT JOIN
# https://sqlite.org/forum/forumpost/e90a8e6e6f
#
reset_db
db null -
do_execsql_test join8-12000 {
CREATE TABLE t1(a INT); INSERT INTO t1 VALUES(0),(1);
CREATE TABLE t2(a INT); INSERT INTO t2 VALUES(0),(2);
CREATE TABLE t3(a INT); INSERT INTO t3 VALUES(0),(3);
} {}
do_catchsql_test join8-12010 {
SELECT * FROM t1 RIGHT JOIN t2 ON t2.a<>0 NATURAL RIGHT JOIN t3;
} {1 {ambiguous reference to a in USING()}}
do_catchsql_test join8-12020 {
SELECT * FROM t1 RIGHT JOIN t2 ON t2.a<>0 NATURAL LEFT JOIN t3;
} {1 {ambiguous reference to a in USING()}}
do_catchsql_test join8-12030 {
SELECT * FROM t1 LEFT JOIN t2 ON t2.a<>0 NATURAL RIGHT JOIN t3;
} {1 {ambiguous reference to a in USING()}}
# The following query should probably also return the same error as the
# previous three cases. However, historical versions of SQLite have always
# let it pass. We will not "fix" this, since to do so might break legacy
# applications.
#
do_catchsql_test join8-12040 {
SELECT * FROM t1 LEFT JOIN t2 ON t2.a<>0 NATURAL LEFT JOIN t3;
} {0 {0 2 1 2}}
# 2022-05-24
# https://sqlite.org/forum/forumpost/687b0bf563a1d4f1
#
reset_db
do_execsql_test join8-13000 {
CREATE TABLE t0(t TEXT, u TEXT); INSERT INTO t0 VALUES('t', 'u');
CREATE TABLE t1(v TEXT, w TEXT); INSERT INTO t1 VALUES('v', 'w');
CREATE TABLE t2(x TEXT, y TEXT); INSERT INTO t2 VALUES('x', 'y');
SELECT * FROM t0 JOIN t1 ON (t2.x NOTNULL) LEFT JOIN t2 ON false;
SELECT * FROM t0 JOIN t1 ON (t2.x NOTNULL) LEFT JOIN t2 ON false
WHERE t2.y ISNULL;
} {}
# 2022-05-25
# https://sqlite.org/forum/forumpost/5cfe08eed6
#
reset_db
do_execsql_test join8-14000 {
CREATE TABLE t0(a TEXT, b TEXT, c TEXT);
CREATE TABLE t1(a TEXT);
INSERT INTO t1 VALUES('1');
CREATE VIEW v0 AS SELECT 'xyz' AS d;
SELECT * FROM v0 RIGHT JOIN t1 ON t1.a<>'' INNER JOIN t0 ON t0.c<>'';
SELECT * FROM v0 RIGHT JOIN t1 ON t1.a<>'' INNER JOIN t0 ON t0.c<>'' WHERE b ISNULL;
} {}
do_execsql_test join8-14010 {
CREATE TABLE y0(a INT);
CREATE TABLE y1(b INT); INSERT INTO y1 VALUES(1), (2);
CREATE TABLE y2(c INT); INSERT INTO y2 VALUES(3), (4);
} {}
db null -
do_execsql_test join8-14020 {
SELECT * FROM y0 RIGHT JOIN y1 ON true INNER JOIN y2 ON true WHERE y2.c!=99 AND y2.c!=98;
} {
- 1 3
- 1 4
- 2 3
- 2 4
}
finish_test

443
test/joinE.test Normal file
View File

@@ -0,0 +1,443 @@
# 2022-05-13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# 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 implements tests for JOINs that use Bloom filters.
#
# The test case output is (mostly) all generated by PostgreSQL 14. This
# test module was created as follows:
#
# 1. Run a TCL script (included at the bottom of this file) that
# generates an input script for "psql" that will run man
# diverse tests on joins.
#
# 2. Run the script from step (1) through psql and collect the
# output.
#
# 3. Make a few minor global search-and-replace operations to convert
# the psql output into a form suitable for this test module.
#
# 4. Add this header, and the script content at the footer.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db nullvalue -
db eval {
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(NULL);
CREATE TABLE t2(b INT);
INSERT INTO t2 VALUES(2),(NULL);
}
do_execsql_test joinE-1 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 2
1 -
- 2
- -
}
do_execsql_test joinE-2 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
do_execsql_test joinE-3 {
SELECT a, b
FROM t1 INNER JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
do_execsql_test joinE-4 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
do_execsql_test joinE-5 {
SELECT a, b
FROM t1 INNER JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
do_execsql_test joinE-6 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 2
1 -
- 2
- -
}
do_execsql_test joinE-7 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
do_execsql_test joinE-8 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- 2
- -
}
do_execsql_test joinE-9 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
do_execsql_test joinE-10 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
do_execsql_test joinE-11 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 2
1 -
- 2
- -
}
do_execsql_test joinE-12 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
do_execsql_test joinE-13 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
do_execsql_test joinE-14 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
do_execsql_test joinE-15 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- 2
- -
}
do_execsql_test joinE-16 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 2
1 -
- 2
- -
}
do_execsql_test joinE-17 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
- 2
- -
}
# PG-14 is unable to perform this join. It says: FULL JOIN is only
# supported with merge-joinable or hash-joinable join conditions
#
# do_execsql_test joinE-18 {
# SELECT a, b
# FROM t1 FULL JOIN t2 ON a IS NULL
# ORDER BY coalesce(a,b,3);
# } {
# }
do_execsql_test joinE-19 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
- -
}
# PG-14 is unable to perform this join. It says: FULL JOIN is only
# supported with merge-joinable or hash-joinable join conditions
#
# do_execsql_test joinE-20 {
# SELECT a, b
# FROM t1 FULL JOIN t2 ON b IS NULL
# ORDER BY coalesce(a,b,3);
# } {
# }
db eval {
DELETE FROM t1;
INSERT INTO t1 VALUES(1);
DELETE FROM t2;
INSERT INTO t2 VALUES(NULL);
}
do_execsql_test joinE-21 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-22 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
}
do_execsql_test joinE-23 {
SELECT a, b
FROM t1 INNER JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
}
do_execsql_test joinE-24 {
SELECT a, b
FROM t1 INNER JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-25 {
SELECT a, b
FROM t1 INNER JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-26 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-27 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
}
do_execsql_test joinE-28 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-29 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-30 {
SELECT a, b
FROM t1 LEFT JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-31 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-32 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
}
do_execsql_test joinE-33 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON a IS NULL
ORDER BY coalesce(a,b,3);
} {
- -
}
do_execsql_test joinE-34 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-35 {
SELECT a, b
FROM t1 RIGHT JOIN t2 ON b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-36 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true
ORDER BY coalesce(a,b,3);
} {
1 -
}
do_execsql_test joinE-37 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true WHERE a IS NULL
ORDER BY coalesce(a,b,3);
} {
}
# PG-14 is unable
#
# do_execsql_test joinE-38 {
# SELECT a, b
# FROM t1 FULL JOIN t2 ON a IS NULL
# ORDER BY coalesce(a,b,3);
# } {
# }
do_execsql_test joinE-39 {
SELECT a, b
FROM t1 FULL JOIN t2 ON true WHERE b IS NULL
ORDER BY coalesce(a,b,3);
} {
1 -
}
# PG-14 is unable
# do_execsql_test joinE-40 {
# SELECT a, b
# FROM t1 FULL JOIN t2 ON b IS NULL
# ORDER BY coalesce(a,b,3);
# } {
# }
finish_test
##############################################################################
# This is the PG-14 test script generator
#
# puts "
# \\pset border off
# \\pset tuples_only on
# \\pset null -
#
# DROP TABLE IF EXISTS t1;
# DROP TABLE IF EXISTS t2;
# CREATE TABLE t1(a INT);
# INSERT INTO t1 VALUES(1),(NULL);
# CREATE TABLE t2(b INT);
# INSERT INTO t2 VALUES(2),(NULL);
# "
#
# proc echo {prefix txt} {
# regsub -all {\n} $txt \n$prefix txt
# puts "$prefix$txt"
# }
#
# set n 0
# set k 0
# foreach j1 {INNER LEFT RIGHT FULL} {
# foreach on1 {
# true
# {true WHERE a IS NULL}
# {a IS NULL}
# {true WHERE b IS NULL}
# {b IS NULL}
# } {
#
# incr n
# incr k
# set q1 ""
# append q1 "SELECT a, b\n"
# append q1 " FROM t1 $j1 JOIN t2 ON $on1\n"
# append q1 " ORDER BY coalesce(a,b,3);"
#
# echo "\\qecho " "do_execsql_test joinE-$n \{"
# echo "\\qecho X " $q1
# echo "\\qecho " "\} \{"
# puts $q1
# echo "\\qecho " "\}"
#
# }
# }
#
# puts "
# DELETE FROM t1;
# INSERT INTO t1 VALUES(1);
# DELETE FROM t2;
# INSERT INTO t2 VALUES(NULL);
# "
#
# foreach j1 {INNER LEFT RIGHT FULL} {
# foreach on1 {
# true
# {true WHERE a IS NULL}
# {a IS NULL}
# {true WHERE b IS NULL}
# {b IS NULL}
# } {
#
# incr n
# incr k
# set q1 ""
# append q1 "SELECT a, b\n"
# append q1 " FROM t1 $j1 JOIN t2 ON $on1\n"
# append q1 " ORDER BY coalesce(a,b,3);"
#
# echo "\\qecho " "do_execsql_test joinE-$n \{"
# echo "\\qecho X " $q1
# echo "\\qecho " "\} \{"
# puts $q1
# echo "\\qecho " "\}"
#
# }
# }

View File

@@ -217,7 +217,8 @@ test_suite "valgrind" -prefix "" -description {
fail under valgrind) omitted.
} -files [
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \
shell*.test crash8.test atof1.test selectG.test \
shell2.test shell6.test shell7.test \
crash8.test atof1.test selectG.test \
tkt-fc62af4523.test numindex1.test corruptK.test
] -initialize {
set ::G(valgrind) 1

View File

@@ -23,7 +23,7 @@
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
set CLI [test_cli_invocation]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db

View File

@@ -136,16 +136,13 @@ SELECT * FROM foo1; SELECT * FROM foo2;
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1;
SELECT * FROM foo1; SELECT * FROM foo2;
1
SELECT * FROM foo2;
1
INSERT INTO foo1(a) VALUES(2);
INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1; SELECT * FROM foo2;
1
2
SELECT * FROM foo2;
1
2
}}
@@ -170,19 +167,16 @@ CREATE TABLE foo1(a);
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1;
SELECT * FROM foo1; SELECT * FROM foo2;
a
1
SELECT * FROM foo2;
b
1
INSERT INTO foo1(a) VALUES(2);
INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1; SELECT * FROM foo2;
a
1
2
SELECT * FROM foo2;
b
1
2

View File

@@ -22,7 +22,7 @@
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
set CLI [test_cli_invocation]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db

View File

@@ -23,7 +23,8 @@
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
set CLI [test_cli_invocation]
set CLI_ONLY [test_find_cli]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db
@@ -130,13 +131,13 @@ do_test shell4-3.1 {
set fd [open t1.txt wb]
puts $fd "SELECT 'squirrel';"
close $fd
exec $::CLI :memory: --interactive ".read t1.txt"
exec $::CLI_ONLY :memory: --interactive ".read t1.txt"
} {squirrel}
do_test shell4-3.2 {
set fd [open t1.txt wb]
puts $fd "SELECT 'pound: \302\243';"
close $fd
exec $::CLI :memory: --interactive ".read t1.txt"
exec $::CLI_ONLY :memory: --interactive ".read t1.txt"
} {pound: £}
do_test shell4-4.1 {

View File

@@ -21,7 +21,7 @@
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
set CLI [test_cli_invocation]
db close
forcedelete test.db test.db-journal test.db-wal

View File

@@ -19,7 +19,7 @@ set testprefix shell8
ifcapable !vtab {
finish_test; return
}
set CLI [test_find_cli]
set CLI [test_cli_invocation]
# Check to make sure the shell has been compiled with ".archive" support.
#

View File

@@ -148,11 +148,13 @@ catch { array unset ::dbcache }
# random integer between 0 and 1,000,000
# 0 and 99.
do_test 2.1 {
catch { array unset ctx_used }
for {set i 0} {$i < 100} {incr i} {
while 1 {
set ctx [expr abs(int(rand() *1000000))]
if {[info exists ::dbcache($ctx)]==0} break
if {[info exists ctx_used($ctx)]==0} break
}
set ctx_used($ctx) 1
set file test_remote.db$ctx
forcedelete $file

View File

@@ -184,7 +184,7 @@ proc get_pwd {} {
set comSpec {C:\Windows\system32\cmd.exe}
}
return [string map [list \\ /] \
[string trim [exec -- $comSpec /c echo %CD%]]]
[string trim [exec -- $comSpec /c CD]]]
} else {
return [pwd]
}
@@ -2478,7 +2478,7 @@ proc test_find_binary {nm} {
}
# Find the name of the 'shell' executable (e.g. "sqlite3.exe") to use for
# the tests in shell[1-5].test. If no such executable can be found, invoke
# the tests in shell*.test. If no such executable can be found, invoke
# [finish_test ; return] in the callers context.
#
proc test_find_cli {} {
@@ -2487,6 +2487,37 @@ proc test_find_cli {} {
return $prog
}
# Find invocation of the 'shell' executable (e.g. "sqlite3.exe") to use
# for the tests in shell*.test with optional valgrind prefix when the
# environment variable SQLITE_CLI_VALGRIND_OPT is set. The set value
# operates as follows:
# empty or 0 => no valgrind prefix;
# 1 => valgrind options for memory leak check;
# other => use value as valgrind options.
# If shell not found, invoke [finish_test ; return] in callers context.
#
proc test_cli_invocation {} {
set prog [test_find_binary sqlite3]
if {$prog==""} { return -code return }
set vgrun [expr {[permutation]=="valgrind"}]
if {$vgrun || [info exists ::env(SQLITE_CLI_VALGRIND_OPT)]} {
if {$vgrun} {
set vgo "--quiet"
} else {
set vgo $::env(SQLITE_CLI_VALGRIND_OPT)
}
if {$vgo == 0 || $vgo eq ""} {
return $prog
} elseif {$vgo == 1} {
return "valgrind --quiet --leak-check=yes $prog"
} else {
return "valgrind $vgo $prog"
}
} else {
return $prog
}
}
# Find the name of the 'sqldiff' executable (e.g. "sqlite3.exe") to use for
# the tests in sqldiff tests. If no such executable can be found, invoke
# [finish_test ; return] in the callers context.

130
test/upfrom4.test Normal file
View File

@@ -0,0 +1,130 @@
# 2022-05-24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix upfrom4
do_execsql_test 100 {
DROP TABLE IF EXISTS t5;
DROP TABLE IF EXISTS m1;
DROP TABLE IF EXISTS m2;
CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT);
CREATE TABLE m1(x INTEGER PRIMARY KEY, y TEXT);
CREATE TABLE m2(u INTEGER PRIMARY KEY, v TEXT);
INSERT INTO t5 VALUES(1, 'one', 'ONE');
INSERT INTO t5 VALUES(2, 'two', 'TWO');
INSERT INTO t5 VALUES(3, 'three', 'THREE');
INSERT INTO t5 VALUES(4, 'four', 'FOUR');
INSERT INTO m1 VALUES(1, 'i');
INSERT INTO m1 VALUES(2, 'ii');
INSERT INTO m1 VALUES(3, 'iii');
INSERT INTO m2 VALUES(1, 'I');
INSERT INTO m2 VALUES(3, 'II');
INSERT INTO m2 VALUES(4, 'III');
SELECT * FROM t5;
} {1 one ONE 2 two TWO 3 three THREE 4 four FOUR}
do_execsql_test 110 {
BEGIN;
UPDATE t5 SET b=y, c=v FROM m1 LEFT JOIN m2 ON (x=u) WHERE x=a;
SELECT * FROM t5 ORDER BY a;
ROLLBACK;
} {1 i I 2 ii {} 3 iii II 4 four FOUR}
do_execsql_test 120 {
BEGIN;
UPDATE t5 SET b=y, c=v FROM m2 RIGHT JOIN m1 ON (x=u) WHERE x=a;
SELECT * FROM t5 ORDER BY a;
ROLLBACK;
} {1 i I 2 ii {} 3 iii II 4 four FOUR}
reset_db
db null -
do_execsql_test 200 {
CREATE TABLE t1(a INT PRIMARY KEY, b INT, c INT);
INSERT INTO t1(a) VALUES(1),(2),(8),(19);
CREATE TABLE c1(x INTEGER PRIMARY KEY, b INT);
INSERT INTO c1(x,b) VALUES(1,1),(8,8),(17,17),(NULL,NULL);
CREATE TABLE c2(x INT,c INT);
INSERT INTO c2(x,c) VALUES(2,2),(8,8),(NULL,NULL);
CREATE TABLE dual(dummy TEXT);
INSERT INTO dual VALUES('X');
} {}
do_execsql_test 210 {
BEGIN;
SELECT * FROM t1 ORDER BY a;
UPDATE t1 SET b=c1.b, c=c2.c
FROM dual, c1 NATURAL RIGHT JOIN c2
WHERE x=a;
SELECT * FROM t1 ORDER BY a;
ROLLBACK;
} {
1 - -
2 - -
8 - -
19 - -
1 - -
2 - 2
8 8 8
19 - -
}
do_execsql_test 300 {
CREATE TABLE t2(x);
CREATE TRIGGER AFTER INSERT ON t2 BEGIN
UPDATE t1 SET b=c1.b, c=c2.c
FROM dual, c1 NATURAL RIGHT JOIN c2
WHERE x=a;
END;
} {}
do_execsql_test 310 {
BEGIN;
SELECT * FROM t1 ORDER BY a;
INSERT INTO t2(x) VALUES(1);
SELECT * FROM t1 ORDER BY a;
ROLLBACK;
} {
1 - -
2 - -
8 - -
19 - -
1 - -
2 - 2
8 8 8
19 - -
}
# 2022-05-26 dbsqlfuzz crash-9401d6ba699f1257d352a657de236286bf2b14da
#
reset_db
db null -
do_execsql_test 400 {
CREATE TABLE t2(x,y,z PRIMARY KEY) WITHOUT ROWID;
INSERT INTO t2 VALUES(89,-89,6);
CREATE TABLE t1(a INT,b TEXT,c TEXT,d REAL) STRICT;
INSERT INTO t1 VALUES(1,'xyz','def',4.5);
CREATE TRIGGER t1tr BEFORE UPDATE ON t1 BEGIN
INSERT INTO t1(a,b) VALUES(1000,'uvw');
UPDATE t1 SET b=NULL FROM (SELECT CAST(a AS varchar) FROM t1 ORDER BY b) NATURAL LEFT FULL JOIN t1 AS text;
END;
UPDATE t1 SET b=b|100;
SELECT * FROM t1 ORDER BY a;
} {
1 100 def 4.5
1000 - - -
}
finish_test

View File

@@ -277,11 +277,15 @@ do_test vtab6-3.6 {
SELECT * FROM t1 JOIN t2 ON t3.a=t2.b;
}
} {1 {no such column: t3.a}}
# EVIDENCE-OF: R-47973-48020 you cannot say "INNER OUTER JOIN", because
# that would be contradictory.
do_test vtab6-3.7 {
catchsql {
SELECT * FROM t1 INNER OUTER JOIN t2;
}
} {1 {unknown join type: INNER OUTER}}
do_test vtab6-3.7 {
catchsql {
SELECT * FROM t1 LEFT BOGUS JOIN t2;

View File

@@ -11,7 +11,6 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the use of indices in WHERE clases.
#
# $Id: where.test,v 1.50 2008/11/03 09:06:06 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -1603,4 +1602,19 @@ if {[permutation]!="valgrind"} {
} {0}
}
# 2022-05-10 dbsqlfuzz 4c5e3e89bc251d28378be88233f531b84ec66901
#
reset_db
do_execsql_test where-28.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
CREATE INDEX t1b ON t1(b,b,b,b,b,b,b,b,b,b,b,b,b);
INSERT INTO t1(a,b) VALUES(1,1),(15,2),(19,5);
UPDATE t1 SET b=999 WHERE a IN (SELECT 15) AND b IN (1,2);
SELECT * FROM t1;
} {
1 1
15 999
19 5
}
finish_test