1 2#pragma ident "%Z%%M% %I% %E% SMI" 3 4# 2001 September 15 5# 6# The author disclaims copyright to this source code. In place of 7# a legal notice, here is a blessing: 8# 9# May you do good and not evil. 10# May you find forgiveness for yourself and forgive others. 11# May you share freely, never taking more than you give. 12# 13#*********************************************************************** 14# This file implements regression tests for SQLite library. The 15# focus of this file is testing the IN and BETWEEN operator. 16# 17# $Id: in.test,v 1.11 2004/01/15 03:30:25 drh Exp $ 18 19set testdir [file dirname $argv0] 20source $testdir/tester.tcl 21 22# Generate the test data we will need for the first squences of tests. 23# 24do_test in-1.0 { 25 set fd [open data1.txt w] 26 for {set i 1} {$i<=10} {incr i} { 27 puts $fd "$i\t[expr {int(pow(2,$i))}]" 28 } 29 close $fd 30 execsql { 31 CREATE TABLE t1(a int, b int); 32 COPY t1 FROM 'data1.txt'; 33 } 34 file delete -force data1.txt 35 execsql {SELECT count(*) FROM t1} 36} {10} 37 38# Do basic testing of BETWEEN. 39# 40do_test in-1.1 { 41 execsql {SELECT a FROM t1 WHERE b BETWEEN 10 AND 50 ORDER BY a} 42} {4 5} 43do_test in-1.2 { 44 execsql {SELECT a FROM t1 WHERE b NOT BETWEEN 10 AND 50 ORDER BY a} 45} {1 2 3 6 7 8 9 10} 46do_test in-1.3 { 47 execsql {SELECT a FROM t1 WHERE b BETWEEN a AND a*5 ORDER BY a} 48} {1 2 3 4} 49do_test in-1.4 { 50 execsql {SELECT a FROM t1 WHERE b NOT BETWEEN a AND a*5 ORDER BY a} 51} {5 6 7 8 9 10} 52do_test in-1.6 { 53 execsql {SELECT a FROM t1 WHERE b BETWEEN a AND a*5 OR b=512 ORDER BY a} 54} {1 2 3 4 9} 55do_test in-1.7 { 56 execsql {SELECT a+ 100*(a BETWEEN 1 and 3) FROM t1 ORDER BY b} 57} {101 102 103 4 5 6 7 8 9 10} 58 59 60# Testing of the IN operator using static lists on the right-hand side. 61# 62do_test in-2.1 { 63 execsql {SELECT a FROM t1 WHERE b IN (8,12,16,24,32) ORDER BY a} 64} {3 4 5} 65do_test in-2.2 { 66 execsql {SELECT a FROM t1 WHERE b NOT IN (8,12,16,24,32) ORDER BY a} 67} {1 2 6 7 8 9 10} 68do_test in-2.3 { 69 execsql {SELECT a FROM t1 WHERE b IN (8,12,16,24,32) OR b=512 ORDER BY a} 70} {3 4 5 9} 71do_test in-2.4 { 72 execsql {SELECT a FROM t1 WHERE b NOT IN (8,12,16,24,32) OR b=512 ORDER BY a} 73} {1 2 6 7 8 9 10} 74do_test in-2.5 { 75 execsql {SELECT a+100*(b IN (8,16,24)) FROM t1 ORDER BY b} 76} {1 2 103 104 5 6 7 8 9 10} 77 78do_test in-2.6 { 79 set v [catch {execsql {SELECT a FROM t1 WHERE b IN (b+10,20)}} msg] 80 lappend v $msg 81} {1 {right-hand side of IN operator must be constant}} 82do_test in-2.7 { 83 set v [catch {execsql {SELECT a FROM t1 WHERE b IN (max(5,10,b),20)}} msg] 84 lappend v $msg 85} {1 {right-hand side of IN operator must be constant}} 86do_test in-2.8 { 87 execsql {SELECT a FROM t1 WHERE b IN (8*2,64/2) ORDER BY b} 88} {4 5} 89do_test in-2.9 { 90 set v [catch {execsql {SELECT a FROM t1 WHERE b IN (max(5,10),20)}} msg] 91 lappend v $msg 92} {1 {right-hand side of IN operator must be constant}} 93do_test in-2.10 { 94 set v [catch {execsql {SELECT a FROM t1 WHERE min(0,b IN (a,30))}} msg] 95 lappend v $msg 96} {1 {right-hand side of IN operator must be constant}} 97do_test in-2.11 { 98 set v [catch {execsql {SELECT a FROM t1 WHERE c IN (10,20)}} msg] 99 lappend v $msg 100} {1 {no such column: c}} 101 102# Testing the IN operator where the right-hand side is a SELECT 103# 104do_test in-3.1 { 105 execsql { 106 SELECT a FROM t1 107 WHERE b IN (SELECT b FROM t1 WHERE a<5) 108 ORDER BY a 109 } 110} {1 2 3 4} 111do_test in-3.2 { 112 execsql { 113 SELECT a FROM t1 114 WHERE b IN (SELECT b FROM t1 WHERE a<5) OR b==512 115 ORDER BY a 116 } 117} {1 2 3 4 9} 118do_test in-3.3 { 119 execsql { 120 SELECT a + 100*(b IN (SELECT b FROM t1 WHERE a<5)) FROM t1 ORDER BY b 121 } 122} {101 102 103 104 5 6 7 8 9 10} 123 124# Make sure the UPDATE and DELETE commands work with IN-SELECT 125# 126do_test in-4.1 { 127 execsql { 128 UPDATE t1 SET b=b*2 129 WHERE b IN (SELECT b FROM t1 WHERE a>8) 130 } 131 execsql {SELECT b FROM t1 ORDER BY b} 132} {2 4 8 16 32 64 128 256 1024 2048} 133do_test in-4.2 { 134 execsql { 135 DELETE FROM t1 WHERE b IN (SELECT b FROM t1 WHERE a>8) 136 } 137 execsql {SELECT a FROM t1 ORDER BY a} 138} {1 2 3 4 5 6 7 8} 139do_test in-4.3 { 140 execsql { 141 DELETE FROM t1 WHERE b NOT IN (SELECT b FROM t1 WHERE a>4) 142 } 143 execsql {SELECT a FROM t1 ORDER BY a} 144} {5 6 7 8} 145 146# Do an IN with a constant RHS but where the RHS has many, many 147# elements. We need to test that collisions in the hash table 148# are resolved properly. 149# 150do_test in-5.1 { 151 execsql { 152 INSERT INTO t1 VALUES('hello', 'world'); 153 SELECT * FROM t1 154 WHERE a IN ( 155 'Do','an','IN','with','a','constant','RHS','but','where','the', 156 'has','many','elements','We','need','to','test','that', 157 'collisions','hash','table','are','resolved','properly', 158 'This','in-set','contains','thirty','one','entries','hello'); 159 } 160} {hello world} 161 162# Make sure the IN operator works with INTEGER PRIMARY KEY fields. 163# 164do_test in-6.1 { 165 execsql { 166 CREATE TABLE ta(a INTEGER PRIMARY KEY, b); 167 INSERT INTO ta VALUES(1,1); 168 INSERT INTO ta VALUES(2,2); 169 INSERT INTO ta VALUES(3,3); 170 INSERT INTO ta VALUES(4,4); 171 INSERT INTO ta VALUES(6,6); 172 INSERT INTO ta VALUES(8,8); 173 INSERT INTO ta VALUES(10, 174 'This is a key that is long enough to require a malloc in the VDBE'); 175 SELECT * FROM ta WHERE a<10; 176 } 177} {1 1 2 2 3 3 4 4 6 6 8 8} 178do_test in-6.2 { 179 execsql { 180 CREATE TABLE tb(a INTEGER PRIMARY KEY, b); 181 INSERT INTO tb VALUES(1,1); 182 INSERT INTO tb VALUES(2,2); 183 INSERT INTO tb VALUES(3,3); 184 INSERT INTO tb VALUES(5,5); 185 INSERT INTO tb VALUES(7,7); 186 INSERT INTO tb VALUES(9,9); 187 INSERT INTO tb VALUES(11, 188 'This is a key that is long enough to require a malloc in the VDBE'); 189 SELECT * FROM tb WHERE a<10; 190 } 191} {1 1 2 2 3 3 5 5 7 7 9 9} 192do_test in-6.3 { 193 execsql { 194 SELECT a FROM ta WHERE b IN (SELECT a FROM tb); 195 } 196} {1 2 3} 197do_test in-6.4 { 198 execsql { 199 SELECT a FROM ta WHERE b NOT IN (SELECT a FROM tb); 200 } 201} {4 6 8 10} 202do_test in-6.5 { 203 execsql { 204 SELECT a FROM ta WHERE b IN (SELECT b FROM tb); 205 } 206} {1 2 3 10} 207do_test in-6.6 { 208 execsql { 209 SELECT a FROM ta WHERE b NOT IN (SELECT b FROM tb); 210 } 211} {4 6 8} 212do_test in-6.7 { 213 execsql { 214 SELECT a FROM ta WHERE a IN (SELECT a FROM tb); 215 } 216} {1 2 3} 217do_test in-6.8 { 218 execsql { 219 SELECT a FROM ta WHERE a NOT IN (SELECT a FROM tb); 220 } 221} {4 6 8 10} 222do_test in-6.9 { 223 execsql { 224 SELECT a FROM ta WHERE a IN (SELECT b FROM tb); 225 } 226} {1 2 3} 227do_test in-6.10 { 228 execsql { 229 SELECT a FROM ta WHERE a NOT IN (SELECT b FROM tb); 230 } 231} {4 6 8 10} 232 233# Tests of IN operator against empty sets. (Ticket #185) 234# 235do_test in-7.1 { 236 execsql { 237 SELECT a FROM t1 WHERE a IN (); 238 } 239} {} 240do_test in-7.2 { 241 execsql { 242 SELECT a FROM t1 WHERE a IN (5); 243 } 244} {5} 245do_test in-7.3 { 246 execsql { 247 SELECT a FROM t1 WHERE a NOT IN () ORDER BY a; 248 } 249} {5 6 7 8 hello} 250do_test in-7.4 { 251 execsql { 252 SELECT a FROM t1 WHERE a IN (5) AND b IN (); 253 } 254} {} 255do_test in-7.5 { 256 execsql { 257 SELECT a FROM t1 WHERE a IN (5) AND b NOT IN (); 258 } 259} {5} 260do_test in-7.6 { 261 execsql { 262 SELECT a FROM ta WHERE a IN (); 263 } 264} {} 265do_test in-7.7 { 266 execsql { 267 SELECT a FROM ta WHERE a NOT IN (); 268 } 269} {1 2 3 4 6 8 10} 270 271do_test in-8.1 { 272 execsql { 273 SELECT b FROM t1 WHERE a IN ('hello','there') 274 } 275} {world} 276do_test in-8.2 { 277 execsql { 278 SELECT b FROM t1 WHERE a IN ("hello",'there') 279 } 280} {world} 281 282# Test constructs of the form: expr IN tablename 283# 284do_test in-9.1 { 285 execsql { 286 CREATE TABLE t4 AS SELECT a FROM tb; 287 SELECT * FROM t4; 288 } 289} {1 2 3 5 7 9 11} 290do_test in-9.2 { 291 execsql { 292 SELECT b FROM t1 WHERE a IN t4; 293 } 294} {32 128} 295do_test in-9.3 { 296 execsql { 297 SELECT b FROM t1 WHERE a NOT IN t4; 298 } 299} {64 256 world} 300do_test in-9.4 { 301 catchsql { 302 SELECT b FROM t1 WHERE a NOT IN tb; 303 } 304} {1 {only a single result allowed for a SELECT that is part of an expression}} 305 306finish_test 307