1b733d037Sdrh# 2002 May 24 2b733d037Sdrh# 3b733d037Sdrh# The author disclaims copyright to this source code. In place of 4b733d037Sdrh# a legal notice, here is a blessing: 5b733d037Sdrh# 6b733d037Sdrh# May you do good and not evil. 7b733d037Sdrh# May you find forgiveness for yourself and forgive others. 8b733d037Sdrh# May you share freely, never taking more than you give. 9b733d037Sdrh# 10b733d037Sdrh#*********************************************************************** 11b733d037Sdrh# This file implements regression tests for SQLite library. 12b733d037Sdrh# 13b733d037Sdrh# This file implements tests for joins, including outer joins. 14b733d037Sdrh# 15b733d037Sdrh 16b733d037Sdrhset testdir [file dirname $argv0] 17b733d037Sdrhsource $testdir/tester.tcl 18f112f0b3Sdanset testprefix join2 19b733d037Sdrh 20b733d037Sdrhdo_test join2-1.1 { 21b733d037Sdrh execsql { 22b733d037Sdrh CREATE TABLE t1(a,b); 23b733d037Sdrh INSERT INTO t1 VALUES(1,11); 24b733d037Sdrh INSERT INTO t1 VALUES(2,22); 25b733d037Sdrh INSERT INTO t1 VALUES(3,33); 26b733d037Sdrh SELECT * FROM t1; 27b733d037Sdrh } 28b733d037Sdrh} {1 11 2 22 3 33} 29b733d037Sdrhdo_test join2-1.2 { 30b733d037Sdrh execsql { 31b733d037Sdrh CREATE TABLE t2(b,c); 32b733d037Sdrh INSERT INTO t2 VALUES(11,111); 33b733d037Sdrh INSERT INTO t2 VALUES(33,333); 34b733d037Sdrh INSERT INTO t2 VALUES(44,444); 35b733d037Sdrh SELECT * FROM t2; 36b733d037Sdrh } 37b733d037Sdrh} {11 111 33 333 44 444}; 38b733d037Sdrhdo_test join2-1.3 { 39b733d037Sdrh execsql { 40b733d037Sdrh CREATE TABLE t3(c,d); 41b733d037Sdrh INSERT INTO t3 VALUES(111,1111); 42b733d037Sdrh INSERT INTO t3 VALUES(444,4444); 43b733d037Sdrh INSERT INTO t3 VALUES(555,5555); 44b733d037Sdrh SELECT * FROM t3; 45b733d037Sdrh } 46b733d037Sdrh} {111 1111 444 4444 555 5555} 47b733d037Sdrh 48b733d037Sdrhdo_test join2-1.4 { 49b733d037Sdrh execsql { 50b733d037Sdrh SELECT * FROM 51b733d037Sdrh t1 NATURAL JOIN t2 NATURAL JOIN t3 52b733d037Sdrh } 53b733d037Sdrh} {1 11 111 1111} 54b733d037Sdrhdo_test join2-1.5 { 55b733d037Sdrh execsql { 56b733d037Sdrh SELECT * FROM 57b733d037Sdrh t1 NATURAL JOIN t2 NATURAL LEFT OUTER JOIN t3 58b733d037Sdrh } 59b733d037Sdrh} {1 11 111 1111 3 33 333 {}} 60b733d037Sdrhdo_test join2-1.6 { 61b733d037Sdrh execsql { 62b733d037Sdrh SELECT * FROM 63b733d037Sdrh t1 NATURAL LEFT OUTER JOIN t2 NATURAL JOIN t3 64b733d037Sdrh } 65b733d037Sdrh} {1 11 111 1111} 66ec27077cSdrhdo_test join2-1.6-rj { 67ec27077cSdrh execsql { 68ec27077cSdrh SELECT * FROM 69ec27077cSdrh t2 NATURAL RIGHT OUTER JOIN t1 NATURAL JOIN t3 70ec27077cSdrh } 71ec27077cSdrh} {11 111 1 1111} 723e8c37e7Sdanielk1977ifcapable subquery { 733e8c37e7Sdanielk1977 do_test join2-1.7 { 74b733d037Sdrh execsql { 75b733d037Sdrh SELECT * FROM 76b733d037Sdrh t1 NATURAL LEFT OUTER JOIN (t2 NATURAL JOIN t3) 77b733d037Sdrh } 78b733d037Sdrh } {1 11 111 1111 2 22 {} {} 3 33 {} {}} 79ec27077cSdrh do_test join2-1.7-rj { 80ec27077cSdrh execsql { 81*6fda176bSdrh SELECT a, b, c, d FROM 82*6fda176bSdrh t2 NATURAL JOIN t3 NATURAL RIGHT JOIN t1 83ec27077cSdrh } 84*6fda176bSdrh } {1 11 111 1111 2 22 {} {} 3 33 {} {}} 853e8c37e7Sdanielk1977} 86b733d037Sdrh 87f112f0b3Sdan#------------------------------------------------------------------------- 88f112f0b3Sdan# Check that ticket [25e335f802ddc] has been resolved. It should be an 89f112f0b3Sdan# error for the ON clause of a LEFT JOIN to refer to a table to its right. 90f112f0b3Sdan# 91f112f0b3Sdando_execsql_test 2.0 { 92f112f0b3Sdan CREATE TABLE aa(a); 93f112f0b3Sdan CREATE TABLE bb(b); 94f112f0b3Sdan CREATE TABLE cc(c); 95f112f0b3Sdan INSERT INTO aa VALUES('one'); 96f112f0b3Sdan INSERT INTO bb VALUES('one'); 97f112f0b3Sdan INSERT INTO cc VALUES('one'); 98f112f0b3Sdan} 99f112f0b3Sdan 100f112f0b3Sdando_catchsql_test 2.1 { 1012589787cSdrh SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); 102f112f0b3Sdan} {1 {ON clause references tables to its right}} 103ec27077cSdrhdo_catchsql_test 2.1b { 104ec27077cSdrh SELECT * FROM aa RIGHT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); 105ec27077cSdrh} {1 {ON clause references tables to its right}} 106f112f0b3Sdando_catchsql_test 2.2 { 107f112f0b3Sdan SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c); 108f112f0b3Sdan} {0 {one one one}} 109f112f0b3Sdan 11075dbf68bSdan#------------------------------------------------------------------------- 11175dbf68bSdan# Test that a problem causing where.c to overlook opportunities to 11275dbf68bSdan# omit unnecessary tables from a LEFT JOIN when UNIQUE, NOT NULL column 11375dbf68bSdan# that makes this possible happens to be the leftmost in its table. 11475dbf68bSdan# 11575dbf68bSdanreset_db 11675dbf68bSdando_execsql_test 3.0 { 11775dbf68bSdan CREATE TABLE t1(k1 INTEGER PRIMARY KEY, k2, k3); 11875dbf68bSdan CREATE TABLE t2(k2 INTEGER PRIMARY KEY, v2); 11975dbf68bSdan 12017f188e3Sdan -- Prior to this problem being fixed, table t3_2 would be omitted from 12117f188e3Sdan -- the join queries below, but if t3_1 were used in its place it would 12217f188e3Sdan -- not. 12375dbf68bSdan CREATE TABLE t3_1(k3 PRIMARY KEY, v3) WITHOUT ROWID; 12475dbf68bSdan CREATE TABLE t3_2(v3, k3 PRIMARY KEY) WITHOUT ROWID; 12575dbf68bSdan} 12675dbf68bSdan 12775dbf68bSdando_eqp_test 3.1 { 12875dbf68bSdan SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_1 USING (k3); 12975dbf68bSdan} { 130b3f0276bSdrh QUERY PLAN 1318210233cSdrh |--SCAN t1 132c583719bSdrh `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN 13375dbf68bSdan} 13475dbf68bSdan 13575dbf68bSdando_eqp_test 3.2 { 13675dbf68bSdan SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_2 USING (k3); 13775dbf68bSdan} { 138b3f0276bSdrh QUERY PLAN 1398210233cSdrh |--SCAN t1 140c583719bSdrh `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN 14175dbf68bSdan} 14275dbf68bSdan 14341203c6cSdan#------------------------------------------------------------------------- 14441203c6cSdan# Test that tables other than the rightmost can be omitted from a 14541203c6cSdan# LEFT JOIN query. 14641203c6cSdan# 14741203c6cSdando_execsql_test 4.0 { 14841203c6cSdan CREATE TABLE c1(k INTEGER PRIMARY KEY, v1); 14941203c6cSdan CREATE TABLE c2(k INTEGER PRIMARY KEY, v2); 15041203c6cSdan CREATE TABLE c3(k INTEGER PRIMARY KEY, v3); 15141203c6cSdan 15241203c6cSdan INSERT INTO c1 VALUES(1, 2); 15341203c6cSdan INSERT INTO c2 VALUES(2, 3); 15441203c6cSdan INSERT INTO c3 VALUES(3, 'v3'); 15541203c6cSdan 15641203c6cSdan INSERT INTO c1 VALUES(111, 1112); 15741203c6cSdan INSERT INTO c2 VALUES(112, 1113); 15841203c6cSdan INSERT INTO c3 VALUES(113, 'v1113'); 15941203c6cSdan} 16041203c6cSdando_execsql_test 4.1.1 { 16141203c6cSdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); 16241203c6cSdan} {2 v3 1112 {}} 16341203c6cSdando_execsql_test 4.1.2 { 16441203c6cSdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); 16541203c6cSdan} {2 v3 1112 {}} 16641203c6cSdan 16741203c6cSdando_execsql_test 4.1.3 { 16841203c6cSdan SELECT DISTINCT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); 16941203c6cSdan} {2 v3 1112 {}} 17041203c6cSdan 17141203c6cSdando_execsql_test 4.1.4 { 17241203c6cSdan SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); 17341203c6cSdan} {2 v3 2 v3 1112 {} 1112 {}} 17441203c6cSdan 1758433e716Sdando_eqp_test 4.1.5 { 17641203c6cSdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); 17741203c6cSdan} { 178b3f0276bSdrh QUERY PLAN 1798210233cSdrh |--SCAN c1 180c583719bSdrh |--SEARCH c2 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN 181c583719bSdrh `--SEARCH c3 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN 18241203c6cSdan} 1838433e716Sdando_eqp_test 4.1.6 { 18441203c6cSdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); 18541203c6cSdan} { 186b3f0276bSdrh QUERY PLAN 1878210233cSdrh |--SCAN c1 188c583719bSdrh `--SEARCH c3 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN 18941203c6cSdan} 19041203c6cSdan 1918433e716Sdando_execsql_test 4.2.0 { 1928433e716Sdan DROP TABLE c1; 1938433e716Sdan DROP TABLE c2; 1948433e716Sdan DROP TABLE c3; 1958433e716Sdan CREATE TABLE c1(k UNIQUE, v1); 1968433e716Sdan CREATE TABLE c2(k UNIQUE, v2); 1978433e716Sdan CREATE TABLE c3(k UNIQUE, v3); 1988433e716Sdan 1998433e716Sdan INSERT INTO c1 VALUES(1, 2); 2008433e716Sdan INSERT INTO c2 VALUES(2, 3); 2018433e716Sdan INSERT INTO c3 VALUES(3, 'v3'); 2028433e716Sdan 2038433e716Sdan INSERT INTO c1 VALUES(111, 1112); 2048433e716Sdan INSERT INTO c2 VALUES(112, 1113); 2058433e716Sdan INSERT INTO c3 VALUES(113, 'v1113'); 2068433e716Sdan} 2078433e716Sdando_execsql_test 4.2.1 { 2088433e716Sdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); 2098433e716Sdan} {2 v3 1112 {}} 2108433e716Sdando_execsql_test 4.2.2 { 2118433e716Sdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); 2128433e716Sdan} {2 v3 1112 {}} 2138433e716Sdan 2148433e716Sdando_execsql_test 4.2.3 { 2158433e716Sdan SELECT DISTINCT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); 2168433e716Sdan} {2 v3 1112 {}} 2178433e716Sdan 2188433e716Sdando_execsql_test 4.2.4 { 2198433e716Sdan SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1); 2208433e716Sdan} {2 v3 2 v3 1112 {} 1112 {}} 2218433e716Sdan 2228433e716Sdando_eqp_test 4.2.5 { 2238433e716Sdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2); 2248433e716Sdan} { 225b3f0276bSdrh QUERY PLAN 2268210233cSdrh |--SCAN c1 227c583719bSdrh |--SEARCH c2 USING INDEX sqlite_autoindex_c2_1 (k=?) LEFT-JOIN 228c583719bSdrh `--SEARCH c3 USING INDEX sqlite_autoindex_c3_1 (k=?) LEFT-JOIN 2298433e716Sdan} 2308433e716Sdando_eqp_test 4.2.6 { 2318433e716Sdan SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1); 2328433e716Sdan} { 233b3f0276bSdrh QUERY PLAN 2348210233cSdrh |--SCAN c1 235c583719bSdrh `--SEARCH c3 USING INDEX sqlite_autoindex_c3_1 (k=?) LEFT-JOIN 2368433e716Sdan} 2378433e716Sdan 23853bf7175Sdrh# 2017-11-23 (Thanksgiving day) 23953bf7175Sdrh# OSSFuzz found an assertion fault in the new LEFT JOIN eliminator code. 24053bf7175Sdrh# 24153bf7175Sdrhdo_execsql_test 4.3.0 { 24253bf7175Sdrh DROP TABLE IF EXISTS t1; 24353bf7175Sdrh DROP TABLE IF EXISTS t2; 24453bf7175Sdrh CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID; 24553bf7175Sdrh CREATE TABLE t2(x); 24653bf7175Sdrh SELECT a.x 24753bf7175Sdrh FROM t1 AS a 24853bf7175Sdrh LEFT JOIN t1 AS b ON (a.x=b.x) 24953bf7175Sdrh LEFT JOIN t2 AS c ON (a.x=c.x); 25053bf7175Sdrh} {} 25153bf7175Sdrhdo_execsql_test 4.3.1 { 25253bf7175Sdrh WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) 25353bf7175Sdrh INSERT INTO t1(x) SELECT x FROM c; 25453bf7175Sdrh INSERT INTO t2(x) SELECT x+9 FROM t1; 25553bf7175Sdrh SELECT a.x, c.x 25653bf7175Sdrh FROM t1 AS a 25753bf7175Sdrh LEFT JOIN t1 AS b ON (a.x=b.x) 25853bf7175Sdrh LEFT JOIN t2 AS c ON (a.x=c.x); 25953bf7175Sdrh} {1 {} 2 {} 3 {} 4 {} 5 {} 6 {} 7 {} 8 {} 9 {} 10 10} 26041203c6cSdan 2618433e716Sdando_execsql_test 5.0 { 2628433e716Sdan CREATE TABLE s1 (a INTEGER PRIMARY KEY); 2638433e716Sdan CREATE TABLE s2 (a INTEGER PRIMARY KEY); 2648433e716Sdan CREATE TABLE s3 (a INTEGER); 2658433e716Sdan CREATE UNIQUE INDEX ndx on s3(a); 2668433e716Sdan} 2678433e716Sdando_eqp_test 5.1 { 2688433e716Sdan SELECT s1.a FROM s1 left join s2 using (a); 2698210233cSdrh} {SCAN s1} 270b3f0276bSdrh 2718433e716Sdando_eqp_test 5.2 { 2728433e716Sdan SELECT s1.a FROM s1 left join s3 using (a); 2738210233cSdrh} {SCAN s1} 2748433e716Sdan 2754ea48144Sdando_execsql_test 6.0 { 2764ea48144Sdan CREATE TABLE u1(a INTEGER PRIMARY KEY, b, c); 2774ea48144Sdan CREATE TABLE u2(a INTEGER PRIMARY KEY, b, c); 2784ea48144Sdan CREATE INDEX u1ab ON u1(b, c); 2794ea48144Sdan} 2804ea48144Sdando_eqp_test 6.1 { 2814ea48144Sdan SELECT u2.* FROM u2 LEFT JOIN u1 ON( u1.a=u2.a AND u1.b=u2.b AND u1.c=u2.c ); 2828210233cSdrh} {SCAN u2} 2834ea48144Sdan 2846a9b9527Sdrhdb close 2856a9b9527Sdrhsqlite3 db :memory: 2866a9b9527Sdrhdo_execsql_test 7.0 { 2876a9b9527Sdrh CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2),(3,4),(5,6); 2886a9b9527Sdrh CREATE TABLE t2(c,d); INSERT INTO t2 VALUES(2,4),(3,6); 2896a9b9527Sdrh CREATE TABLE t3(x); INSERT INTO t3 VALUES(9); 2906a9b9527Sdrh CREATE VIEW test AS 2916a9b9527Sdrh SELECT *, 'x' 2926a9b9527Sdrh FROM t1 LEFT JOIN (SELECT * FROM t2, t3) ON (c=b AND x=9) 2936a9b9527Sdrh WHERE c IS NULL; 2946a9b9527Sdrh SELECT * FROM test; 2956a9b9527Sdrh} {3 4 {} {} {} x 5 6 {} {} {} x} 2966a9b9527Sdrh 2971d24a531Sdan#------------------------------------------------------------------------- 2981d24a531Sdan# Ticket [dfd66334]. 2991d24a531Sdan# 3001d24a531Sdanreset_db 3011d24a531Sdando_execsql_test 8.0 { 3021d24a531Sdan CREATE TABLE t0(c0); 3031d24a531Sdan CREATE TABLE t1(c0); 3041d24a531Sdan} 3051d24a531Sdan 3061d24a531Sdando_execsql_test 8.1 { 3071d24a531Sdan SELECT * FROM t0 LEFT JOIN t1 3081d24a531Sdan WHERE (t1.c0 BETWEEN 0 AND 0) > ('' AND t0.c0); 3091d24a531Sdan} 3101d24a531Sdan 31107f9e8f4Sdan#------------------------------------------------------------------------- 31246fe138dSdrh# Ticket [45f4bf4eb] reported by Manuel Rigger (2020-04-25) 31346fe138dSdrh# 31446fe138dSdrh# Follow up error reported by Eric Speckman on the SQLite forum 31546fe138dSdrh# https://sqlite.org/forum/info/c49496d24d35bd7c (2020-08-19) 31607f9e8f4Sdan# 31707f9e8f4Sdanreset_db 31807f9e8f4Sdando_execsql_test 9.0 { 31907f9e8f4Sdan CREATE TABLE t0(c0 INT); 32007f9e8f4Sdan CREATE VIEW v0(c0) AS SELECT CAST(t0.c0 AS INTEGER) FROM t0; 32107f9e8f4Sdan INSERT INTO t0(c0) VALUES (0); 32207f9e8f4Sdan} 32307f9e8f4Sdan 32407f9e8f4Sdando_execsql_test 9.1 { 32507f9e8f4Sdan SELECT typeof(c0), c0 FROM v0 WHERE c0>='0' 32607f9e8f4Sdan} {integer 0} 32707f9e8f4Sdan 32807f9e8f4Sdando_execsql_test 9.2 { 32907f9e8f4Sdan SELECT * FROM t0, v0 WHERE v0.c0 >= '0'; 33007f9e8f4Sdan} {0 0} 33107f9e8f4Sdan 33207f9e8f4Sdando_execsql_test 9.3 { 33307f9e8f4Sdan SELECT * FROM t0 LEFT JOIN v0 WHERE v0.c0 >= '0'; 33407f9e8f4Sdan} {0 0} 33507f9e8f4Sdan 33607f9e8f4Sdando_execsql_test 9.4 { 33707f9e8f4Sdan SELECT * FROM t0 LEFT JOIN v0 ON v0.c0 >= '0'; 33807f9e8f4Sdan} {0 0} 33907f9e8f4Sdan 34007f9e8f4Sdando_execsql_test 9.5 { 34107f9e8f4Sdan SELECT * FROM t0 LEFT JOIN v0 ON v0.c0 >= '0' WHERE TRUE 34207f9e8f4Sdan UNION SELECT 0,0 WHERE 0; 34307f9e8f4Sdan} {0 0} 34407f9e8f4Sdan 34546fe138dSdrhdo_execsql_test 9.10 { 34646fe138dSdrh CREATE TABLE t1 (aaa); 34746fe138dSdrh INSERT INTO t1 VALUES(23456); 34846fe138dSdrh CREATE TABLE t2(bbb); 34946fe138dSdrh CREATE VIEW v2(ccc) AS SELECT bbb IS 1234 FROM t2; 35046fe138dSdrh SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2; 35146fe138dSdrh} {{} 1} 35246fe138dSdrhoptimization_control db query-flattener 0 35346fe138dSdrhdo_execsql_test 9.11 { 35446fe138dSdrh SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2; 35546fe138dSdrh} {{} 1} 35646fe138dSdrh 3576a9b9527Sdrh 358b733d037Sdrhfinish_test 359