xref: /sqlite-3.40.0/test/join2.test (revision 6fda176b)
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