1# 2001 September 15 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 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. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this file is testing SELECT statements that are part of 13# expressions. 14# 15# $Id: subselect.test,v 1.15 2008/07/15 00:27:35 drh Exp $ 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# Omit this whole file if the library is build without subquery support. 21ifcapable !subquery { 22 finish_test 23 return 24} 25 26# Basic sanity checking. Try a simple subselect. 27# 28do_test subselect-1.1 { 29 execsql { 30 CREATE TABLE t1(a int, b int); 31 INSERT INTO t1 VALUES(1,2); 32 INSERT INTO t1 VALUES(3,4); 33 INSERT INTO t1 VALUES(5,6); 34 } 35 execsql {SELECT * FROM t1 WHERE a = (SELECT count(*) FROM t1)} 36} {3 4} 37 38# Try a select with more than one result column. 39# 40do_test subselect-1.2 { 41 set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg] 42 lappend v $msg 43} {1 {only a single result allowed for a SELECT that is part of an expression}} 44 45# A subselect without an aggregate. 46# 47do_test subselect-1.3a { 48 execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=2)} 49} {2} 50do_test subselect-1.3b { 51 execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=4)} 52} {4} 53do_test subselect-1.3c { 54 execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=6)} 55} {6} 56do_test subselect-1.3d { 57 execsql {SELECT b from t1 where a = (SELECT a FROM t1 WHERE b=8)} 58} {} 59do_test subselect-1.3e { 60 execsql { 61 SELECT b FROM t1 62 WHERE a = (SELECT a FROM t1 UNION SELECT b FROM t1 ORDER BY 1); 63 } 64} {2} 65 66# What if the subselect doesn't return any value. We should get 67# NULL as the result. Check it out. 68# 69do_test subselect-1.4 { 70 execsql {SELECT b from t1 where a = coalesce((SELECT a FROM t1 WHERE b=5),1)} 71} {2} 72 73# Try multiple subselects within a single expression. 74# 75do_test subselect-1.5 { 76 execsql { 77 CREATE TABLE t2(x int, y int); 78 INSERT INTO t2 VALUES(1,2); 79 INSERT INTO t2 VALUES(2,4); 80 INSERT INTO t2 VALUES(3,8); 81 INSERT INTO t2 VALUES(4,16); 82 } 83 execsql { 84 SELECT y from t2 85 WHERE x = (SELECT sum(b) FROM t1 where a notnull) - (SELECT sum(a) FROM t1) 86 } 87} {8} 88 89# Try something useful. Delete every entry from t2 where the 90# x value is less than half of the maximum. 91# 92do_test subselect-1.6 { 93 execsql {DELETE FROM t2 WHERE x < 0.5*(SELECT max(x) FROM t2)} 94 execsql {SELECT x FROM t2 ORDER BY x} 95} {2 3 4} 96 97# Make sure sorting works for SELECTs there used as a scalar expression. 98# 99do_test subselect-2.1 { 100 execsql { 101 SELECT (SELECT a FROM t1 ORDER BY a), (SELECT a FROM t1 ORDER BY a DESC) 102 } 103} {1 5} 104do_test subselect-2.2 { 105 execsql { 106 SELECT 1 IN (SELECT a FROM t1 ORDER BY a); 107 } 108} {1} 109do_test subselect-2.3 { 110 execsql { 111 SELECT 2 IN (SELECT a FROM t1 ORDER BY a DESC); 112 } 113} {0} 114 115# Verify that the ORDER BY clause is honored in a subquery. 116# 117ifcapable compound { 118do_test subselect-3.1 { 119 execsql { 120 CREATE TABLE t3(x int); 121 INSERT INTO t3 SELECT a FROM t1 UNION ALL SELECT b FROM t1; 122 SELECT * FROM t3 ORDER BY x; 123 } 124} {1 2 3 4 5 6} 125} ;# ifcapable compound 126ifcapable !compound { 127do_test subselect-3.1 { 128 execsql { 129 CREATE TABLE t3(x int); 130 INSERT INTO t3 SELECT a FROM t1; 131 INSERT INTO t3 SELECT b FROM t1; 132 SELECT * FROM t3 ORDER BY x; 133 } 134} {1 2 3 4 5 6} 135} ;# ifcapable !compound 136 137do_test subselect-3.2 { 138 execsql { 139 SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x LIMIT 2); 140 } 141} {3} 142do_test subselect-3.3 { 143 execsql { 144 SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x DESC LIMIT 2); 145 } 146} {11} 147do_test subselect-3.4 { 148 execsql { 149 SELECT (SELECT x FROM t3 ORDER BY x); 150 } 151} {1} 152do_test subselect-3.5 { 153 execsql { 154 SELECT (SELECT x FROM t3 ORDER BY x DESC); 155 } 156} {6} 157do_test subselect-3.6 { 158 execsql { 159 SELECT (SELECT x FROM t3 ORDER BY x LIMIT 1); 160 } 161} {1} 162do_test subselect-3.7 { 163 execsql { 164 SELECT (SELECT x FROM t3 ORDER BY x DESC LIMIT 1); 165 } 166} {6} 167do_test subselect-3.8 { 168 execsql { 169 SELECT (SELECT x FROM t3 ORDER BY x LIMIT 1 OFFSET 2); 170 } 171} {3} 172do_test subselect-3.9 { 173 execsql { 174 SELECT (SELECT x FROM t3 ORDER BY x DESC LIMIT 1 OFFSET 2); 175 } 176} {4} 177do_test subselect-3.10 { 178 execsql { 179 SELECT x FROM t3 WHERE x IN 180 (SELECT x FROM t3 ORDER BY x DESC LIMIT 1 OFFSET 2); 181 } 182} {4} 183 184# Ticket #2295. 185# Make sure type affinities work correctly on subqueries with 186# an ORDER BY clause. 187# 188do_test subselect-4.1 { 189 execsql { 190 CREATE TABLE t4(a TEXT, b TEXT); 191 INSERT INTO t4 VALUES('a','1'); 192 INSERT INTO t4 VALUES('b','2'); 193 INSERT INTO t4 VALUES('c','3'); 194 SELECT a FROM t4 WHERE b IN (SELECT b FROM t4 ORDER BY b); 195 } 196} {a b c} 197do_test subselect-4.2 { 198 execsql { 199 SELECT a FROM t4 WHERE b IN (SELECT b FROM t4 ORDER BY b LIMIT 1); 200 } 201} {a} 202do_test subselect-4.3 { 203 execsql { 204 SELECT a FROM t4 WHERE b IN (SELECT b FROM t4 ORDER BY b DESC LIMIT 1); 205 } 206} {c} 207 208finish_test 209