sl@0: # The author disclaims copyright to this source code. In place of sl@0: # a legal notice, here is a blessing: sl@0: # sl@0: # May you do good and not evil. sl@0: # May you find forgiveness for yourself and forgive others. sl@0: # May you share freely, never taking more than you give. sl@0: # sl@0: #*********************************************************************** sl@0: # This file implements regression tests for SQLite library. The sl@0: # focus of this file is testing compute SELECT statements and nested sl@0: # views. sl@0: # sl@0: # $Id: select7.test,v 1.11 2007/09/12 17:01:45 danielk1977 Exp $ sl@0: sl@0: sl@0: set testdir [file dirname $argv0] sl@0: source $testdir/tester.tcl sl@0: sl@0: ifcapable compound { sl@0: sl@0: # A 3-way INTERSECT. Ticket #875 sl@0: ifcapable tempdb { sl@0: do_test select7-1.1 { sl@0: execsql { sl@0: create temp table t1(x); sl@0: insert into t1 values('amx'); sl@0: insert into t1 values('anx'); sl@0: insert into t1 values('amy'); sl@0: insert into t1 values('bmy'); sl@0: select * from t1 where x like 'a__' sl@0: intersect select * from t1 where x like '_m_' sl@0: intersect select * from t1 where x like '__x'; sl@0: } sl@0: } {amx} sl@0: } sl@0: sl@0: sl@0: # Nested views do not handle * properly. Ticket #826. sl@0: # sl@0: ifcapable view { sl@0: do_test select7-2.1 { sl@0: execsql { sl@0: CREATE TABLE x(id integer primary key, a TEXT NULL); sl@0: INSERT INTO x (a) VALUES ('first'); sl@0: CREATE TABLE tempx(id integer primary key, a TEXT NULL); sl@0: INSERT INTO tempx (a) VALUES ('t-first'); sl@0: CREATE VIEW tv1 AS SELECT x.id, tx.id FROM x JOIN tempx tx ON tx.id=x.id; sl@0: CREATE VIEW tv1b AS SELECT x.id, tx.id FROM x JOIN tempx tx on tx.id=x.id; sl@0: CREATE VIEW tv2 AS SELECT * FROM tv1 UNION SELECT * FROM tv1b; sl@0: SELECT * FROM tv2; sl@0: } sl@0: } {1 1} sl@0: } ;# ifcapable view sl@0: sl@0: } ;# ifcapable compound sl@0: sl@0: # Do not allow GROUP BY without an aggregate. Ticket #1039. sl@0: # sl@0: # Change: force any query with a GROUP BY clause to be processed as sl@0: # an aggregate query, whether it contains aggregates or not. sl@0: # sl@0: ifcapable subquery { sl@0: # do_test select7-3.1 { sl@0: # catchsql { sl@0: # SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name sl@0: # } sl@0: # } {1 {GROUP BY may only be used on aggregate queries}} sl@0: do_test select7-3.1 { sl@0: catchsql { sl@0: SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name sl@0: } sl@0: } [list 0 [execsql {SELECT * FROM sqlite_master ORDER BY name}]] sl@0: } sl@0: sl@0: # Ticket #2018 - Make sure names are resolved correctly on all sl@0: # SELECT statements of a compound subquery. sl@0: # sl@0: ifcapable {subquery && compound} { sl@0: do_test select7-4.1 { sl@0: execsql { sl@0: CREATE TABLE IF NOT EXISTS photo(pk integer primary key, x); sl@0: CREATE TABLE IF NOT EXISTS tag(pk integer primary key, fk int, name); sl@0: sl@0: SELECT P.pk from PHOTO P WHERE NOT EXISTS ( sl@0: SELECT T2.pk from TAG T2 WHERE T2.fk = P.pk sl@0: EXCEPT sl@0: SELECT T3.pk from TAG T3 WHERE T3.fk = P.pk AND T3.name LIKE '%foo%' sl@0: ); sl@0: } sl@0: } {} sl@0: do_test select7-4.2 { sl@0: execsql { sl@0: INSERT INTO photo VALUES(1,1); sl@0: INSERT INTO photo VALUES(2,2); sl@0: INSERT INTO photo VALUES(3,3); sl@0: INSERT INTO tag VALUES(11,1,'one'); sl@0: INSERT INTO tag VALUES(12,1,'two'); sl@0: INSERT INTO tag VALUES(21,1,'one-b'); sl@0: SELECT P.pk from PHOTO P WHERE NOT EXISTS ( sl@0: SELECT T2.pk from TAG T2 WHERE T2.fk = P.pk sl@0: EXCEPT sl@0: SELECT T3.pk from TAG T3 WHERE T3.fk = P.pk AND T3.name LIKE '%foo%' sl@0: ); sl@0: } sl@0: } {2 3} sl@0: } sl@0: sl@0: # ticket #2347 sl@0: # sl@0: ifcapable {subquery && compound} { sl@0: do_test select7-5.1 { sl@0: catchsql { sl@0: CREATE TABLE t2(a,b); sl@0: SELECT 5 IN (SELECT a,b FROM t2); sl@0: } sl@0: } [list 1 \ sl@0: {only a single result allowed for a SELECT that is part of an expression}] sl@0: do_test select7-5.2 { sl@0: catchsql { sl@0: SELECT 5 IN (SELECT * FROM t2); sl@0: } sl@0: } [list 1 \ sl@0: {only a single result allowed for a SELECT that is part of an expression}] sl@0: do_test select7-5.3 { sl@0: catchsql { sl@0: SELECT 5 IN (SELECT a,b FROM t2 UNION SELECT b,a FROM t2); sl@0: } sl@0: } [list 1 \ sl@0: {only a single result allowed for a SELECT that is part of an expression}] sl@0: do_test select7-5.4 { sl@0: catchsql { sl@0: SELECT 5 IN (SELECT * FROM t2 UNION SELECT * FROM t2); sl@0: } sl@0: } [list 1 \ sl@0: {only a single result allowed for a SELECT that is part of an expression}] sl@0: } sl@0: sl@0: # Verify that an error occurs if you have too many terms on a sl@0: # compound select statement. sl@0: # sl@0: ifcapable compound { sl@0: if {$SQLITE_MAX_COMPOUND_SELECT>0} { sl@0: set sql {SELECT 0} sl@0: set result 0 sl@0: for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} { sl@0: append sql " UNION ALL SELECT $i" sl@0: lappend result $i sl@0: } sl@0: do_test select7-6.1 { sl@0: catchsql $sql sl@0: } [list 0 $result] sl@0: append sql { UNION ALL SELECT 99999999} sl@0: do_test select7-6.2 { sl@0: catchsql $sql sl@0: } {1 {too many terms in compound SELECT}} sl@0: } sl@0: } sl@0: sl@0: finish_test