sl@0
|
1 |
# 2001 September 15
|
sl@0
|
2 |
#
|
sl@0
|
3 |
# The author disclaims copyright to this source code. In place of
|
sl@0
|
4 |
# a legal notice, here is a blessing:
|
sl@0
|
5 |
#
|
sl@0
|
6 |
# May you do good and not evil.
|
sl@0
|
7 |
# May you find forgiveness for yourself and forgive others.
|
sl@0
|
8 |
# May you share freely, never taking more than you give.
|
sl@0
|
9 |
#
|
sl@0
|
10 |
#***********************************************************************
|
sl@0
|
11 |
# This file implements regression tests for SQLite library. The
|
sl@0
|
12 |
# focus of this file is testing the IN and BETWEEN operator.
|
sl@0
|
13 |
#
|
sl@0
|
14 |
# $Id: in.test,v 1.22 2008/08/04 03:51:24 danielk1977 Exp $
|
sl@0
|
15 |
|
sl@0
|
16 |
set testdir [file dirname $argv0]
|
sl@0
|
17 |
source $testdir/tester.tcl
|
sl@0
|
18 |
|
sl@0
|
19 |
# Generate the test data we will need for the first squences of tests.
|
sl@0
|
20 |
#
|
sl@0
|
21 |
do_test in-1.0 {
|
sl@0
|
22 |
execsql {
|
sl@0
|
23 |
BEGIN;
|
sl@0
|
24 |
CREATE TABLE t1(a int, b int);
|
sl@0
|
25 |
}
|
sl@0
|
26 |
for {set i 1} {$i<=10} {incr i} {
|
sl@0
|
27 |
execsql "INSERT INTO t1 VALUES($i,[expr {1<<$i}])"
|
sl@0
|
28 |
}
|
sl@0
|
29 |
execsql {
|
sl@0
|
30 |
COMMIT;
|
sl@0
|
31 |
SELECT count(*) FROM t1;
|
sl@0
|
32 |
}
|
sl@0
|
33 |
} {10}
|
sl@0
|
34 |
|
sl@0
|
35 |
# Do basic testing of BETWEEN.
|
sl@0
|
36 |
#
|
sl@0
|
37 |
do_test in-1.1 {
|
sl@0
|
38 |
execsql {SELECT a FROM t1 WHERE b BETWEEN 10 AND 50 ORDER BY a}
|
sl@0
|
39 |
} {4 5}
|
sl@0
|
40 |
do_test in-1.2 {
|
sl@0
|
41 |
execsql {SELECT a FROM t1 WHERE b NOT BETWEEN 10 AND 50 ORDER BY a}
|
sl@0
|
42 |
} {1 2 3 6 7 8 9 10}
|
sl@0
|
43 |
do_test in-1.3 {
|
sl@0
|
44 |
execsql {SELECT a FROM t1 WHERE b BETWEEN a AND a*5 ORDER BY a}
|
sl@0
|
45 |
} {1 2 3 4}
|
sl@0
|
46 |
do_test in-1.4 {
|
sl@0
|
47 |
execsql {SELECT a FROM t1 WHERE b NOT BETWEEN a AND a*5 ORDER BY a}
|
sl@0
|
48 |
} {5 6 7 8 9 10}
|
sl@0
|
49 |
do_test in-1.6 {
|
sl@0
|
50 |
execsql {SELECT a FROM t1 WHERE b BETWEEN a AND a*5 OR b=512 ORDER BY a}
|
sl@0
|
51 |
} {1 2 3 4 9}
|
sl@0
|
52 |
do_test in-1.7 {
|
sl@0
|
53 |
execsql {SELECT a+ 100*(a BETWEEN 1 and 3) FROM t1 ORDER BY b}
|
sl@0
|
54 |
} {101 102 103 4 5 6 7 8 9 10}
|
sl@0
|
55 |
|
sl@0
|
56 |
# The rest of this file concentrates on testing the IN operator.
|
sl@0
|
57 |
# Skip this if the library is compiled with SQLITE_OMIT_SUBQUERY
|
sl@0
|
58 |
# (because the IN operator is unavailable).
|
sl@0
|
59 |
#
|
sl@0
|
60 |
ifcapable !subquery {
|
sl@0
|
61 |
finish_test
|
sl@0
|
62 |
return
|
sl@0
|
63 |
}
|
sl@0
|
64 |
|
sl@0
|
65 |
# Testing of the IN operator using static lists on the right-hand side.
|
sl@0
|
66 |
#
|
sl@0
|
67 |
do_test in-2.1 {
|
sl@0
|
68 |
execsql {SELECT a FROM t1 WHERE b IN (8,12,16,24,32) ORDER BY a}
|
sl@0
|
69 |
} {3 4 5}
|
sl@0
|
70 |
do_test in-2.2 {
|
sl@0
|
71 |
execsql {SELECT a FROM t1 WHERE b NOT IN (8,12,16,24,32) ORDER BY a}
|
sl@0
|
72 |
} {1 2 6 7 8 9 10}
|
sl@0
|
73 |
do_test in-2.3 {
|
sl@0
|
74 |
execsql {SELECT a FROM t1 WHERE b IN (8,12,16,24,32) OR b=512 ORDER BY a}
|
sl@0
|
75 |
} {3 4 5 9}
|
sl@0
|
76 |
do_test in-2.4 {
|
sl@0
|
77 |
execsql {SELECT a FROM t1 WHERE b NOT IN (8,12,16,24,32) OR b=512 ORDER BY a}
|
sl@0
|
78 |
} {1 2 6 7 8 9 10}
|
sl@0
|
79 |
do_test in-2.5 {
|
sl@0
|
80 |
execsql {SELECT a+100*(b IN (8,16,24)) FROM t1 ORDER BY b}
|
sl@0
|
81 |
} {1 2 103 104 5 6 7 8 9 10}
|
sl@0
|
82 |
|
sl@0
|
83 |
do_test in-2.6 {
|
sl@0
|
84 |
execsql {SELECT a FROM t1 WHERE b IN (b+8,64)}
|
sl@0
|
85 |
} {6}
|
sl@0
|
86 |
do_test in-2.7 {
|
sl@0
|
87 |
execsql {SELECT a FROM t1 WHERE b IN (max(5,10,b),20)}
|
sl@0
|
88 |
} {4 5 6 7 8 9 10}
|
sl@0
|
89 |
do_test in-2.8 {
|
sl@0
|
90 |
execsql {SELECT a FROM t1 WHERE b IN (8*2,64/2) ORDER BY b}
|
sl@0
|
91 |
} {4 5}
|
sl@0
|
92 |
do_test in-2.9 {
|
sl@0
|
93 |
execsql {SELECT a FROM t1 WHERE b IN (max(5,10),20)}
|
sl@0
|
94 |
} {}
|
sl@0
|
95 |
do_test in-2.10 {
|
sl@0
|
96 |
execsql {SELECT a FROM t1 WHERE min(0,b IN (a,30))}
|
sl@0
|
97 |
} {}
|
sl@0
|
98 |
do_test in-2.11 {
|
sl@0
|
99 |
set v [catch {execsql {SELECT a FROM t1 WHERE c IN (10,20)}} msg]
|
sl@0
|
100 |
lappend v $msg
|
sl@0
|
101 |
} {1 {no such column: c}}
|
sl@0
|
102 |
|
sl@0
|
103 |
# Testing the IN operator where the right-hand side is a SELECT
|
sl@0
|
104 |
#
|
sl@0
|
105 |
do_test in-3.1 {
|
sl@0
|
106 |
execsql {
|
sl@0
|
107 |
SELECT a FROM t1
|
sl@0
|
108 |
WHERE b IN (SELECT b FROM t1 WHERE a<5)
|
sl@0
|
109 |
ORDER BY a
|
sl@0
|
110 |
}
|
sl@0
|
111 |
} {1 2 3 4}
|
sl@0
|
112 |
do_test in-3.2 {
|
sl@0
|
113 |
execsql {
|
sl@0
|
114 |
SELECT a FROM t1
|
sl@0
|
115 |
WHERE b IN (SELECT b FROM t1 WHERE a<5) OR b==512
|
sl@0
|
116 |
ORDER BY a
|
sl@0
|
117 |
}
|
sl@0
|
118 |
} {1 2 3 4 9}
|
sl@0
|
119 |
do_test in-3.3 {
|
sl@0
|
120 |
execsql {
|
sl@0
|
121 |
SELECT a + 100*(b IN (SELECT b FROM t1 WHERE a<5)) FROM t1 ORDER BY b
|
sl@0
|
122 |
}
|
sl@0
|
123 |
} {101 102 103 104 5 6 7 8 9 10}
|
sl@0
|
124 |
|
sl@0
|
125 |
# Make sure the UPDATE and DELETE commands work with IN-SELECT
|
sl@0
|
126 |
#
|
sl@0
|
127 |
do_test in-4.1 {
|
sl@0
|
128 |
execsql {
|
sl@0
|
129 |
UPDATE t1 SET b=b*2
|
sl@0
|
130 |
WHERE b IN (SELECT b FROM t1 WHERE a>8)
|
sl@0
|
131 |
}
|
sl@0
|
132 |
execsql {SELECT b FROM t1 ORDER BY b}
|
sl@0
|
133 |
} {2 4 8 16 32 64 128 256 1024 2048}
|
sl@0
|
134 |
do_test in-4.2 {
|
sl@0
|
135 |
execsql {
|
sl@0
|
136 |
DELETE FROM t1 WHERE b IN (SELECT b FROM t1 WHERE a>8)
|
sl@0
|
137 |
}
|
sl@0
|
138 |
execsql {SELECT a FROM t1 ORDER BY a}
|
sl@0
|
139 |
} {1 2 3 4 5 6 7 8}
|
sl@0
|
140 |
do_test in-4.3 {
|
sl@0
|
141 |
execsql {
|
sl@0
|
142 |
DELETE FROM t1 WHERE b NOT IN (SELECT b FROM t1 WHERE a>4)
|
sl@0
|
143 |
}
|
sl@0
|
144 |
execsql {SELECT a FROM t1 ORDER BY a}
|
sl@0
|
145 |
} {5 6 7 8}
|
sl@0
|
146 |
|
sl@0
|
147 |
# Do an IN with a constant RHS but where the RHS has many, many
|
sl@0
|
148 |
# elements. We need to test that collisions in the hash table
|
sl@0
|
149 |
# are resolved properly.
|
sl@0
|
150 |
#
|
sl@0
|
151 |
do_test in-5.1 {
|
sl@0
|
152 |
execsql {
|
sl@0
|
153 |
INSERT INTO t1 VALUES('hello', 'world');
|
sl@0
|
154 |
SELECT * FROM t1
|
sl@0
|
155 |
WHERE a IN (
|
sl@0
|
156 |
'Do','an','IN','with','a','constant','RHS','but','where','the',
|
sl@0
|
157 |
'has','many','elements','We','need','to','test','that',
|
sl@0
|
158 |
'collisions','hash','table','are','resolved','properly',
|
sl@0
|
159 |
'This','in-set','contains','thirty','one','entries','hello');
|
sl@0
|
160 |
}
|
sl@0
|
161 |
} {hello world}
|
sl@0
|
162 |
|
sl@0
|
163 |
# Make sure the IN operator works with INTEGER PRIMARY KEY fields.
|
sl@0
|
164 |
#
|
sl@0
|
165 |
do_test in-6.1 {
|
sl@0
|
166 |
execsql {
|
sl@0
|
167 |
CREATE TABLE ta(a INTEGER PRIMARY KEY, b);
|
sl@0
|
168 |
INSERT INTO ta VALUES(1,1);
|
sl@0
|
169 |
INSERT INTO ta VALUES(2,2);
|
sl@0
|
170 |
INSERT INTO ta VALUES(3,3);
|
sl@0
|
171 |
INSERT INTO ta VALUES(4,4);
|
sl@0
|
172 |
INSERT INTO ta VALUES(6,6);
|
sl@0
|
173 |
INSERT INTO ta VALUES(8,8);
|
sl@0
|
174 |
INSERT INTO ta VALUES(10,
|
sl@0
|
175 |
'This is a key that is long enough to require a malloc in the VDBE');
|
sl@0
|
176 |
SELECT * FROM ta WHERE a<10;
|
sl@0
|
177 |
}
|
sl@0
|
178 |
} {1 1 2 2 3 3 4 4 6 6 8 8}
|
sl@0
|
179 |
do_test in-6.2 {
|
sl@0
|
180 |
execsql {
|
sl@0
|
181 |
CREATE TABLE tb(a INTEGER PRIMARY KEY, b);
|
sl@0
|
182 |
INSERT INTO tb VALUES(1,1);
|
sl@0
|
183 |
INSERT INTO tb VALUES(2,2);
|
sl@0
|
184 |
INSERT INTO tb VALUES(3,3);
|
sl@0
|
185 |
INSERT INTO tb VALUES(5,5);
|
sl@0
|
186 |
INSERT INTO tb VALUES(7,7);
|
sl@0
|
187 |
INSERT INTO tb VALUES(9,9);
|
sl@0
|
188 |
INSERT INTO tb VALUES(11,
|
sl@0
|
189 |
'This is a key that is long enough to require a malloc in the VDBE');
|
sl@0
|
190 |
SELECT * FROM tb WHERE a<10;
|
sl@0
|
191 |
}
|
sl@0
|
192 |
} {1 1 2 2 3 3 5 5 7 7 9 9}
|
sl@0
|
193 |
do_test in-6.3 {
|
sl@0
|
194 |
execsql {
|
sl@0
|
195 |
SELECT a FROM ta WHERE b IN (SELECT a FROM tb);
|
sl@0
|
196 |
}
|
sl@0
|
197 |
} {1 2 3}
|
sl@0
|
198 |
do_test in-6.4 {
|
sl@0
|
199 |
execsql {
|
sl@0
|
200 |
SELECT a FROM ta WHERE b NOT IN (SELECT a FROM tb);
|
sl@0
|
201 |
}
|
sl@0
|
202 |
} {4 6 8 10}
|
sl@0
|
203 |
do_test in-6.5 {
|
sl@0
|
204 |
execsql {
|
sl@0
|
205 |
SELECT a FROM ta WHERE b IN (SELECT b FROM tb);
|
sl@0
|
206 |
}
|
sl@0
|
207 |
} {1 2 3 10}
|
sl@0
|
208 |
do_test in-6.6 {
|
sl@0
|
209 |
execsql {
|
sl@0
|
210 |
SELECT a FROM ta WHERE b NOT IN (SELECT b FROM tb);
|
sl@0
|
211 |
}
|
sl@0
|
212 |
} {4 6 8}
|
sl@0
|
213 |
do_test in-6.7 {
|
sl@0
|
214 |
execsql {
|
sl@0
|
215 |
SELECT a FROM ta WHERE a IN (SELECT a FROM tb);
|
sl@0
|
216 |
}
|
sl@0
|
217 |
} {1 2 3}
|
sl@0
|
218 |
do_test in-6.8 {
|
sl@0
|
219 |
execsql {
|
sl@0
|
220 |
SELECT a FROM ta WHERE a NOT IN (SELECT a FROM tb);
|
sl@0
|
221 |
}
|
sl@0
|
222 |
} {4 6 8 10}
|
sl@0
|
223 |
do_test in-6.9 {
|
sl@0
|
224 |
execsql {
|
sl@0
|
225 |
SELECT a FROM ta WHERE a IN (SELECT b FROM tb);
|
sl@0
|
226 |
}
|
sl@0
|
227 |
} {1 2 3}
|
sl@0
|
228 |
do_test in-6.10 {
|
sl@0
|
229 |
execsql {
|
sl@0
|
230 |
SELECT a FROM ta WHERE a NOT IN (SELECT b FROM tb);
|
sl@0
|
231 |
}
|
sl@0
|
232 |
} {4 6 8 10}
|
sl@0
|
233 |
|
sl@0
|
234 |
# Tests of IN operator against empty sets. (Ticket #185)
|
sl@0
|
235 |
#
|
sl@0
|
236 |
do_test in-7.1 {
|
sl@0
|
237 |
execsql {
|
sl@0
|
238 |
SELECT a FROM t1 WHERE a IN ();
|
sl@0
|
239 |
}
|
sl@0
|
240 |
} {}
|
sl@0
|
241 |
do_test in-7.2 {
|
sl@0
|
242 |
execsql {
|
sl@0
|
243 |
SELECT a FROM t1 WHERE a IN (5);
|
sl@0
|
244 |
}
|
sl@0
|
245 |
} {5}
|
sl@0
|
246 |
do_test in-7.3 {
|
sl@0
|
247 |
execsql {
|
sl@0
|
248 |
SELECT a FROM t1 WHERE a NOT IN () ORDER BY a;
|
sl@0
|
249 |
}
|
sl@0
|
250 |
} {5 6 7 8 hello}
|
sl@0
|
251 |
do_test in-7.4 {
|
sl@0
|
252 |
execsql {
|
sl@0
|
253 |
SELECT a FROM t1 WHERE a IN (5) AND b IN ();
|
sl@0
|
254 |
}
|
sl@0
|
255 |
} {}
|
sl@0
|
256 |
do_test in-7.5 {
|
sl@0
|
257 |
execsql {
|
sl@0
|
258 |
SELECT a FROM t1 WHERE a IN (5) AND b NOT IN ();
|
sl@0
|
259 |
}
|
sl@0
|
260 |
} {5}
|
sl@0
|
261 |
do_test in-7.6 {
|
sl@0
|
262 |
execsql {
|
sl@0
|
263 |
SELECT a FROM ta WHERE a IN ();
|
sl@0
|
264 |
}
|
sl@0
|
265 |
} {}
|
sl@0
|
266 |
do_test in-7.7 {
|
sl@0
|
267 |
execsql {
|
sl@0
|
268 |
SELECT a FROM ta WHERE a NOT IN ();
|
sl@0
|
269 |
}
|
sl@0
|
270 |
} {1 2 3 4 6 8 10}
|
sl@0
|
271 |
|
sl@0
|
272 |
do_test in-8.1 {
|
sl@0
|
273 |
execsql {
|
sl@0
|
274 |
SELECT b FROM t1 WHERE a IN ('hello','there')
|
sl@0
|
275 |
}
|
sl@0
|
276 |
} {world}
|
sl@0
|
277 |
do_test in-8.2 {
|
sl@0
|
278 |
execsql {
|
sl@0
|
279 |
SELECT b FROM t1 WHERE a IN ("hello",'there')
|
sl@0
|
280 |
}
|
sl@0
|
281 |
} {world}
|
sl@0
|
282 |
|
sl@0
|
283 |
# Test constructs of the form: expr IN tablename
|
sl@0
|
284 |
#
|
sl@0
|
285 |
do_test in-9.1 {
|
sl@0
|
286 |
execsql {
|
sl@0
|
287 |
CREATE TABLE t4 AS SELECT a FROM tb;
|
sl@0
|
288 |
SELECT * FROM t4;
|
sl@0
|
289 |
}
|
sl@0
|
290 |
} {1 2 3 5 7 9 11}
|
sl@0
|
291 |
do_test in-9.2 {
|
sl@0
|
292 |
execsql {
|
sl@0
|
293 |
SELECT b FROM t1 WHERE a IN t4;
|
sl@0
|
294 |
}
|
sl@0
|
295 |
} {32 128}
|
sl@0
|
296 |
do_test in-9.3 {
|
sl@0
|
297 |
execsql {
|
sl@0
|
298 |
SELECT b FROM t1 WHERE a NOT IN t4;
|
sl@0
|
299 |
}
|
sl@0
|
300 |
} {64 256 world}
|
sl@0
|
301 |
do_test in-9.4 {
|
sl@0
|
302 |
catchsql {
|
sl@0
|
303 |
SELECT b FROM t1 WHERE a NOT IN tb;
|
sl@0
|
304 |
}
|
sl@0
|
305 |
} {1 {only a single result allowed for a SELECT that is part of an expression}}
|
sl@0
|
306 |
|
sl@0
|
307 |
# IN clauses in CHECK constraints. Ticket #1645
|
sl@0
|
308 |
#
|
sl@0
|
309 |
do_test in-10.1 {
|
sl@0
|
310 |
execsql {
|
sl@0
|
311 |
CREATE TABLE t5(
|
sl@0
|
312 |
a INTEGER,
|
sl@0
|
313 |
CHECK( a IN (111,222,333) )
|
sl@0
|
314 |
);
|
sl@0
|
315 |
INSERT INTO t5 VALUES(111);
|
sl@0
|
316 |
SELECT * FROM t5;
|
sl@0
|
317 |
}
|
sl@0
|
318 |
} {111}
|
sl@0
|
319 |
do_test in-10.2 {
|
sl@0
|
320 |
catchsql {
|
sl@0
|
321 |
INSERT INTO t5 VALUES(4);
|
sl@0
|
322 |
}
|
sl@0
|
323 |
} {1 {constraint failed}}
|
sl@0
|
324 |
|
sl@0
|
325 |
# Ticket #1821
|
sl@0
|
326 |
#
|
sl@0
|
327 |
# Type affinity applied to the right-hand side of an IN operator.
|
sl@0
|
328 |
#
|
sl@0
|
329 |
do_test in-11.1 {
|
sl@0
|
330 |
execsql {
|
sl@0
|
331 |
CREATE TABLE t6(a,b NUMERIC);
|
sl@0
|
332 |
INSERT INTO t6 VALUES(1,2);
|
sl@0
|
333 |
INSERT INTO t6 VALUES(2,3);
|
sl@0
|
334 |
SELECT * FROM t6 WHERE b IN (2);
|
sl@0
|
335 |
}
|
sl@0
|
336 |
} {1 2}
|
sl@0
|
337 |
do_test in-11.2 {
|
sl@0
|
338 |
# The '2' should be coerced into 2 because t6.b is NUMERIC
|
sl@0
|
339 |
execsql {
|
sl@0
|
340 |
SELECT * FROM t6 WHERE b IN ('2');
|
sl@0
|
341 |
}
|
sl@0
|
342 |
} {1 2}
|
sl@0
|
343 |
do_test in-11.3 {
|
sl@0
|
344 |
# No coercion should occur here because of the unary + before b.
|
sl@0
|
345 |
execsql {
|
sl@0
|
346 |
SELECT * FROM t6 WHERE +b IN ('2');
|
sl@0
|
347 |
}
|
sl@0
|
348 |
} {}
|
sl@0
|
349 |
do_test in-11.4 {
|
sl@0
|
350 |
# No coercion because column a as affinity NONE
|
sl@0
|
351 |
execsql {
|
sl@0
|
352 |
SELECT * FROM t6 WHERE a IN ('2');
|
sl@0
|
353 |
}
|
sl@0
|
354 |
} {}
|
sl@0
|
355 |
do_test in-11.5 {
|
sl@0
|
356 |
execsql {
|
sl@0
|
357 |
SELECT * FROM t6 WHERE a IN (2);
|
sl@0
|
358 |
}
|
sl@0
|
359 |
} {2 3}
|
sl@0
|
360 |
do_test in-11.6 {
|
sl@0
|
361 |
# No coercion because column a as affinity NONE
|
sl@0
|
362 |
execsql {
|
sl@0
|
363 |
SELECT * FROM t6 WHERE +a IN ('2');
|
sl@0
|
364 |
}
|
sl@0
|
365 |
} {}
|
sl@0
|
366 |
|
sl@0
|
367 |
# Test error conditions with expressions of the form IN(<compound select>).
|
sl@0
|
368 |
#
|
sl@0
|
369 |
ifcapable compound {
|
sl@0
|
370 |
do_test in-12.1 {
|
sl@0
|
371 |
execsql {
|
sl@0
|
372 |
CREATE TABLE t2(a, b, c);
|
sl@0
|
373 |
CREATE TABLE t3(a, b, c);
|
sl@0
|
374 |
}
|
sl@0
|
375 |
} {}
|
sl@0
|
376 |
do_test in-12.2 {
|
sl@0
|
377 |
catchsql {
|
sl@0
|
378 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
379 |
SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2
|
sl@0
|
380 |
);
|
sl@0
|
381 |
}
|
sl@0
|
382 |
} {1 {only a single result allowed for a SELECT that is part of an expression}}
|
sl@0
|
383 |
do_test in-12.3 {
|
sl@0
|
384 |
catchsql {
|
sl@0
|
385 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
386 |
SELECT a, b FROM t3 UNION SELECT a, b FROM t2
|
sl@0
|
387 |
);
|
sl@0
|
388 |
}
|
sl@0
|
389 |
} {1 {only a single result allowed for a SELECT that is part of an expression}}
|
sl@0
|
390 |
do_test in-12.4 {
|
sl@0
|
391 |
catchsql {
|
sl@0
|
392 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
393 |
SELECT a, b FROM t3 EXCEPT SELECT a, b FROM t2
|
sl@0
|
394 |
);
|
sl@0
|
395 |
}
|
sl@0
|
396 |
} {1 {only a single result allowed for a SELECT that is part of an expression}}
|
sl@0
|
397 |
do_test in-12.5 {
|
sl@0
|
398 |
catchsql {
|
sl@0
|
399 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
400 |
SELECT a, b FROM t3 INTERSECT SELECT a, b FROM t2
|
sl@0
|
401 |
);
|
sl@0
|
402 |
}
|
sl@0
|
403 |
} {1 {only a single result allowed for a SELECT that is part of an expression}}
|
sl@0
|
404 |
do_test in-12.6 {
|
sl@0
|
405 |
catchsql {
|
sl@0
|
406 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
407 |
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
|
sl@0
|
408 |
);
|
sl@0
|
409 |
}
|
sl@0
|
410 |
} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
|
sl@0
|
411 |
do_test in-12.7 {
|
sl@0
|
412 |
catchsql {
|
sl@0
|
413 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
414 |
SELECT a FROM t3 UNION SELECT a, b FROM t2
|
sl@0
|
415 |
);
|
sl@0
|
416 |
}
|
sl@0
|
417 |
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
|
sl@0
|
418 |
do_test in-12.8 {
|
sl@0
|
419 |
catchsql {
|
sl@0
|
420 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
421 |
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
|
sl@0
|
422 |
);
|
sl@0
|
423 |
}
|
sl@0
|
424 |
} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}}
|
sl@0
|
425 |
do_test in-12.9 {
|
sl@0
|
426 |
catchsql {
|
sl@0
|
427 |
SELECT * FROM t2 WHERE a IN (
|
sl@0
|
428 |
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
|
sl@0
|
429 |
);
|
sl@0
|
430 |
}
|
sl@0
|
431 |
} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
|
sl@0
|
432 |
}
|
sl@0
|
433 |
|
sl@0
|
434 |
|
sl@0
|
435 |
#------------------------------------------------------------------------
|
sl@0
|
436 |
# The following tests check that NULL is handled correctly when it
|
sl@0
|
437 |
# appears as part of a set of values on the right-hand side of an
|
sl@0
|
438 |
# IN or NOT IN operator.
|
sl@0
|
439 |
#
|
sl@0
|
440 |
# When it appears in such a set, NULL is handled as an "unknown value".
|
sl@0
|
441 |
# If, because of the unknown value in the set, the result of the expression
|
sl@0
|
442 |
# cannot be determined, then it itself evaluates to NULL.
|
sl@0
|
443 |
#
|
sl@0
|
444 |
|
sl@0
|
445 |
# Warm body test to demonstrate the principles being tested:
|
sl@0
|
446 |
#
|
sl@0
|
447 |
do_test in-13.1 {
|
sl@0
|
448 |
db nullvalue "null"
|
sl@0
|
449 |
execsql { SELECT
|
sl@0
|
450 |
1 IN (NULL, 1, 2), -- The value 1 is a member of the set, return true.
|
sl@0
|
451 |
3 IN (NULL, 1, 2), -- Ambiguous, return NULL.
|
sl@0
|
452 |
1 NOT IN (NULL, 1, 2), -- The value 1 is a member of the set, return false.
|
sl@0
|
453 |
3 NOT IN (NULL, 1, 2) -- Ambiguous, return NULL.
|
sl@0
|
454 |
}
|
sl@0
|
455 |
} {1 null 0 null}
|
sl@0
|
456 |
|
sl@0
|
457 |
do_test in-13.2 {
|
sl@0
|
458 |
execsql {
|
sl@0
|
459 |
CREATE TABLE t7(a, b, c NOT NULL);
|
sl@0
|
460 |
INSERT INTO t7 VALUES(1, 1, 1);
|
sl@0
|
461 |
INSERT INTO t7 VALUES(2, 2, 2);
|
sl@0
|
462 |
INSERT INTO t7 VALUES(3, 3, 3);
|
sl@0
|
463 |
INSERT INTO t7 VALUES(NULL, 4, 4);
|
sl@0
|
464 |
INSERT INTO t7 VALUES(NULL, 5, 5);
|
sl@0
|
465 |
}
|
sl@0
|
466 |
} {}
|
sl@0
|
467 |
|
sl@0
|
468 |
do_test in-13.3 {
|
sl@0
|
469 |
execsql { SELECT 2 IN (SELECT a FROM t7) }
|
sl@0
|
470 |
} {1}
|
sl@0
|
471 |
do_test in-13.4 {
|
sl@0
|
472 |
execsql { SELECT 6 IN (SELECT a FROM t7) }
|
sl@0
|
473 |
} {null}
|
sl@0
|
474 |
|
sl@0
|
475 |
do_test in-13.5 {
|
sl@0
|
476 |
execsql { SELECT 2 IN (SELECT b FROM t7) }
|
sl@0
|
477 |
} {1}
|
sl@0
|
478 |
do_test in-13.6 {
|
sl@0
|
479 |
execsql { SELECT 6 IN (SELECT b FROM t7) }
|
sl@0
|
480 |
} {0}
|
sl@0
|
481 |
|
sl@0
|
482 |
do_test in-13.7 {
|
sl@0
|
483 |
execsql { SELECT 2 IN (SELECT c FROM t7) }
|
sl@0
|
484 |
} {1}
|
sl@0
|
485 |
do_test in-13.8 {
|
sl@0
|
486 |
execsql { SELECT 6 IN (SELECT c FROM t7) }
|
sl@0
|
487 |
} {0}
|
sl@0
|
488 |
|
sl@0
|
489 |
do_test in-13.9 {
|
sl@0
|
490 |
execsql {
|
sl@0
|
491 |
SELECT
|
sl@0
|
492 |
2 NOT IN (SELECT a FROM t7),
|
sl@0
|
493 |
6 NOT IN (SELECT a FROM t7),
|
sl@0
|
494 |
2 NOT IN (SELECT b FROM t7),
|
sl@0
|
495 |
6 NOT IN (SELECT b FROM t7),
|
sl@0
|
496 |
2 NOT IN (SELECT c FROM t7),
|
sl@0
|
497 |
6 NOT IN (SELECT c FROM t7)
|
sl@0
|
498 |
}
|
sl@0
|
499 |
} {0 null 0 1 0 1}
|
sl@0
|
500 |
|
sl@0
|
501 |
do_test in-13.10 {
|
sl@0
|
502 |
execsql {
|
sl@0
|
503 |
SELECT b IN (
|
sl@0
|
504 |
SELECT inside.a
|
sl@0
|
505 |
FROM t7 AS inside
|
sl@0
|
506 |
WHERE inside.b BETWEEN outside.b+1 AND outside.b+2
|
sl@0
|
507 |
)
|
sl@0
|
508 |
FROM t7 AS outside ORDER BY b;
|
sl@0
|
509 |
}
|
sl@0
|
510 |
} {0 null null null 0}
|
sl@0
|
511 |
|
sl@0
|
512 |
do_test in-13.11 {
|
sl@0
|
513 |
execsql {
|
sl@0
|
514 |
SELECT b NOT IN (
|
sl@0
|
515 |
SELECT inside.a
|
sl@0
|
516 |
FROM t7 AS inside
|
sl@0
|
517 |
WHERE inside.b BETWEEN outside.b+1 AND outside.b+2
|
sl@0
|
518 |
)
|
sl@0
|
519 |
FROM t7 AS outside ORDER BY b;
|
sl@0
|
520 |
}
|
sl@0
|
521 |
} {1 null null null 1}
|
sl@0
|
522 |
|
sl@0
|
523 |
do_test in-13.12 {
|
sl@0
|
524 |
execsql {
|
sl@0
|
525 |
CREATE INDEX i1 ON t7(a);
|
sl@0
|
526 |
CREATE INDEX i2 ON t7(b);
|
sl@0
|
527 |
CREATE INDEX i3 ON t7(c);
|
sl@0
|
528 |
}
|
sl@0
|
529 |
execsql {
|
sl@0
|
530 |
SELECT
|
sl@0
|
531 |
2 IN (SELECT a FROM t7),
|
sl@0
|
532 |
6 IN (SELECT a FROM t7),
|
sl@0
|
533 |
2 IN (SELECT b FROM t7),
|
sl@0
|
534 |
6 IN (SELECT b FROM t7),
|
sl@0
|
535 |
2 IN (SELECT c FROM t7),
|
sl@0
|
536 |
6 IN (SELECT c FROM t7)
|
sl@0
|
537 |
}
|
sl@0
|
538 |
} {1 null 1 0 1 0}
|
sl@0
|
539 |
|
sl@0
|
540 |
do_test in-13.13 {
|
sl@0
|
541 |
execsql {
|
sl@0
|
542 |
SELECT
|
sl@0
|
543 |
2 NOT IN (SELECT a FROM t7),
|
sl@0
|
544 |
6 NOT IN (SELECT a FROM t7),
|
sl@0
|
545 |
2 NOT IN (SELECT b FROM t7),
|
sl@0
|
546 |
6 NOT IN (SELECT b FROM t7),
|
sl@0
|
547 |
2 NOT IN (SELECT c FROM t7),
|
sl@0
|
548 |
6 NOT IN (SELECT c FROM t7)
|
sl@0
|
549 |
}
|
sl@0
|
550 |
} {0 null 0 1 0 1}
|
sl@0
|
551 |
|
sl@0
|
552 |
do_test in-13.14 {
|
sl@0
|
553 |
execsql {
|
sl@0
|
554 |
BEGIN TRANSACTION;
|
sl@0
|
555 |
CREATE TABLE a(id INTEGER);
|
sl@0
|
556 |
INSERT INTO a VALUES(1);
|
sl@0
|
557 |
INSERT INTO a VALUES(2);
|
sl@0
|
558 |
INSERT INTO a VALUES(3);
|
sl@0
|
559 |
CREATE TABLE b(id INTEGER);
|
sl@0
|
560 |
INSERT INTO b VALUES(NULL);
|
sl@0
|
561 |
INSERT INTO b VALUES(3);
|
sl@0
|
562 |
INSERT INTO b VALUES(4);
|
sl@0
|
563 |
INSERT INTO b VALUES(5);
|
sl@0
|
564 |
COMMIT;
|
sl@0
|
565 |
SELECT * FROM a WHERE id NOT IN (SELECT id FROM b);
|
sl@0
|
566 |
}
|
sl@0
|
567 |
} {}
|
sl@0
|
568 |
do_test in-13.14 {
|
sl@0
|
569 |
execsql {
|
sl@0
|
570 |
CREATE INDEX i5 ON b(id);
|
sl@0
|
571 |
SELECT * FROM a WHERE id NOT IN (SELECT id FROM b);
|
sl@0
|
572 |
}
|
sl@0
|
573 |
} {}
|
sl@0
|
574 |
|
sl@0
|
575 |
|
sl@0
|
576 |
do_test in-13.X {
|
sl@0
|
577 |
db nullvalue ""
|
sl@0
|
578 |
} {}
|
sl@0
|
579 |
|
sl@0
|
580 |
finish_test
|