3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
13 set testdir [file dirname $argv0]
14 source $testdir/tester.tcl
19 CREATE TABLE t1x(x INTEGER PRIMARY KEY);
20 INSERT INTO t1x VALUES(1),(3),(5),(7),(9);
21 CREATE TABLE t1y(y INTEGER UNIQUE);
22 INSERT INTO t1y VALUES(2),(4),(6),(8);
23 CREATE TABLE t1z(z TEXT UNIQUE);
24 INSERT INTO t1z VALUES('a'),('c'),('e'),('g');
25 CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT, d TEXT);
26 INSERT INTO t2 VALUES(1,2,'a','12a'),(1,2,'b','12b'),
27 (2,3,'g','23g'),(3,5,'c','35c'),
28 (4,6,'h','46h'),(5,6,'e','56e');
29 CREATE TABLE t3x AS SELECT x FROM t1x;
30 CREATE TABLE t3y AS SELECT y FROM t1y;
31 CREATE TABLE t3z AS SELECT z FROM t1z;
32 SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY c;
37 SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
42 SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d;
49 CREATE INDEX t2abc ON t2(a,b,c);
50 SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
55 SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
59 regexp {OpenEphemeral} [db eval {
60 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
65 SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d;
69 regexp {OpenEphemeral} [db eval {
70 EXPLAIN SELECT d FROM t2 WHERE a IN t3x AND b IN t1y AND c IN t1z
74 regexp {OpenEphemeral} [db eval {
75 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t3y AND c IN t1z
79 regexp {OpenEphemeral} [db eval {
80 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t3z
87 CREATE INDEX t2ab ON t2(a,b);
88 SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
93 SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
97 regexp {OpenEphemeral} [db eval {
98 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
105 CREATE INDEX t2abcd ON t2(a,b,c,d);
106 SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
111 SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
115 regexp {OpenEphemeral} [db eval {
116 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
124 CREATE INDEX t2cbad ON t2(c,b,a,d);
125 SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
130 SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
134 regexp {OpenEphemeral} [db eval {
135 EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
139 #-------------------------------------------------------------------------
140 # At one point SQLite was removing the DISTINCT keyword from expressions
143 # <expr1> IN (SELECT DISTINCT <expr2> FROM...)
145 # However, there are a few obscure cases where this is incorrect. For
146 # example, if the SELECT features a LIMIT clause, or if the collation
147 # sequence or affinity used by the DISTINCT does not match the one used
148 # by the IN(...) expression.
150 do_execsql_test 6.1.1 {
151 CREATE TABLE t1(a COLLATE nocase);
152 INSERT INTO t1 VALUES('one');
153 INSERT INTO t1 VALUES('ONE');
155 do_execsql_test 6.1.2 {
156 SELECT count(*) FROM t1 WHERE a COLLATE BINARY IN (SELECT DISTINCT a FROM t1)
159 do_execsql_test 6.2.1 {
160 CREATE TABLE t3(a, b);
161 INSERT INTO t3 VALUES(1, 1);
162 INSERT INTO t3 VALUES(1, 2);
163 INSERT INTO t3 VALUES(1, 3);
164 INSERT INTO t3 VALUES(2, 4);
165 INSERT INTO t3 VALUES(2, 5);
166 INSERT INTO t3 VALUES(2, 6);
167 INSERT INTO t3 VALUES(3, 7);
168 INSERT INTO t3 VALUES(3, 8);
169 INSERT INTO t3 VALUES(3, 9);
171 do_execsql_test 6.2.2 {
172 SELECT count(*) FROM t3 WHERE b IN (SELECT DISTINCT a FROM t3 LIMIT 5);
174 do_execsql_test 6.2.3 {
175 SELECT count(*) FROM t3 WHERE b IN (SELECT a FROM t3 LIMIT 5);
178 do_execsql_test 6.3.1 {
181 INSERT INTO x1 VALUES(1), (1), (2);
182 INSERT INTO x2 VALUES(1), (2);
183 SELECT count(*) FROM x2 WHERE b IN (SELECT DISTINCT a FROM x1 LIMIT 2);