mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
testing/sqlite3: Import SELECT statement TCL tests
This commit is contained in:
parent
4206fc2e23
commit
38f3d213db
18 changed files with 7351 additions and 0 deletions
21
testing/sqlite3/all.test
Executable file
21
testing/sqlite3/all.test
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env tclsh
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
||||
source $testdir/select1.test
|
||||
source $testdir/select2.test
|
||||
source $testdir/select3.test
|
||||
source $testdir/select4.test
|
||||
source $testdir/select5.test
|
||||
source $testdir/select6.test
|
||||
source $testdir/select7.test
|
||||
source $testdir/select8.test
|
||||
source $testdir/select9.test
|
||||
source $testdir/selectA.test
|
||||
source $testdir/selectB.test
|
||||
source $testdir/selectC.test
|
||||
source $testdir/selectD.test
|
||||
source $testdir/selectE.test
|
||||
source $testdir/selectF.test
|
||||
source $testdir/selectG.test
|
||||
source $testdir/selectH.test
|
1213
testing/sqlite3/select1.test
Normal file
1213
testing/sqlite3/select1.test
Normal file
File diff suppressed because it is too large
Load diff
185
testing/sqlite3/select2.test
Normal file
185
testing/sqlite3/select2.test
Normal file
|
@ -0,0 +1,185 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the SELECT statement.
|
||||
#
|
||||
# $Id: select2.test,v 1.28 2009/01/15 15:23:59 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Create a table with some data
|
||||
#
|
||||
execsql {CREATE TABLE tbl1(f1 int, f2 int)}
|
||||
execsql {BEGIN}
|
||||
for {set i 0} {$i<=30} {incr i} {
|
||||
execsql "INSERT INTO tbl1 VALUES([expr {$i%9}],[expr {$i%10}])"
|
||||
}
|
||||
execsql {COMMIT}
|
||||
|
||||
# Do a second query inside a first.
|
||||
#
|
||||
do_test select2-1.1 {
|
||||
set sql {SELECT DISTINCT f1 FROM tbl1 ORDER BY f1}
|
||||
set r {}
|
||||
catch {unset data}
|
||||
db eval $sql data {
|
||||
set f1 $data(f1)
|
||||
lappend r $f1:
|
||||
set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2"
|
||||
db eval $sql2 d2 {
|
||||
lappend r $d2(f2)
|
||||
}
|
||||
}
|
||||
set r
|
||||
} {0: 0 7 8 9 1: 0 1 8 9 2: 0 1 2 9 3: 0 1 2 3 4: 2 3 4 5: 3 4 5 6: 4 5 6 7: 5 6 7 8: 6 7 8}
|
||||
|
||||
do_test select2-1.2 {
|
||||
set sql {SELECT DISTINCT f1 FROM tbl1 WHERE f1>3 AND f1<5}
|
||||
set r {}
|
||||
db eval $sql data {
|
||||
set f1 $data(f1)
|
||||
lappend r $f1:
|
||||
set sql2 "SELECT f2 FROM tbl1 WHERE f1=$f1 ORDER BY f2"
|
||||
db eval $sql2 d2 {
|
||||
lappend r $d2(f2)
|
||||
}
|
||||
}
|
||||
set r
|
||||
} {4: 2 3 4}
|
||||
unset data
|
||||
|
||||
# Create a largish table. Do this twice, once using the TCL cache and once
|
||||
# without. Compare the performance to make sure things go faster with the
|
||||
# cache turned on.
|
||||
#
|
||||
ifcapable tclvar {
|
||||
do_test select2-2.0.1 {
|
||||
set t1 [time {
|
||||
execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int); BEGIN;}
|
||||
for {set i 1} {$i<=30000} {incr i} {
|
||||
set i2 [expr {$i*2}]
|
||||
set i3 [expr {$i*3}]
|
||||
db eval {INSERT INTO tbl2 VALUES($i,$i2,$i3)}
|
||||
}
|
||||
execsql {COMMIT}
|
||||
}]
|
||||
list
|
||||
} {}
|
||||
puts "time with cache: $::t1"
|
||||
}
|
||||
catch {execsql {DROP TABLE tbl2}}
|
||||
do_test select2-2.0.2 {
|
||||
set t2 [time {
|
||||
execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int); BEGIN;}
|
||||
for {set i 1} {$i<=30000} {incr i} {
|
||||
set i2 [expr {$i*2}]
|
||||
set i3 [expr {$i*3}]
|
||||
execsql "INSERT INTO tbl2 VALUES($i,$i2,$i3)"
|
||||
}
|
||||
execsql {COMMIT}
|
||||
}]
|
||||
list
|
||||
} {}
|
||||
puts "time without cache: $t2"
|
||||
#ifcapable tclvar {
|
||||
# do_test select2-2.0.3 {
|
||||
# expr {[lindex $t1 0]<[lindex $t2 0]}
|
||||
# } 1
|
||||
#}
|
||||
|
||||
do_test select2-2.1 {
|
||||
execsql {SELECT count(*) FROM tbl2}
|
||||
} {30000}
|
||||
do_test select2-2.2 {
|
||||
execsql {SELECT count(*) FROM tbl2 WHERE f2>1000}
|
||||
} {29500}
|
||||
|
||||
do_test select2-3.1 {
|
||||
execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}
|
||||
} {500}
|
||||
|
||||
do_test select2-3.2a {
|
||||
execsql {CREATE INDEX idx1 ON tbl2(f2)}
|
||||
} {}
|
||||
do_test select2-3.2b {
|
||||
execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}
|
||||
} {500}
|
||||
do_test select2-3.2c {
|
||||
execsql {SELECT f1 FROM tbl2 WHERE f2=1000}
|
||||
} {500}
|
||||
do_test select2-3.2d {
|
||||
set sqlite_search_count 0
|
||||
execsql {SELECT * FROM tbl2 WHERE 1000=f2}
|
||||
set sqlite_search_count
|
||||
} {3}
|
||||
do_test select2-3.2e {
|
||||
set sqlite_search_count 0
|
||||
execsql {SELECT * FROM tbl2 WHERE f2=1000}
|
||||
set sqlite_search_count
|
||||
} {3}
|
||||
|
||||
# Make sure queries run faster with an index than without
|
||||
#
|
||||
do_test select2-3.3 {
|
||||
execsql {DROP INDEX idx1}
|
||||
set sqlite_search_count 0
|
||||
execsql {SELECT f1 FROM tbl2 WHERE f2==2000}
|
||||
set sqlite_search_count
|
||||
} {29999}
|
||||
|
||||
# Make sure we can optimize functions in the WHERE clause that
|
||||
# use fields from two or more different table. (Bug #6)
|
||||
#
|
||||
do_test select2-4.1 {
|
||||
execsql {
|
||||
CREATE TABLE aa(a);
|
||||
CREATE TABLE bb(b);
|
||||
INSERT INTO aa VALUES(1);
|
||||
INSERT INTO aa VALUES(3);
|
||||
INSERT INTO bb VALUES(2);
|
||||
INSERT INTO bb VALUES(4);
|
||||
SELECT * FROM aa, bb WHERE max(a,b)>2;
|
||||
}
|
||||
} {1 4 3 2 3 4}
|
||||
do_test select2-4.2 {
|
||||
execsql {
|
||||
INSERT INTO bb VALUES(0);
|
||||
SELECT * FROM aa CROSS JOIN bb WHERE b;
|
||||
}
|
||||
} {1 2 1 4 3 2 3 4}
|
||||
do_test select2-4.3 {
|
||||
execsql {
|
||||
SELECT * FROM aa CROSS JOIN bb WHERE NOT b;
|
||||
}
|
||||
} {1 0 3 0}
|
||||
do_test select2-4.4 {
|
||||
execsql {
|
||||
SELECT * FROM aa, bb WHERE min(a,b);
|
||||
}
|
||||
} {1 2 1 4 3 2 3 4}
|
||||
do_test select2-4.5 {
|
||||
execsql {
|
||||
SELECT * FROM aa, bb WHERE NOT min(a,b);
|
||||
}
|
||||
} {1 0 3 0}
|
||||
do_test select2-4.6 {
|
||||
execsql {
|
||||
SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 1 END;
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test select2-4.7 {
|
||||
execsql {
|
||||
SELECT * FROM aa, bb WHERE CASE WHEN a=b-1 THEN 0 ELSE 1 END;
|
||||
}
|
||||
} {1 4 1 0 3 2 3 0}
|
||||
|
||||
finish_test
|
436
testing/sqlite3/select3.test
Normal file
436
testing/sqlite3/select3.test
Normal file
|
@ -0,0 +1,436 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing aggregate functions and the
|
||||
# GROUP BY and HAVING clauses of SELECT statements.
|
||||
#
|
||||
# $Id: select3.test,v 1.23 2008/01/16 18:20:42 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Build some test data
|
||||
#
|
||||
do_test select3-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(n int, log int);
|
||||
BEGIN;
|
||||
}
|
||||
for {set i 1} {$i<32} {incr i} {
|
||||
for {set j 0} {(1<<$j)<$i} {incr j} {}
|
||||
execsql "INSERT INTO t1 VALUES($i,$j)"
|
||||
}
|
||||
execsql {
|
||||
COMMIT
|
||||
}
|
||||
execsql {SELECT DISTINCT log FROM t1 ORDER BY log}
|
||||
} {0 1 2 3 4 5}
|
||||
|
||||
# Basic aggregate functions.
|
||||
#
|
||||
do_test select3-1.1 {
|
||||
execsql {SELECT count(*) FROM t1}
|
||||
} {31}
|
||||
do_test select3-1.2 {
|
||||
execsql {
|
||||
SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log)
|
||||
FROM t1
|
||||
}
|
||||
} {1 0 31 5 496 124 16.0 4.0}
|
||||
do_test select3-1.3 {
|
||||
execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1}
|
||||
} {1.9375 1.25}
|
||||
|
||||
# Try some basic GROUP BY clauses
|
||||
#
|
||||
do_test select3-2.1 {
|
||||
execsql {SELECT log, count(*) FROM t1 GROUP BY log ORDER BY log}
|
||||
} {0 1 1 1 2 2 3 4 4 8 5 15}
|
||||
do_test select3-2.2 {
|
||||
execsql {SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log}
|
||||
} {0 1 1 2 2 3 3 5 4 9 5 17}
|
||||
do_test select3-2.3.1 {
|
||||
execsql {SELECT log, avg(n) FROM t1 GROUP BY log ORDER BY log}
|
||||
} {0 1.0 1 2.0 2 3.5 3 6.5 4 12.5 5 24.0}
|
||||
do_test select3-2.3.2 {
|
||||
execsql {SELECT log, avg(n)+1 FROM t1 GROUP BY log ORDER BY log}
|
||||
} {0 2.0 1 3.0 2 4.5 3 7.5 4 13.5 5 25.0}
|
||||
do_test select3-2.4 {
|
||||
execsql {SELECT log, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
|
||||
} {0 0.0 1 0.0 2 0.5 3 1.5 4 3.5 5 7.0}
|
||||
do_test select3-2.5 {
|
||||
execsql {SELECT log*2+1, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
|
||||
} {1 0.0 3 0.0 5 0.5 7 1.5 9 3.5 11 7.0}
|
||||
do_test select3-2.6 {
|
||||
execsql {
|
||||
SELECT log*2+1 as x, count(*) FROM t1 GROUP BY x ORDER BY x
|
||||
}
|
||||
} {1 1 3 1 5 2 7 4 9 8 11 15}
|
||||
do_test select3-2.7 {
|
||||
execsql {
|
||||
SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY y, x
|
||||
}
|
||||
} {1 1 3 1 5 2 7 4 9 8 11 15}
|
||||
do_test select3-2.8 {
|
||||
execsql {
|
||||
SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY 10-(x+y)
|
||||
}
|
||||
} {11 15 9 8 7 4 5 2 3 1 1 1}
|
||||
#do_test select3-2.9 {
|
||||
# catchsql {
|
||||
# SELECT log, count(*) FROM t1 GROUP BY 'x' ORDER BY log;
|
||||
# }
|
||||
#} {1 {GROUP BY terms must not be non-integer constants}}
|
||||
do_test select3-2.10 {
|
||||
catchsql {
|
||||
SELECT log, count(*) FROM t1 GROUP BY 0 ORDER BY log;
|
||||
}
|
||||
} {1 {1st GROUP BY term out of range - should be between 1 and 2}}
|
||||
do_test select3-2.11 {
|
||||
catchsql {
|
||||
SELECT log, count(*) FROM t1 GROUP BY 3 ORDER BY log;
|
||||
}
|
||||
} {1 {1st GROUP BY term out of range - should be between 1 and 2}}
|
||||
do_test select3-2.12 {
|
||||
catchsql {
|
||||
SELECT log, count(*) FROM t1 GROUP BY 1 ORDER BY log;
|
||||
}
|
||||
} {0 {0 1 1 1 2 2 3 4 4 8 5 15}}
|
||||
|
||||
# Cannot have an empty GROUP BY
|
||||
do_test select3-2.13 {
|
||||
catchsql {
|
||||
SELECT log, count(*) FROM t1 GROUP BY ORDER BY log;
|
||||
}
|
||||
} {1 {near "ORDER": syntax error}}
|
||||
do_test select3-2.14 {
|
||||
catchsql {
|
||||
SELECT log, count(*) FROM t1 GROUP BY;
|
||||
}
|
||||
} {1 {near ";": syntax error}}
|
||||
|
||||
# Cannot have a HAVING without a GROUP BY
|
||||
#
|
||||
# Update: As of 3.39.0, you can.
|
||||
#
|
||||
do_execsql_test select3-3.1 {
|
||||
SELECT log, count(*) FROM t1 HAVING log>=4
|
||||
} {}
|
||||
do_execsql_test select3-3.2 {
|
||||
SELECT count(*) FROM t1 HAVING log>=4
|
||||
} {}
|
||||
do_execsql_test select3-3.3 {
|
||||
SELECT count(*) FROM t1 HAVING log!=400
|
||||
} {31}
|
||||
|
||||
# Toss in some HAVING clauses
|
||||
#
|
||||
do_test select3-4.1 {
|
||||
execsql {SELECT log, count(*) FROM t1 GROUP BY log HAVING log>=4 ORDER BY log}
|
||||
} {4 8 5 15}
|
||||
do_test select3-4.2 {
|
||||
execsql {
|
||||
SELECT log, count(*) FROM t1
|
||||
GROUP BY log
|
||||
HAVING count(*)>=4
|
||||
ORDER BY log
|
||||
}
|
||||
} {3 4 4 8 5 15}
|
||||
do_test select3-4.3 {
|
||||
execsql {
|
||||
SELECT log, count(*) FROM t1
|
||||
GROUP BY log
|
||||
HAVING count(*)>=4
|
||||
ORDER BY max(n)+0
|
||||
}
|
||||
} {3 4 4 8 5 15}
|
||||
do_test select3-4.4 {
|
||||
execsql {
|
||||
SELECT log AS x, count(*) AS y FROM t1
|
||||
GROUP BY x
|
||||
HAVING y>=4
|
||||
ORDER BY max(n)+0
|
||||
}
|
||||
} {3 4 4 8 5 15}
|
||||
do_test select3-4.5 {
|
||||
execsql {
|
||||
SELECT log AS x FROM t1
|
||||
GROUP BY x
|
||||
HAVING count(*)>=4
|
||||
ORDER BY max(n)+0
|
||||
}
|
||||
} {3 4 5}
|
||||
|
||||
do_test select3-5.1 {
|
||||
execsql {
|
||||
SELECT log, count(*), avg(n), max(n+log*2) FROM t1
|
||||
GROUP BY log
|
||||
ORDER BY max(n+log*2)+0, avg(n)+0
|
||||
}
|
||||
} {0 1 1.0 1 1 1 2.0 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24.0 41}
|
||||
do_test select3-5.2 {
|
||||
execsql {
|
||||
SELECT log, count(*), avg(n), max(n+log*2) FROM t1
|
||||
GROUP BY log
|
||||
ORDER BY max(n+log*2)+0, min(log,avg(n))+0
|
||||
}
|
||||
} {0 1 1.0 1 1 1 2.0 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24.0 41}
|
||||
|
||||
# Test sorting of GROUP BY results in the presence of an index
|
||||
# on the GROUP BY column.
|
||||
#
|
||||
do_test select3-6.1 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log;
|
||||
}
|
||||
} {0 1 1 2 2 3 3 5 4 9 5 17}
|
||||
do_test select3-6.2 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log DESC;
|
||||
}
|
||||
} {5 17 4 9 3 5 2 3 1 2 0 1}
|
||||
do_test select3-6.3 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1;
|
||||
}
|
||||
} {0 1 1 2 2 3 3 5 4 9 5 17}
|
||||
do_test select3-6.4 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1 DESC;
|
||||
}
|
||||
} {5 17 4 9 3 5 2 3 1 2 0 1}
|
||||
do_test select3-6.5 {
|
||||
execsql {
|
||||
CREATE INDEX i1 ON t1(log);
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log;
|
||||
}
|
||||
} {0 1 1 2 2 3 3 5 4 9 5 17}
|
||||
do_test select3-6.6 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log DESC;
|
||||
}
|
||||
} {5 17 4 9 3 5 2 3 1 2 0 1}
|
||||
do_test select3-6.7 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1;
|
||||
}
|
||||
} {0 1 1 2 2 3 3 5 4 9 5 17}
|
||||
do_test select3-6.8 {
|
||||
execsql {
|
||||
SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1 DESC;
|
||||
}
|
||||
} {5 17 4 9 3 5 2 3 1 2 0 1}
|
||||
|
||||
# Sometimes an aggregate query can return no rows at all.
|
||||
#
|
||||
do_test select3-7.1 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a,b);
|
||||
INSERT INTO t2 VALUES(1,2);
|
||||
SELECT a, sum(b) FROM t2 WHERE b=5 GROUP BY a;
|
||||
}
|
||||
} {}
|
||||
do_test select3-7.2 {
|
||||
execsql {
|
||||
SELECT a, sum(b) FROM t2 WHERE b=5;
|
||||
}
|
||||
} {{} {}}
|
||||
|
||||
# If a table column is of type REAL but we are storing integer values
|
||||
# in it, the values are stored as integers to take up less space. The
|
||||
# values are converted by to REAL as they are read out of the table.
|
||||
# Make sure the GROUP BY clause does this conversion correctly.
|
||||
# Ticket #2251.
|
||||
#
|
||||
do_test select3-8.1 {
|
||||
execsql {
|
||||
CREATE TABLE A (
|
||||
A1 DOUBLE,
|
||||
A2 VARCHAR COLLATE NOCASE,
|
||||
A3 DOUBLE
|
||||
);
|
||||
INSERT INTO A VALUES(39136,'ABC',1201900000);
|
||||
INSERT INTO A VALUES(39136,'ABC',1207000000);
|
||||
SELECT typeof(sum(a3)) FROM a;
|
||||
}
|
||||
} {real}
|
||||
do_test select3-8.2 {
|
||||
execsql {
|
||||
SELECT typeof(sum(a3)) FROM a GROUP BY a1;
|
||||
}
|
||||
} {real}
|
||||
|
||||
# 2019-05-09 ticket https://sqlite.org/src/tktview/6c1d3febc00b22d457c7
|
||||
#
|
||||
unset -nocomplain x
|
||||
foreach {id x} {
|
||||
100 127
|
||||
101 128
|
||||
102 -127
|
||||
103 -128
|
||||
104 -129
|
||||
110 32767
|
||||
111 32768
|
||||
112 -32767
|
||||
113 -32768
|
||||
114 -32769
|
||||
120 2147483647
|
||||
121 2147483648
|
||||
122 -2147483647
|
||||
123 -2147483648
|
||||
124 -2147483649
|
||||
130 140737488355327
|
||||
131 140737488355328
|
||||
132 -140737488355327
|
||||
133 -140737488355328
|
||||
134 -140737488355329
|
||||
140 9223372036854775807
|
||||
141 -9223372036854775807
|
||||
142 -9223372036854775808
|
||||
143 9223372036854775806
|
||||
144 9223372036854775805
|
||||
145 -9223372036854775806
|
||||
146 -9223372036854775805
|
||||
|
||||
} {
|
||||
set x [expr {$x+0}]
|
||||
do_execsql_test select3-8.$id {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c0, c1 REAL PRIMARY KEY);
|
||||
INSERT INTO t1(c0, c1) VALUES (0, $x), (0, 0);
|
||||
UPDATE t1 SET c0 = NULL;
|
||||
UPDATE OR REPLACE t1 SET c1 = 1;
|
||||
SELECT DISTINCT * FROM t1 WHERE (t1.c0 IS NULL);
|
||||
PRAGMA integrity_check;
|
||||
} {{} 1.0 ok}
|
||||
}
|
||||
|
||||
# 2020-03-10 ticket e0c2ad1aa8a9c691
|
||||
reset_db
|
||||
do_execsql_test select3-9.100 {
|
||||
CREATE TABLE t0(c0 REAL, c1 REAL GENERATED ALWAYS AS (c0));
|
||||
INSERT INTO t0(c0) VALUES (1);
|
||||
SELECT * FROM t0 GROUP BY c0;
|
||||
} {1.0 1.0}
|
||||
|
||||
reset_db
|
||||
do_execsql_test select3.10.100 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(c, d);
|
||||
SELECT max(t1.a),
|
||||
(SELECT 'xyz' FROM (SELECT * FROM t2 WHERE 0) WHERE t1.b=1)
|
||||
FROM t1;
|
||||
} {{} {}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# dbsqlfuzz crash-8e17857db2c5a9294c975123ac807156a6559f13.txt
|
||||
# Associated with the flatten-left-join branch circa 2022-06-23.
|
||||
#
|
||||
foreach {tn sql} {
|
||||
1 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
CREATE INDEX t2x ON t2(x);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
}
|
||||
2 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
}
|
||||
3 {
|
||||
CREATE TABLE t1(a TEXT);
|
||||
CREATE TABLE t2(x INT);
|
||||
INSERT INTO t1 VALUES('abc');
|
||||
PRAGMA automatic_index=OFF;
|
||||
}
|
||||
} {
|
||||
reset_db
|
||||
do_execsql_test select3-11.$tn.1 $sql
|
||||
do_execsql_test select3.11.$tn.2 {
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc {}}
|
||||
do_execsql_test select3.11.$tn.3 {
|
||||
INSERT INTO t2 VALUES(123);
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc {}}
|
||||
do_execsql_test select3.11.$tn.4 {
|
||||
INSERT INTO t2 VALUES(1234);
|
||||
SELECT max(a), val FROM t1 LEFT JOIN (
|
||||
SELECT 'constant' AS val FROM t2 WHERE x=1234
|
||||
)
|
||||
} {abc constant}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 12.0 {
|
||||
CREATE TABLE t1(a);
|
||||
CREATE TABLE t2(x);
|
||||
}
|
||||
do_execsql_test 12.1 {
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
}
|
||||
do_execsql_test 12.2 {
|
||||
INSERT INTO t1 VALUES(1), (1), (2), (3);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
0 {}
|
||||
0 {}
|
||||
0 {}
|
||||
}
|
||||
do_execsql_test 12.3 {
|
||||
INSERT INTO t2 VALUES(45);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
2 59
|
||||
1 59
|
||||
1 59
|
||||
}
|
||||
do_execsql_test 12.4 {
|
||||
INSERT INTO t2 VALUES(210);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
4 59
|
||||
2 59
|
||||
2 59
|
||||
}
|
||||
do_execsql_test 12.5 {
|
||||
INSERT INTO t2 VALUES(NULL);
|
||||
SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
4 59
|
||||
2 59
|
||||
2 59
|
||||
}
|
||||
do_execsql_test 12.6 {
|
||||
DELETE FROM t2;
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES('value');
|
||||
INSERT INTO t2 VALUES('hello');
|
||||
} {}
|
||||
do_execsql_test 12.7 {
|
||||
SELECT group_concat(x), m FROM t1
|
||||
LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
|
||||
} {
|
||||
hello 59
|
||||
}
|
||||
do_execsql_test 12.8 {
|
||||
SELECT group_concat(x), m, n FROM t1
|
||||
LEFT JOIN (SELECT x, 59 AS m, 60 AS n FROM t2) GROUP BY a;
|
||||
} {
|
||||
hello 59 60
|
||||
}
|
||||
|
||||
finish_test
|
1043
testing/sqlite3/select4.test
Normal file
1043
testing/sqlite3/select4.test
Normal file
File diff suppressed because it is too large
Load diff
262
testing/sqlite3/select5.test
Normal file
262
testing/sqlite3/select5.test
Normal file
|
@ -0,0 +1,262 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing aggregate functions and the
|
||||
# GROUP BY and HAVING clauses of SELECT statements.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Build some test data
|
||||
#
|
||||
execsql {
|
||||
CREATE TABLE t1(x int, y int);
|
||||
BEGIN;
|
||||
}
|
||||
for {set i 1} {$i<32} {incr i} {
|
||||
for {set j 0} {(1<<$j)<$i} {incr j} {}
|
||||
execsql "INSERT INTO t1 VALUES([expr {32-$i}],[expr {10-$j}])"
|
||||
}
|
||||
execsql {
|
||||
COMMIT
|
||||
}
|
||||
|
||||
do_test select5-1.0 {
|
||||
execsql {SELECT DISTINCT y FROM t1 ORDER BY y}
|
||||
} {5 6 7 8 9 10}
|
||||
|
||||
# Sort by an aggregate function.
|
||||
#
|
||||
do_test select5-1.1 {
|
||||
execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY y}
|
||||
} {5 15 6 8 7 4 8 2 9 1 10 1}
|
||||
do_test select5-1.2 {
|
||||
execsql {SELECT y, count(*) FROM t1 GROUP BY y ORDER BY count(*), y}
|
||||
} {9 1 10 1 8 2 7 4 6 8 5 15}
|
||||
do_test select5-1.3 {
|
||||
execsql {SELECT count(*), y FROM t1 GROUP BY y ORDER BY count(*), y}
|
||||
} {1 9 1 10 2 8 4 7 8 6 15 5}
|
||||
|
||||
# Some error messages associated with aggregates and GROUP BY
|
||||
#
|
||||
do_test select5-2.1.1 {
|
||||
catchsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY z ORDER BY y
|
||||
}
|
||||
} {1 {no such column: z}}
|
||||
do_test select5-2.1.2 {
|
||||
catchsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY temp.t1.y ORDER BY y
|
||||
}
|
||||
} {1 {no such column: temp.t1.y}}
|
||||
do_test select5-2.2 {
|
||||
set v [catch {execsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY z(y) ORDER BY y
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {no such function: z}}
|
||||
do_test select5-2.3 {
|
||||
set v [catch {execsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<3 ORDER BY y
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {0 {8 2 9 1 10 1}}
|
||||
do_test select5-2.4 {
|
||||
set v [catch {execsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY y HAVING z(y)<3 ORDER BY y
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {no such function: z}}
|
||||
do_test select5-2.5 {
|
||||
set v [catch {execsql {
|
||||
SELECT y, count(*) FROM t1 GROUP BY y HAVING count(*)<z ORDER BY y
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {no such column: z}}
|
||||
|
||||
# Get the Agg function to rehash in vdbe.c
|
||||
#
|
||||
do_test select5-3.1 {
|
||||
execsql {
|
||||
SELECT x, count(*), avg(y) FROM t1 GROUP BY x HAVING x<4 ORDER BY x
|
||||
}
|
||||
} {1 1 5.0 2 1 5.0 3 1 5.0}
|
||||
|
||||
# Run various aggregate functions when the count is zero.
|
||||
#
|
||||
do_test select5-4.1 {
|
||||
execsql {
|
||||
SELECT avg(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
do_test select5-4.2 {
|
||||
execsql {
|
||||
SELECT count(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {0}
|
||||
do_test select5-4.3 {
|
||||
execsql {
|
||||
SELECT min(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
do_test select5-4.4 {
|
||||
execsql {
|
||||
SELECT max(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
do_test select5-4.5 {
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
|
||||
# Some tests for queries with a GROUP BY clause but no aggregate functions.
|
||||
#
|
||||
# Note: The query in test cases 5.1 through 5.5 are not legal SQL. So if the
|
||||
# implementation changes in the future and it returns different results,
|
||||
# this is not such a big deal.
|
||||
#
|
||||
do_test select5-5.1 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a, b, c);
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
INSERT INTO t2 VALUES(1, 4, 5);
|
||||
INSERT INTO t2 VALUES(6, 4, 7);
|
||||
CREATE INDEX t2_idx ON t2(a);
|
||||
}
|
||||
} {}
|
||||
do_test select5-5.2 {
|
||||
execsql {
|
||||
SELECT a FROM t2 GROUP BY a;
|
||||
}
|
||||
} {1 6}
|
||||
do_test select5-5.3 {
|
||||
execsql {
|
||||
SELECT a FROM t2 WHERE a>2 GROUP BY a;
|
||||
}
|
||||
} {6}
|
||||
do_test select5-5.4 {
|
||||
execsql {
|
||||
SELECT a, b FROM t2 GROUP BY a, b;
|
||||
}
|
||||
} {1 2 1 4 6 4}
|
||||
do_test select5-5.5 {
|
||||
execsql {
|
||||
SELECT a, b FROM t2 GROUP BY a;
|
||||
}
|
||||
} {1 2 6 4}
|
||||
|
||||
# Test rendering of columns for the GROUP BY clause.
|
||||
#
|
||||
do_test select5-5.11 {
|
||||
execsql {
|
||||
SELECT max(c), b*a, b, a FROM t2 GROUP BY b*a, b, a
|
||||
}
|
||||
} {3 2 2 1 5 4 4 1 7 24 4 6}
|
||||
|
||||
# NULL compare equal to each other for the purposes of processing
|
||||
# the GROUP BY clause.
|
||||
#
|
||||
do_test select5-6.1 {
|
||||
execsql {
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO t3 VALUES(1,NULL);
|
||||
INSERT INTO t3 VALUES(2,NULL);
|
||||
INSERT INTO t3 VALUES(3,4);
|
||||
SELECT count(x), y FROM t3 GROUP BY y ORDER BY 1
|
||||
}
|
||||
} {1 4 2 {}}
|
||||
do_test select5-6.2 {
|
||||
execsql {
|
||||
CREATE TABLE t4(x,y,z);
|
||||
INSERT INTO t4 VALUES(1,2,NULL);
|
||||
INSERT INTO t4 VALUES(2,3,NULL);
|
||||
INSERT INTO t4 VALUES(3,NULL,5);
|
||||
INSERT INTO t4 VALUES(4,NULL,6);
|
||||
INSERT INTO t4 VALUES(4,NULL,6);
|
||||
INSERT INTO t4 VALUES(5,NULL,NULL);
|
||||
INSERT INTO t4 VALUES(5,NULL,NULL);
|
||||
INSERT INTO t4 VALUES(6,7,8);
|
||||
SELECT max(x), count(x), y, z FROM t4 GROUP BY y, z ORDER BY 1
|
||||
}
|
||||
} {1 1 2 {} 2 1 3 {} 3 1 {} 5 4 2 {} 6 5 2 {} {} 6 1 7 8}
|
||||
|
||||
do_test select5-7.2 {
|
||||
execsql {
|
||||
SELECT count(*), count(x) as cnt FROM t4 GROUP BY y ORDER BY cnt;
|
||||
}
|
||||
} {1 1 1 1 1 1 5 5}
|
||||
|
||||
# See ticket #3324.
|
||||
#
|
||||
do_test select5-8.1 {
|
||||
execsql {
|
||||
CREATE TABLE t8a(a,b);
|
||||
CREATE TABLE t8b(x);
|
||||
INSERT INTO t8a VALUES('one', 1);
|
||||
INSERT INTO t8a VALUES('one', 2);
|
||||
INSERT INTO t8a VALUES('two', 3);
|
||||
INSERT INTO t8a VALUES('one', NULL);
|
||||
INSERT INTO t8b(rowid,x) VALUES(1,111);
|
||||
INSERT INTO t8b(rowid,x) VALUES(2,222);
|
||||
INSERT INTO t8b(rowid,x) VALUES(3,333);
|
||||
SELECT a, count(b) FROM t8a, t8b WHERE b=t8b.rowid GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {one 2 two 1}
|
||||
do_test select5-8.2 {
|
||||
execsql {
|
||||
SELECT a, count(b) FROM t8a, t8b WHERE b=+t8b.rowid GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {one 2 two 1}
|
||||
do_test select5-8.3 {
|
||||
execsql {
|
||||
SELECT t8a.a, count(t8a.b) FROM t8a, t8b WHERE t8a.b=t8b.rowid
|
||||
GROUP BY 1 ORDER BY 1;
|
||||
}
|
||||
} {one 2 two 1}
|
||||
do_test select5-8.4 {
|
||||
execsql {
|
||||
SELECT a, count(*) FROM t8a, t8b WHERE b=+t8b.rowid GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {one 2 two 1}
|
||||
do_test select5-8.5 {
|
||||
execsql {
|
||||
SELECT a, count(b) FROM t8a, t8b WHERE b<x GROUP BY a ORDER BY a;
|
||||
}
|
||||
} {one 6 two 3}
|
||||
do_test select5-8.6 {
|
||||
execsql {
|
||||
SELECT a, count(t8a.b) FROM t8a, t8b WHERE b=t8b.rowid
|
||||
GROUP BY a ORDER BY 2;
|
||||
}
|
||||
} {two 1 one 2}
|
||||
do_test select5-8.7 {
|
||||
execsql {
|
||||
SELECT a, count(b) FROM t8a, t8b GROUP BY a ORDER BY 2;
|
||||
}
|
||||
} {two 3 one 6}
|
||||
do_test select5-8.8 {
|
||||
execsql {
|
||||
SELECT a, count(*) FROM t8a, t8b GROUP BY a ORDER BY 2;
|
||||
}
|
||||
} {two 3 one 9}
|
||||
|
||||
# 2021-04-26 forum https://sqlite.org/forum/forumpost/74330094d8
|
||||
reset_db
|
||||
do_execsql_test select5-9.1 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null);
|
||||
CREATE UNIQUE INDEX t1b ON t1(abs(b));
|
||||
SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b);
|
||||
} {NULL NULL | 1 NULL |}
|
||||
|
||||
finish_test
|
670
testing/sqlite3/select6.test
Normal file
670
testing/sqlite3/select6.test
Normal file
|
@ -0,0 +1,670 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing SELECT statements that contain
|
||||
# subqueries in their FROM clause.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Omit this whole file if the library is build without subquery support.
|
||||
ifcapable !subquery {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
set ::testprefix select6
|
||||
|
||||
do_test select6-1.0 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
CREATE TABLE t1(x, y);
|
||||
INSERT INTO t1 VALUES(1,1);
|
||||
INSERT INTO t1 VALUES(2,2);
|
||||
INSERT INTO t1 VALUES(3,2);
|
||||
INSERT INTO t1 VALUES(4,3);
|
||||
INSERT INTO t1 VALUES(5,3);
|
||||
INSERT INTO t1 VALUES(6,3);
|
||||
INSERT INTO t1 VALUES(7,3);
|
||||
INSERT INTO t1 VALUES(8,4);
|
||||
INSERT INTO t1 VALUES(9,4);
|
||||
INSERT INTO t1 VALUES(10,4);
|
||||
INSERT INTO t1 VALUES(11,4);
|
||||
INSERT INTO t1 VALUES(12,4);
|
||||
INSERT INTO t1 VALUES(13,4);
|
||||
INSERT INTO t1 VALUES(14,4);
|
||||
INSERT INTO t1 VALUES(15,4);
|
||||
INSERT INTO t1 VALUES(16,5);
|
||||
INSERT INTO t1 VALUES(17,5);
|
||||
INSERT INTO t1 VALUES(18,5);
|
||||
INSERT INTO t1 VALUES(19,5);
|
||||
INSERT INTO t1 VALUES(20,5);
|
||||
COMMIT;
|
||||
SELECT DISTINCT y FROM t1 ORDER BY y;
|
||||
}
|
||||
} {1 2 3 4 5}
|
||||
|
||||
do_test select6-1.1 {
|
||||
execsql2 {SELECT * FROM (SELECT x, y FROM t1 WHERE x<2)}
|
||||
} {x 1 y 1}
|
||||
do_test select6-1.2 {
|
||||
execsql {SELECT count(*) FROM (SELECT y FROM t1)}
|
||||
} {20}
|
||||
do_test select6-1.3 {
|
||||
execsql {SELECT count(*) FROM (SELECT DISTINCT y FROM t1)}
|
||||
} {5}
|
||||
do_test select6-1.4 {
|
||||
execsql {SELECT count(*) FROM (SELECT DISTINCT * FROM (SELECT y FROM t1))}
|
||||
} {5}
|
||||
do_test select6-1.5 {
|
||||
execsql {SELECT count(*) FROM (SELECT * FROM (SELECT DISTINCT y FROM t1))}
|
||||
} {5}
|
||||
|
||||
do_test select6-1.6 {
|
||||
execsql {
|
||||
SELECT *
|
||||
FROM (SELECT count(*),y FROM t1 GROUP BY y) AS a,
|
||||
(SELECT max(x),y FROM t1 GROUP BY y) as b
|
||||
WHERE a.y=b.y ORDER BY a.y
|
||||
}
|
||||
} {1 1 1 1 2 2 3 2 4 3 7 3 8 4 15 4 5 5 20 5}
|
||||
do_test select6-1.7 {
|
||||
execsql {
|
||||
SELECT a.y, a.[count(*)], [max(x)], [count(*)]
|
||||
FROM (SELECT count(*),y FROM t1 GROUP BY y) AS a,
|
||||
(SELECT max(x),y FROM t1 GROUP BY y) as b
|
||||
WHERE a.y=b.y ORDER BY a.y
|
||||
}
|
||||
} {1 1 1 1 2 2 3 2 3 4 7 4 4 8 15 8 5 5 20 5}
|
||||
do_test select6-1.8 {
|
||||
execsql {
|
||||
SELECT q, p, r
|
||||
FROM (SELECT count(*) as p , y as q FROM t1 GROUP BY y) AS a,
|
||||
(SELECT max(x) as r, y as s FROM t1 GROUP BY y) as b
|
||||
WHERE q=s ORDER BY s
|
||||
}
|
||||
} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20}
|
||||
do_test select6-1.9 {
|
||||
execsql {
|
||||
SELECT q, p, r, b.[min(x)+y]
|
||||
FROM (SELECT count(*) as p , y as q FROM t1 GROUP BY y) AS a,
|
||||
(SELECT max(x) as r, y as s, min(x)+y FROM t1 GROUP BY y) as b
|
||||
WHERE q=s ORDER BY s
|
||||
}
|
||||
} {1 1 1 2 2 2 3 4 3 4 7 7 4 8 15 12 5 5 20 21}
|
||||
|
||||
do_test select6-2.0 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
SELECT DISTINCT b FROM t2 ORDER BY b;
|
||||
}
|
||||
} {1 2 3 4 5}
|
||||
do_test select6-2.1 {
|
||||
execsql2 {SELECT * FROM (SELECT a, b FROM t2 WHERE a<2)}
|
||||
} {a 1 b 1}
|
||||
do_test select6-2.2 {
|
||||
execsql {SELECT count(*) FROM (SELECT b FROM t2)}
|
||||
} {20}
|
||||
do_test select6-2.3 {
|
||||
execsql {SELECT count(*) FROM (SELECT DISTINCT b FROM t2)}
|
||||
} {5}
|
||||
do_test select6-2.4 {
|
||||
execsql {SELECT count(*) FROM (SELECT DISTINCT * FROM (SELECT b FROM t2))}
|
||||
} {5}
|
||||
do_test select6-2.5 {
|
||||
execsql {SELECT count(*) FROM (SELECT * FROM (SELECT DISTINCT b FROM t2))}
|
||||
} {5}
|
||||
|
||||
do_test select6-2.6 {
|
||||
execsql {
|
||||
SELECT *
|
||||
FROM (SELECT count(*),b FROM t2 GROUP BY b) AS a,
|
||||
(SELECT max(a),b FROM t2 GROUP BY b) as b
|
||||
WHERE a.b=b.b ORDER BY a.b
|
||||
}
|
||||
} {1 1 1 1 2 2 3 2 4 3 7 3 8 4 15 4 5 5 20 5}
|
||||
do_test select6-2.7 {
|
||||
execsql {
|
||||
SELECT a.b, a.[count(*)], [max(a)], [count(*)]
|
||||
FROM (SELECT count(*),b FROM t2 GROUP BY b) AS a,
|
||||
(SELECT max(a),b FROM t2 GROUP BY b) as b
|
||||
WHERE a.b=b.b ORDER BY a.b
|
||||
}
|
||||
} {1 1 1 1 2 2 3 2 3 4 7 4 4 8 15 8 5 5 20 5}
|
||||
do_test select6-2.8 {
|
||||
execsql {
|
||||
SELECT q, p, r
|
||||
FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY b) AS a,
|
||||
(SELECT max(a) as r, b as s FROM t2 GROUP BY b) as b
|
||||
WHERE q=s ORDER BY s
|
||||
}
|
||||
} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20}
|
||||
do_test select6-2.9 {
|
||||
execsql {
|
||||
SELECT a.q, a.p, b.r
|
||||
FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY q) AS a,
|
||||
(SELECT max(a) as r, b as s FROM t2 GROUP BY s) as b
|
||||
WHERE a.q=b.s ORDER BY a.q
|
||||
}
|
||||
} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20}
|
||||
|
||||
do_test select6-3.1 {
|
||||
execsql2 {
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM t1 WHERE x=3));
|
||||
}
|
||||
} {x 3 y 2}
|
||||
do_test select6-3.2 {
|
||||
execsql {
|
||||
SELECT * FROM
|
||||
(SELECT a.q, a.p, b.r
|
||||
FROM (SELECT count(*) as p , b as q FROM t2 GROUP BY q) AS a,
|
||||
(SELECT max(a) as r, b as s FROM t2 GROUP BY s) as b
|
||||
WHERE a.q=b.s ORDER BY a.q)
|
||||
}
|
||||
} {1 1 1 2 2 3 3 4 7 4 8 15 5 5 20}
|
||||
do_test select6-3.3 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
|
||||
}
|
||||
} {10.5 3.7 14.2}
|
||||
do_test select6-3.4 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
|
||||
}
|
||||
} {11.5 4.0 15.5}
|
||||
do_test select6-3.5 {
|
||||
execsql {
|
||||
SELECT x,y,x+y FROM (SELECT avg(a) as 'x', avg(b) as 'y' FROM t2 WHERE a=4)
|
||||
}
|
||||
} {4.0 3.0 7.0}
|
||||
do_test select6-3.6 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
|
||||
WHERE a>10
|
||||
}
|
||||
} {10.5 3.7 14.2}
|
||||
do_test select6-3.7 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1)
|
||||
WHERE a<10
|
||||
}
|
||||
} {}
|
||||
do_test select6-3.8 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
|
||||
WHERE a>10
|
||||
}
|
||||
} {11.5 4.0 15.5}
|
||||
do_test select6-3.9 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', avg(y) as 'b' FROM t1 WHERE y=4)
|
||||
WHERE a<10
|
||||
}
|
||||
} {}
|
||||
do_test select6-3.10 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM (SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b)
|
||||
ORDER BY a
|
||||
}
|
||||
} {1.0 1 2.0 2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23.0}
|
||||
do_test select6-3.11 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM
|
||||
(SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b)
|
||||
WHERE b<4 ORDER BY a
|
||||
}
|
||||
} {1.0 1 2.0 2.5 2 4.5 5.5 3 8.5}
|
||||
do_test select6-3.12 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM
|
||||
(SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1)
|
||||
WHERE b<4 ORDER BY a
|
||||
}
|
||||
} {2.5 2 4.5 5.5 3 8.5}
|
||||
do_test select6-3.13 {
|
||||
execsql {
|
||||
SELECT a,b,a+b FROM
|
||||
(SELECT avg(x) as 'a', y as 'b' FROM t1 GROUP BY b HAVING a>1)
|
||||
ORDER BY a
|
||||
}
|
||||
} {2.5 2 4.5 5.5 3 8.5 11.5 4 15.5 18.0 5 23.0}
|
||||
do_test select6-3.14 {
|
||||
execsql {
|
||||
SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y)
|
||||
ORDER BY [count(*)]
|
||||
}
|
||||
} {1 1 2 2 4 3 5 5 8 4}
|
||||
do_test select6-3.15 {
|
||||
execsql {
|
||||
SELECT [count(*)],y FROM (SELECT count(*), y FROM t1 GROUP BY y)
|
||||
ORDER BY y
|
||||
}
|
||||
} {1 1 2 2 4 3 8 4 5 5}
|
||||
|
||||
do_test select6-4.1 {
|
||||
execsql {
|
||||
SELECT a,b,c FROM
|
||||
(SELECT x AS 'a', y AS 'b', x+y AS 'c' FROM t1 WHERE y=4)
|
||||
WHERE a<10 ORDER BY a;
|
||||
}
|
||||
} {8 4 12 9 4 13}
|
||||
do_test select6-4.2 {
|
||||
execsql {
|
||||
SELECT y FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test select6-4.3 {
|
||||
execsql {
|
||||
SELECT DISTINCT y FROM (SELECT y FROM t1) WHERE y<5 ORDER BY y
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test select6-4.4 {
|
||||
execsql {
|
||||
SELECT avg(y) FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y
|
||||
}
|
||||
} {2.5}
|
||||
do_test select6-4.5 {
|
||||
execsql {
|
||||
SELECT avg(y) FROM (SELECT DISTINCT y FROM t1 WHERE y<5) ORDER BY y
|
||||
}
|
||||
} {2.5}
|
||||
|
||||
do_test select6-5.1 {
|
||||
execsql {
|
||||
SELECT a,x,b FROM
|
||||
(SELECT x+3 AS 'a', x FROM t1 WHERE y=3) AS 'p',
|
||||
(SELECT x AS 'b' FROM t1 WHERE y=4) AS 'q'
|
||||
WHERE a=b
|
||||
ORDER BY a
|
||||
}
|
||||
} {8 5 8 9 6 9 10 7 10}
|
||||
do_test select6-5.2 {
|
||||
execsql {
|
||||
SELECT a,x,b FROM
|
||||
(SELECT x+3 AS 'a', x FROM t1 WHERE y=3),
|
||||
(SELECT x AS 'b' FROM t1 WHERE y=4)
|
||||
WHERE a=b
|
||||
ORDER BY a
|
||||
}
|
||||
} {8 5 8 9 6 9 10 7 10}
|
||||
|
||||
# Tests of compound sub-selects
|
||||
#
|
||||
do_test select6-6.1 {
|
||||
execsql {
|
||||
DELETE FROM t1 WHERE x>4;
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 1 2 2 3 2 4 3}
|
||||
ifcapable compound {
|
||||
do_test select6-6.2 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT x AS 'a' FROM t1 UNION ALL SELECT x+10 AS 'a' FROM t1
|
||||
) ORDER BY a;
|
||||
}
|
||||
} {1 2 3 4 11 12 13 14}
|
||||
do_test select6-6.3 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT x AS 'a' FROM t1 UNION ALL SELECT x+1 AS 'a' FROM t1
|
||||
) ORDER BY a;
|
||||
}
|
||||
} {1 2 2 3 3 4 4 5}
|
||||
do_test select6-6.4 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT x AS 'a' FROM t1 UNION SELECT x+1 AS 'a' FROM t1
|
||||
) ORDER BY a;
|
||||
}
|
||||
} {1 2 3 4 5}
|
||||
do_test select6-6.5 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT x AS 'a' FROM t1 INTERSECT SELECT x+1 AS 'a' FROM t1
|
||||
) ORDER BY a;
|
||||
}
|
||||
} {2 3 4}
|
||||
do_test select6-6.6 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT x AS 'a' FROM t1 EXCEPT SELECT x*2 AS 'a' FROM t1
|
||||
) ORDER BY a;
|
||||
}
|
||||
} {1 3}
|
||||
} ;# ifcapable compound
|
||||
|
||||
# Subselects with no FROM clause
|
||||
#
|
||||
do_test select6-7.1 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT 1)
|
||||
}
|
||||
} {1}
|
||||
do_test select6-7.2 {
|
||||
execsql {
|
||||
SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c')
|
||||
}
|
||||
} {abc 2 1 1 2 abc}
|
||||
do_test select6-7.3 {
|
||||
execsql {
|
||||
SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c' WHERE 0)
|
||||
}
|
||||
} {}
|
||||
do_test select6-7.4 {
|
||||
execsql2 {
|
||||
SELECT c,b,a,* FROM (SELECT 1 AS 'a', 2 AS 'b', 'abc' AS 'c' WHERE 1)
|
||||
}
|
||||
} {c abc b 2 a 1 a 1 b 2 c abc}
|
||||
|
||||
# The remaining tests in this file depend on the EXPLAIN keyword.
|
||||
# Skip these tests if EXPLAIN is disabled in the current build.
|
||||
#
|
||||
ifcapable {!explain} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# The following procedure compiles the SQL given as an argument and returns
|
||||
# TRUE if that SQL uses any transient tables and returns FALSE if no
|
||||
# transient tables are used. This is used to make sure that the
|
||||
# sqliteFlattenSubquery() routine in select.c is doing its job.
|
||||
#
|
||||
proc is_flat {sql} {
|
||||
return [expr 0>[lsearch [execsql "EXPLAIN $sql"] OpenEphemeral]]
|
||||
}
|
||||
|
||||
# Check that the flattener works correctly for deeply nested subqueries
|
||||
# involving joins.
|
||||
#
|
||||
do_test select6-8.1 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
CREATE TABLE t3(p,q);
|
||||
INSERT INTO t3 VALUES(1,11);
|
||||
INSERT INTO t3 VALUES(2,22);
|
||||
CREATE TABLE t4(q,r);
|
||||
INSERT INTO t4 VALUES(11,111);
|
||||
INSERT INTO t4 VALUES(22,222);
|
||||
COMMIT;
|
||||
SELECT * FROM t3 NATURAL JOIN t4;
|
||||
}
|
||||
} {1 11 111 2 22 222}
|
||||
do_test select6-8.2 {
|
||||
execsql {
|
||||
SELECT y, p, q, r FROM
|
||||
(SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m,
|
||||
(SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n
|
||||
WHERE y=p
|
||||
}
|
||||
} {1 1 11 111 2 2 22 222 2 2 22 222}
|
||||
# If view support is omitted from the build, then so is the query
|
||||
# "flattener". So omit this test and test select6-8.6 in that case.
|
||||
ifcapable view {
|
||||
do_test select6-8.3 {
|
||||
is_flat {
|
||||
SELECT y, p, q, r FROM
|
||||
(SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m,
|
||||
(SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n
|
||||
WHERE y=p
|
||||
}
|
||||
} {1}
|
||||
} ;# ifcapable view
|
||||
do_test select6-8.4 {
|
||||
execsql {
|
||||
SELECT DISTINCT y, p, q, r FROM
|
||||
(SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m,
|
||||
(SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n
|
||||
WHERE y=p
|
||||
}
|
||||
} {1 1 11 111 2 2 22 222}
|
||||
do_test select6-8.5 {
|
||||
execsql {
|
||||
SELECT * FROM
|
||||
(SELECT y, p, q, r FROM
|
||||
(SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m,
|
||||
(SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n
|
||||
WHERE y=p) AS e,
|
||||
(SELECT r AS z FROM t4 WHERE q=11) AS f
|
||||
WHERE e.r=f.z
|
||||
}
|
||||
} {1 1 11 111 111}
|
||||
ifcapable view {
|
||||
do_test select6-8.6 {
|
||||
is_flat {
|
||||
SELECT * FROM
|
||||
(SELECT y, p, q, r FROM
|
||||
(SELECT t1.y AS y, t2.b AS b FROM t1, t2 WHERE t1.x=t2.a) AS m,
|
||||
(SELECT t3.p AS p, t3.q AS q, t4.r AS r FROM t3 NATURAL JOIN t4) as n
|
||||
WHERE y=p) AS e,
|
||||
(SELECT r AS z FROM t4 WHERE q=11) AS f
|
||||
WHERE e.r=f.z
|
||||
}
|
||||
} {1}
|
||||
} ;# ifcapable view
|
||||
|
||||
# Ticket #1634
|
||||
#
|
||||
do_test select6-9.1 {
|
||||
execsql {
|
||||
SELECT a.x, b.x FROM t1 AS a, (SELECT x FROM t1 LIMIT 2) AS b
|
||||
ORDER BY 1, 2
|
||||
}
|
||||
} {1 1 1 2 2 1 2 2 3 1 3 2 4 1 4 2}
|
||||
do_test select6-9.2 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT 2);
|
||||
}
|
||||
} {1 2}
|
||||
do_test select6-9.3 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT 2 OFFSET 1);
|
||||
}
|
||||
} {2 3}
|
||||
do_test select6-9.4 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1) LIMIT 2;
|
||||
}
|
||||
} {1 2}
|
||||
do_test select6-9.5 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1) LIMIT 2 OFFSET 1;
|
||||
}
|
||||
} {2 3}
|
||||
do_test select6-9.6 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT 2) LIMIT 3;
|
||||
}
|
||||
} {1 2}
|
||||
do_test select6-9.7 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT -1) LIMIT 3;
|
||||
}
|
||||
} {1 2 3}
|
||||
do_test select6-9.8 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT -1);
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test select6-9.9 {
|
||||
execsql {
|
||||
SELECT x FROM (SELECT x FROM t1 LIMIT -1 OFFSET 1);
|
||||
}
|
||||
} {2 3 4}
|
||||
do_test select6-9.10 {
|
||||
execsql {
|
||||
SELECT x, y FROM (SELECT x, (SELECT 10+x) y FROM t1 LIMIT -1 OFFSET 1);
|
||||
}
|
||||
} {2 12 3 13 4 14}
|
||||
do_test select6-9.11 {
|
||||
execsql {
|
||||
SELECT x, y FROM (SELECT x, (SELECT 10)+x y FROM t1 LIMIT -1 OFFSET 1);
|
||||
}
|
||||
} {2 12 3 13 4 14}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that if a UNION ALL sub-query that would otherwise be eligible for
|
||||
# flattening consists of two or more SELECT statements that do not all
|
||||
# return the same number of result columns, the error is detected.
|
||||
#
|
||||
do_execsql_test 10.1 {
|
||||
CREATE TABLE t(i,j,k);
|
||||
CREATE TABLE j(l,m);
|
||||
CREATE TABLE k(o);
|
||||
}
|
||||
|
||||
set err [list 1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}]
|
||||
|
||||
do_execsql_test 10.2 {
|
||||
SELECT * FROM (SELECT * FROM t), j;
|
||||
}
|
||||
do_catchsql_test 10.3 {
|
||||
SELECT * FROM t UNION ALL SELECT * FROM j
|
||||
} $err
|
||||
do_catchsql_test 10.4 {
|
||||
SELECT * FROM (SELECT i FROM t UNION ALL SELECT l, m FROM j)
|
||||
} $err
|
||||
do_catchsql_test 10.5 {
|
||||
SELECT * FROM (SELECT j FROM t UNION ALL SELECT * FROM j)
|
||||
} $err
|
||||
do_catchsql_test 10.6 {
|
||||
SELECT * FROM (SELECT * FROM t UNION ALL SELECT * FROM j)
|
||||
} $err
|
||||
do_catchsql_test 10.7 {
|
||||
SELECT * FROM (
|
||||
SELECT * FROM t UNION ALL
|
||||
SELECT l,m,l FROM j UNION ALL
|
||||
SELECT * FROM k
|
||||
)
|
||||
} $err
|
||||
do_catchsql_test 10.8 {
|
||||
SELECT * FROM (
|
||||
SELECT * FROM k UNION ALL
|
||||
SELECT * FROM t UNION ALL
|
||||
SELECT l,m,l FROM j
|
||||
)
|
||||
} $err
|
||||
|
||||
# 2015-02-09 Ticket [2f7170d73bf9abf80339187aa3677dce3dbcd5ca]
|
||||
# "misuse of aggregate" error if aggregate column from FROM
|
||||
# subquery is used in correlated subquery
|
||||
#
|
||||
do_execsql_test 11.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(w INT, x INT);
|
||||
INSERT INTO t1(w,x)
|
||||
VALUES(1,10),(2,20),(3,30),
|
||||
(2,21),(3,31),
|
||||
(3,32);
|
||||
CREATE INDEX t1wx ON t1(w,x);
|
||||
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t2(w INT, y VARCHAR(8));
|
||||
INSERT INTO t2(w,y) VALUES(1,'one'),(2,'two'),(3,'three'),(4,'four');
|
||||
CREATE INDEX t2wy ON t2(w,y);
|
||||
|
||||
SELECT cnt, xyz, (SELECT y FROM t2 WHERE w=cnt), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT cnt, xyz, lower((SELECT y FROM t2 WHERE w=cnt)), '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 one | 2 2 two | 3 3 three |}
|
||||
do_execsql_test 11.3 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
WHERE (SELECT y FROM t2 WHERE w=cnt)!='two'
|
||||
ORDER BY cnt, xyz;
|
||||
} {1 1 | 3 3 |}
|
||||
do_execsql_test 11.4 {
|
||||
SELECT cnt, xyz, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY lower((SELECT y FROM t2 WHERE w=cnt));
|
||||
} {1 1 | 3 3 | 2 2 |}
|
||||
do_execsql_test 11.5 {
|
||||
SELECT cnt, xyz,
|
||||
CASE WHEN (SELECT y FROM t2 WHERE w=cnt)=='two'
|
||||
THEN 'aaa' ELSE 'bbb'
|
||||
END, '|'
|
||||
FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
|
||||
ORDER BY +cnt;
|
||||
} {1 1 bbb | 2 2 aaa | 3 3 bbb |}
|
||||
|
||||
do_execsql_test 11.100 {
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE t2(y, z);
|
||||
SELECT ( SELECT y FROM t2 WHERE z = cnt )
|
||||
FROM ( SELECT count(*) AS cnt FROM t1 );
|
||||
} {{}}
|
||||
|
||||
# 2019-05-29 ticket https://sqlite.org/src/info/c41afac34f15781f
|
||||
# A LIMIT clause in a subquery is incorrectly applied to a subquery.
|
||||
#
|
||||
do_execsql_test 12.100 {
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(1);
|
||||
INSERT INTO t1 VALUES(2);
|
||||
CREATE TABLE t2(b);
|
||||
INSERT INTO t2 VALUES(3);
|
||||
SELECT * FROM (
|
||||
SELECT * FROM (SELECT * FROM t1 LIMIT 1)
|
||||
UNION ALL
|
||||
SELECT * from t2);
|
||||
} {1 3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 13.100 {
|
||||
|
||||
CREATE TABLE t1(y INT);
|
||||
INSERT INTO t1 (y) VALUES (1);
|
||||
|
||||
CREATE TABLE t2(x INTEGER);
|
||||
INSERT INTO t2 VALUES(0);
|
||||
|
||||
CREATE TABLE empty1(z);
|
||||
}
|
||||
|
||||
do_execsql_test 13.110 {
|
||||
SELECT t1.y
|
||||
FROM ( SELECT 'AAA' )
|
||||
INNER JOIN (
|
||||
SELECT 1 AS abc FROM (
|
||||
SELECT 1 FROM t2 LEFT JOIN empty1
|
||||
)
|
||||
) AS sub0 ON sub0.abc
|
||||
, t1
|
||||
RIGHT JOIN (SELECT 'BBB' FROM ( SELECT 'CCC' ))
|
||||
} {1}
|
||||
|
||||
do_execsql_test 13.120 {
|
||||
SELECT t1.y
|
||||
FROM ( SELECT 'AAA' )
|
||||
INNER JOIN (
|
||||
SELECT 1 AS abc FROM (
|
||||
SELECT 1 FROM t2 LEFT JOIN empty1
|
||||
)
|
||||
) AS sub0 ON sub0.abc
|
||||
, t1
|
||||
RIGHT JOIN (SELECT 'BBB' FROM ( SELECT 'CCC' ))
|
||||
WHERE t1.y
|
||||
} {1}
|
||||
|
||||
|
||||
finish_test
|
250
testing/sqlite3/select7.test
Normal file
250
testing/sqlite3/select7.test
Normal file
|
@ -0,0 +1,250 @@
|
|||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing compute SELECT statements and nested
|
||||
# views.
|
||||
#
|
||||
# $Id: select7.test,v 1.11 2007/09/12 17:01:45 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix select7
|
||||
|
||||
ifcapable compound {
|
||||
|
||||
# A 3-way INTERSECT. Ticket #875
|
||||
ifcapable tempdb {
|
||||
do_test select7-1.1 {
|
||||
execsql {
|
||||
create temp table t1(x);
|
||||
insert into t1 values('amx');
|
||||
insert into t1 values('anx');
|
||||
insert into t1 values('amy');
|
||||
insert into t1 values('bmy');
|
||||
select * from t1 where x like 'a__'
|
||||
intersect select * from t1 where x like '_m_'
|
||||
intersect select * from t1 where x like '__x';
|
||||
}
|
||||
} {amx}
|
||||
}
|
||||
|
||||
|
||||
# Nested views do not handle * properly. Ticket #826.
|
||||
#
|
||||
ifcapable view {
|
||||
do_test select7-2.1 {
|
||||
execsql {
|
||||
CREATE TABLE x(id integer primary key, a TEXT NULL);
|
||||
INSERT INTO x (a) VALUES ('first');
|
||||
CREATE TABLE tempx(id integer primary key, a TEXT NULL);
|
||||
INSERT INTO tempx (a) VALUES ('t-first');
|
||||
CREATE VIEW tv1 AS SELECT x.id, tx.id FROM x JOIN tempx tx ON tx.id=x.id;
|
||||
CREATE VIEW tv1b AS SELECT x.id, tx.id FROM x JOIN tempx tx on tx.id=x.id;
|
||||
CREATE VIEW tv2 AS SELECT * FROM tv1 UNION SELECT * FROM tv1b;
|
||||
SELECT * FROM tv2;
|
||||
}
|
||||
} {1 1}
|
||||
} ;# ifcapable view
|
||||
|
||||
} ;# ifcapable compound
|
||||
|
||||
# Do not allow GROUP BY without an aggregate. Ticket #1039.
|
||||
#
|
||||
# Change: force any query with a GROUP BY clause to be processed as
|
||||
# an aggregate query, whether it contains aggregates or not.
|
||||
#
|
||||
ifcapable subquery {
|
||||
# do_test select7-3.1 {
|
||||
# catchsql {
|
||||
# SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name
|
||||
# }
|
||||
# } {1 {GROUP BY may only be used on aggregate queries}}
|
||||
do_test select7-3.1 {
|
||||
catchsql {
|
||||
SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name
|
||||
}
|
||||
} [list 0 [execsql {SELECT * FROM sqlite_master ORDER BY name}]]
|
||||
}
|
||||
|
||||
# Ticket #2018 - Make sure names are resolved correctly on all
|
||||
# SELECT statements of a compound subquery.
|
||||
#
|
||||
ifcapable {subquery && compound} {
|
||||
do_test select7-4.1 {
|
||||
execsql {
|
||||
CREATE TABLE IF NOT EXISTS photo(pk integer primary key, x);
|
||||
CREATE TABLE IF NOT EXISTS tag(pk integer primary key, fk int, name);
|
||||
|
||||
SELECT P.pk from PHOTO P WHERE NOT EXISTS (
|
||||
SELECT T2.pk from TAG T2 WHERE T2.fk = P.pk
|
||||
EXCEPT
|
||||
SELECT T3.pk from TAG T3 WHERE T3.fk = P.pk AND T3.name LIKE '%foo%'
|
||||
);
|
||||
}
|
||||
} {}
|
||||
do_test select7-4.2 {
|
||||
execsql {
|
||||
INSERT INTO photo VALUES(1,1);
|
||||
INSERT INTO photo VALUES(2,2);
|
||||
INSERT INTO photo VALUES(3,3);
|
||||
INSERT INTO tag VALUES(11,1,'one');
|
||||
INSERT INTO tag VALUES(12,1,'two');
|
||||
INSERT INTO tag VALUES(21,1,'one-b');
|
||||
SELECT P.pk from PHOTO P WHERE NOT EXISTS (
|
||||
SELECT T2.pk from TAG T2 WHERE T2.fk = P.pk
|
||||
EXCEPT
|
||||
SELECT T3.pk from TAG T3 WHERE T3.fk = P.pk AND T3.name LIKE '%foo%'
|
||||
);
|
||||
}
|
||||
} {2 3}
|
||||
}
|
||||
|
||||
# ticket #2347
|
||||
#
|
||||
ifcapable {subquery && compound} {
|
||||
do_test select7-5.1 {
|
||||
catchsql {
|
||||
CREATE TABLE t2(a,b);
|
||||
SELECT 5 IN (SELECT a,b FROM t2);
|
||||
}
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
do_test select7-5.2 {
|
||||
catchsql {
|
||||
SELECT 5 IN (SELECT * FROM t2);
|
||||
}
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
do_test select7-5.3 {
|
||||
catchsql {
|
||||
SELECT 5 IN (SELECT a,b FROM t2 UNION SELECT b,a FROM t2);
|
||||
}
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
do_test select7-5.4 {
|
||||
catchsql {
|
||||
SELECT 5 IN (SELECT * FROM t2 UNION SELECT * FROM t2);
|
||||
}
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
}
|
||||
|
||||
# Verify that an error occurs if you have too many terms on a
|
||||
# compound select statement.
|
||||
#
|
||||
if {[clang_sanitize_address]==0} {
|
||||
ifcapable compound {
|
||||
if {$SQLITE_MAX_COMPOUND_SELECT>0} {
|
||||
set sql {SELECT 0}
|
||||
set result 0
|
||||
for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} {
|
||||
append sql " UNION ALL SELECT $i"
|
||||
lappend result $i
|
||||
}
|
||||
do_test select7-6.1 {
|
||||
catchsql $sql
|
||||
} [list 0 $result]
|
||||
append sql { UNION ALL SELECT 99999999}
|
||||
do_test select7-6.2 {
|
||||
catchsql $sql
|
||||
} {1 {too many terms in compound SELECT}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# https://issues.chromium.org/issues/358174302
|
||||
# Need to support an unlimited number of terms in a VALUES clause, even
|
||||
# if some of those terms contain double-quoted string literals.
|
||||
#
|
||||
do_execsql_test select7-6.5 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
}
|
||||
sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 10
|
||||
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 0
|
||||
do_catchsql_test select7-6.6 {
|
||||
INSERT INTO t1 VALUES
|
||||
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
|
||||
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
|
||||
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
|
||||
(0,NULL,0), (X'',X'',0.0);
|
||||
} {1 {no such column: "" - should this be a string literal in single-quotes?}}
|
||||
do_execsql_test select7-6.7 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {0}
|
||||
sqlite3_db_config db SQLITE_DBCONFIG_DQS_DML 1
|
||||
do_catchsql_test select7-6.8 {
|
||||
INSERT INTO t1 VALUES
|
||||
(NULL,0,""), (X'',0.0,0.0), (X'',X'',""), (0.0,0.0,""), (NULL,NULL,0.0),
|
||||
(0,"",0), (0.0,X'',0), ("",X'',0.0), (0.0,X'',NULL), (0,NULL,""),
|
||||
(0,"",NULL), (0.0,NULL,X''), ("",X'',NULL), (NULL,0,""),
|
||||
(0,NULL,0), (X'',X'',0.0);
|
||||
} {0 {}}
|
||||
do_execsql_test select7-6.9 {
|
||||
SELECT count(*) FROM t1;
|
||||
} {16}
|
||||
|
||||
# This block of tests verifies that bug aa92c76cd4 is fixed.
|
||||
#
|
||||
do_test select7-7.1 {
|
||||
execsql {
|
||||
CREATE TABLE t3(a REAL);
|
||||
INSERT INTO t3 VALUES(44.0);
|
||||
INSERT INTO t3 VALUES(56.0);
|
||||
}
|
||||
} {}
|
||||
do_test select7-7.2 {
|
||||
execsql {
|
||||
pragma vdbe_trace = 0;
|
||||
SELECT (CASE WHEN a=0 THEN 0 ELSE (a + 25) / 50 END) AS categ, count(*)
|
||||
FROM t3 GROUP BY categ
|
||||
}
|
||||
} {1.38 1 1.62 1}
|
||||
do_test select7-7.3 {
|
||||
execsql {
|
||||
CREATE TABLE t4(a REAL);
|
||||
INSERT INTO t4 VALUES( 2.0 );
|
||||
INSERT INTO t4 VALUES( 3.0 );
|
||||
}
|
||||
} {}
|
||||
do_test select7-7.4 {
|
||||
execsql {
|
||||
SELECT (CASE WHEN a=0 THEN 'zero' ELSE a/2 END) AS t FROM t4 GROUP BY t;
|
||||
}
|
||||
} {1.0 1.5}
|
||||
do_test select7-7.5 {
|
||||
execsql { SELECT a=0, typeof(a) FROM t4 }
|
||||
} {0 real 0 real}
|
||||
do_test select7-7.6 {
|
||||
execsql { SELECT a=0, typeof(a) FROM t4 GROUP BY a }
|
||||
} {0 real 0 real}
|
||||
|
||||
do_test select7-7.7 {
|
||||
execsql {
|
||||
CREATE TABLE t5(a TEXT, b INT);
|
||||
INSERT INTO t5 VALUES(123, 456);
|
||||
SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
|
||||
}
|
||||
} {text 123}
|
||||
|
||||
do_execsql_test 8.0 {
|
||||
CREATE TABLE t01(x, y);
|
||||
CREATE TABLE t02(x, y);
|
||||
}
|
||||
|
||||
do_catchsql_test 8.1 {
|
||||
SELECT * FROM (
|
||||
SELECT * FROM t01 UNION SELECT x FROM t02
|
||||
) WHERE y=1
|
||||
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
|
||||
|
||||
do_catchsql_test 8.2 {
|
||||
CREATE VIEW v0 as SELECT x, y FROM t01 UNION SELECT x FROM t02;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM v0 WHERE x='0' OR y;
|
||||
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
|
||||
|
||||
|
||||
finish_test
|
61
testing/sqlite3/select8.test
Normal file
61
testing/sqlite3/select8.test
Normal file
|
@ -0,0 +1,61 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# The focus of this file is testing that LIMIT and OFFSET work for
|
||||
# unusual combinations SELECT statements.
|
||||
#
|
||||
# $Id: select8.test,v 1.1 2008/01/12 12:48:09 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
execsql {
|
||||
CREATE TABLE songs(songid, artist, timesplayed);
|
||||
INSERT INTO songs VALUES(1,'one',1);
|
||||
INSERT INTO songs VALUES(2,'one',2);
|
||||
INSERT INTO songs VALUES(3,'two',3);
|
||||
INSERT INTO songs VALUES(4,'three',5);
|
||||
INSERT INTO songs VALUES(5,'one',7);
|
||||
INSERT INTO songs VALUES(6,'two',11);
|
||||
}
|
||||
set result [execsql {
|
||||
SELECT DISTINCT artist,sum(timesplayed) AS total
|
||||
FROM songs
|
||||
GROUP BY LOWER(artist)
|
||||
}]
|
||||
do_test select8-1.1 {
|
||||
execsql {
|
||||
SELECT DISTINCT artist,sum(timesplayed) AS total
|
||||
FROM songs
|
||||
GROUP BY LOWER(artist)
|
||||
LIMIT 1 OFFSET 1
|
||||
}
|
||||
} [lrange $result 2 3]
|
||||
do_test select8-1.2 {
|
||||
execsql {
|
||||
SELECT DISTINCT artist,sum(timesplayed) AS total
|
||||
FROM songs
|
||||
GROUP BY LOWER(artist)
|
||||
LIMIT 2 OFFSET 1
|
||||
}
|
||||
} [lrange $result 2 5]
|
||||
do_test select8-1.3 {
|
||||
execsql {
|
||||
SELECT DISTINCT artist,sum(timesplayed) AS total
|
||||
FROM songs
|
||||
GROUP BY LOWER(artist)
|
||||
LIMIT -1 OFFSET 2
|
||||
}
|
||||
} [lrange $result 4 end]
|
||||
|
||||
|
||||
finish_test
|
472
testing/sqlite3/select9.test
Normal file
472
testing/sqlite3/select9.test
Normal file
|
@ -0,0 +1,472 @@
|
|||
# 2008 June 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# $Id: select9.test,v 1.4 2008/07/01 14:39:35 danielk1977 Exp $
|
||||
|
||||
# The tests in this file are focused on test compound SELECT statements
|
||||
# that have any or all of an ORDER BY, LIMIT or OFFSET clauses. As of
|
||||
# version 3.6.0, SQLite contains code to use SQL indexes where possible
|
||||
# to optimize such statements.
|
||||
#
|
||||
|
||||
# TODO Points:
|
||||
#
|
||||
# * Are there any "column affinity" issues to consider?
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# test_compound_select TESTNAME SELECT RESULT
|
||||
#
|
||||
# This command is used to run multiple LIMIT/OFFSET test cases based on
|
||||
# the single SELECT statement passed as the second argument. The SELECT
|
||||
# statement may not contain a LIMIT or OFFSET clause. This proc tests
|
||||
# many statements of the form:
|
||||
#
|
||||
# "$SELECT limit $X offset $Y"
|
||||
#
|
||||
# for various values of $X and $Y.
|
||||
#
|
||||
# The third argument, $RESULT, should contain the expected result of
|
||||
# the command [execsql $SELECT].
|
||||
#
|
||||
# The first argument, $TESTNAME, is used as the base test case name to
|
||||
# pass to [do_test] for each individual LIMIT OFFSET test case.
|
||||
#
|
||||
proc test_compound_select {testname sql result} {
|
||||
|
||||
set nCol 1
|
||||
db eval $sql A {
|
||||
set nCol [llength $A(*)]
|
||||
break
|
||||
}
|
||||
set nRow [expr {[llength $result] / $nCol}]
|
||||
|
||||
set ::compound_sql $sql
|
||||
do_test $testname {
|
||||
execsql $::compound_sql
|
||||
} $result
|
||||
#return
|
||||
|
||||
set iLimitIncr 1
|
||||
set iOffsetIncr 1
|
||||
if {[info exists ::G(isquick)] && $::G(isquick) && $nRow>=5} {
|
||||
set iOffsetIncr [expr $nRow / 5]
|
||||
set iLimitIncr [expr $nRow / 5]
|
||||
}
|
||||
|
||||
set iLimitEnd [expr $nRow+$iLimitIncr]
|
||||
set iOffsetEnd [expr $nRow+$iOffsetIncr]
|
||||
|
||||
for {set iOffset 0} {$iOffset < $iOffsetEnd} {incr iOffset $iOffsetIncr} {
|
||||
for {set iLimit 0} {$iLimit < $iLimitEnd} {incr iLimit} {
|
||||
|
||||
set ::compound_sql "$sql LIMIT $iLimit"
|
||||
if {$iOffset != 0} {
|
||||
append ::compound_sql " OFFSET $iOffset"
|
||||
}
|
||||
|
||||
set iStart [expr {$iOffset*$nCol}]
|
||||
set iEnd [expr {($iOffset*$nCol) + ($iLimit*$nCol) -1}]
|
||||
|
||||
do_test $testname.limit=$iLimit.offset=$iOffset {
|
||||
execsql $::compound_sql
|
||||
} [lrange $result $iStart $iEnd]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# test_compound_select_flippable TESTNAME SELECT RESULT
|
||||
#
|
||||
# This command is for testing statements of the form:
|
||||
#
|
||||
# <simple select 1> <compound op> <simple select 2> ORDER BY <order by>
|
||||
#
|
||||
# where each <simple select> is a simple (non-compound) select statement
|
||||
# and <compound op> is one of "INTERSECT", "UNION ALL" or "UNION".
|
||||
#
|
||||
# This proc calls [test_compound_select] twice, once with the select
|
||||
# statement as it is passed to this command, and once with the positions
|
||||
# of <select statement 1> and <select statement 2> exchanged.
|
||||
#
|
||||
proc test_compound_select_flippable {testname sql result} {
|
||||
test_compound_select $testname $sql $result
|
||||
|
||||
set select [string trim $sql]
|
||||
set RE {(.*)(UNION ALL|INTERSECT|UNION)(.*)(ORDER BY.*)}
|
||||
set rc [regexp $RE $select -> s1 op s2 order_by]
|
||||
if {!$rc} {error "Statement is unflippable: $select"}
|
||||
|
||||
set flipsql "$s2 $op $s1 $order_by"
|
||||
test_compound_select $testname.flipped $flipsql $result
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# Begin tests.
|
||||
#
|
||||
|
||||
# Create and populate a sample database.
|
||||
#
|
||||
do_test select9-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE TABLE t2(d, e, f);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1, 'one', 'I');
|
||||
INSERT INTO t1 VALUES(3, NULL, NULL);
|
||||
INSERT INTO t1 VALUES(5, 'five', 'V');
|
||||
INSERT INTO t1 VALUES(7, 'seven', 'VII');
|
||||
INSERT INTO t1 VALUES(9, NULL, NULL);
|
||||
INSERT INTO t1 VALUES(2, 'two', 'II');
|
||||
INSERT INTO t1 VALUES(4, 'four', 'IV');
|
||||
INSERT INTO t1 VALUES(6, NULL, NULL);
|
||||
INSERT INTO t1 VALUES(8, 'eight', 'VIII');
|
||||
INSERT INTO t1 VALUES(10, 'ten', 'X');
|
||||
|
||||
INSERT INTO t2 VALUES(1, 'two', 'IV');
|
||||
INSERT INTO t2 VALUES(2, 'four', 'VIII');
|
||||
INSERT INTO t2 VALUES(3, NULL, NULL);
|
||||
INSERT INTO t2 VALUES(4, 'eight', 'XVI');
|
||||
INSERT INTO t2 VALUES(5, 'ten', 'XX');
|
||||
INSERT INTO t2 VALUES(6, NULL, NULL);
|
||||
INSERT INTO t2 VALUES(7, 'fourteen', 'XXVIII');
|
||||
INSERT INTO t2 VALUES(8, 'sixteen', 'XXXII');
|
||||
INSERT INTO t2 VALUES(9, NULL, NULL);
|
||||
INSERT INTO t2 VALUES(10, 'twenty', 'XL');
|
||||
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
|
||||
# Each iteration of this loop runs the same tests with a different set
|
||||
# of indexes present within the database schema. The data returned by
|
||||
# the compound SELECT statements in the test cases should be the same
|
||||
# in each case.
|
||||
#
|
||||
set iOuterLoop 1
|
||||
foreach indexes [list {
|
||||
/* Do not create any indexes. */
|
||||
} {
|
||||
CREATE INDEX i1 ON t1(a)
|
||||
} {
|
||||
CREATE INDEX i2 ON t1(b)
|
||||
} {
|
||||
CREATE INDEX i3 ON t2(d)
|
||||
} {
|
||||
CREATE INDEX i4 ON t2(e)
|
||||
}] {
|
||||
|
||||
do_test select9-1.$iOuterLoop.1 {
|
||||
execsql $indexes
|
||||
} {}
|
||||
|
||||
# Test some 2-way UNION ALL queries. No WHERE clauses.
|
||||
#
|
||||
test_compound_select select9-1.$iOuterLoop.2 {
|
||||
SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2
|
||||
} {1 one 3 {} 5 five 7 seven 9 {} 2 two 4 four 6 {} 8 eight 10 ten 1 two 2 four 3 {} 4 eight 5 ten 6 {} 7 fourteen 8 sixteen 9 {} 10 twenty}
|
||||
test_compound_select select9-1.$iOuterLoop.3 {
|
||||
SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY 1
|
||||
} {1 one 1 two 2 two 2 four 3 {} 3 {} 4 four 4 eight 5 five 5 ten 6 {} 6 {} 7 seven 7 fourteen 8 eight 8 sixteen 9 {} 9 {} 10 ten 10 twenty}
|
||||
test_compound_select select9-1.$iOuterLoop.4 {
|
||||
SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY 2
|
||||
} {3 {} 9 {} 6 {} 3 {} 6 {} 9 {} 8 eight 4 eight 5 five 4 four 2 four 7 fourteen 1 one 7 seven 8 sixteen 10 ten 5 ten 10 twenty 2 two 1 two}
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.5 {
|
||||
SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY 1, 2
|
||||
} {1 one 1 two 2 four 2 two 3 {} 3 {} 4 eight 4 four 5 five 5 ten 6 {} 6 {} 7 fourteen 7 seven 8 eight 8 sixteen 9 {} 9 {} 10 ten 10 twenty}
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.6 {
|
||||
SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY 2, 1
|
||||
} {3 {} 3 {} 6 {} 6 {} 9 {} 9 {} 4 eight 8 eight 5 five 2 four 4 four 7 fourteen 1 one 7 seven 8 sixteen 5 ten 10 ten 10 twenty 1 two 2 two}
|
||||
|
||||
# Test some 2-way UNION queries.
|
||||
#
|
||||
test_compound_select select9-1.$iOuterLoop.7 {
|
||||
SELECT a, b FROM t1 UNION SELECT d, e FROM t2
|
||||
} {1 one 1 two 2 four 2 two 3 {} 4 eight 4 four 5 five 5 ten 6 {} 7 fourteen 7 seven 8 eight 8 sixteen 9 {} 10 ten 10 twenty}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.8 {
|
||||
SELECT a, b FROM t1 UNION SELECT d, e FROM t2 ORDER BY 1
|
||||
} {1 one 1 two 2 four 2 two 3 {} 4 eight 4 four 5 five 5 ten 6 {} 7 fourteen 7 seven 8 eight 8 sixteen 9 {} 10 ten 10 twenty}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.9 {
|
||||
SELECT a, b FROM t1 UNION SELECT d, e FROM t2 ORDER BY 2
|
||||
} {3 {} 6 {} 9 {} 4 eight 8 eight 5 five 2 four 4 four 7 fourteen 1 one 7 seven 8 sixteen 5 ten 10 ten 10 twenty 1 two 2 two}
|
||||
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.10 {
|
||||
SELECT a, b FROM t1 UNION SELECT d, e FROM t2 ORDER BY 1, 2
|
||||
} {1 one 1 two 2 four 2 two 3 {} 4 eight 4 four 5 five 5 ten 6 {} 7 fourteen 7 seven 8 eight 8 sixteen 9 {} 10 ten 10 twenty}
|
||||
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.11 {
|
||||
SELECT a, b FROM t1 UNION SELECT d, e FROM t2 ORDER BY 2, 1
|
||||
} {3 {} 6 {} 9 {} 4 eight 8 eight 5 five 2 four 4 four 7 fourteen 1 one 7 seven 8 sixteen 5 ten 10 ten 10 twenty 1 two 2 two}
|
||||
|
||||
# Test some 2-way INTERSECT queries.
|
||||
#
|
||||
test_compound_select select9-1.$iOuterLoop.11 {
|
||||
SELECT a, b FROM t1 INTERSECT SELECT d, e FROM t2
|
||||
} {3 {} 6 {} 9 {}}
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.12 {
|
||||
SELECT a, b FROM t1 INTERSECT SELECT d, e FROM t2 ORDER BY 1
|
||||
} {3 {} 6 {} 9 {}}
|
||||
test_compound_select select9-1.$iOuterLoop.13 {
|
||||
SELECT a, b FROM t1 INTERSECT SELECT d, e FROM t2 ORDER BY 2
|
||||
} {3 {} 6 {} 9 {}}
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.14 {
|
||||
SELECT a, b FROM t1 INTERSECT SELECT d, e FROM t2 ORDER BY 2, 1
|
||||
} {3 {} 6 {} 9 {}}
|
||||
test_compound_select_flippable select9-1.$iOuterLoop.15 {
|
||||
SELECT a, b FROM t1 INTERSECT SELECT d, e FROM t2 ORDER BY 1, 2
|
||||
} {3 {} 6 {} 9 {}}
|
||||
|
||||
# Test some 2-way EXCEPT queries.
|
||||
#
|
||||
test_compound_select select9-1.$iOuterLoop.16 {
|
||||
SELECT a, b FROM t1 EXCEPT SELECT d, e FROM t2
|
||||
} {1 one 2 two 4 four 5 five 7 seven 8 eight 10 ten}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.17 {
|
||||
SELECT a, b FROM t1 EXCEPT SELECT d, e FROM t2 ORDER BY 1
|
||||
} {1 one 2 two 4 four 5 five 7 seven 8 eight 10 ten}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.18 {
|
||||
SELECT a, b FROM t1 EXCEPT SELECT d, e FROM t2 ORDER BY 2
|
||||
} {8 eight 5 five 4 four 1 one 7 seven 10 ten 2 two}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.19 {
|
||||
SELECT a, b FROM t1 EXCEPT SELECT d, e FROM t2 ORDER BY 1, 2
|
||||
} {1 one 2 two 4 four 5 five 7 seven 8 eight 10 ten}
|
||||
|
||||
test_compound_select select9-1.$iOuterLoop.20 {
|
||||
SELECT a, b FROM t1 EXCEPT SELECT d, e FROM t2 ORDER BY 2, 1
|
||||
} {8 eight 5 five 4 four 1 one 7 seven 10 ten 2 two}
|
||||
|
||||
incr iOuterLoop
|
||||
}
|
||||
|
||||
do_test select9-2.0 {
|
||||
execsql {
|
||||
DROP INDEX i1;
|
||||
DROP INDEX i2;
|
||||
DROP INDEX i3;
|
||||
DROP INDEX i4;
|
||||
}
|
||||
} {}
|
||||
|
||||
proc reverse {lhs rhs} {
|
||||
return [string compare $rhs $lhs]
|
||||
}
|
||||
db collate reverse reverse
|
||||
|
||||
# This loop is similar to the previous one (test cases select9-1.*)
|
||||
# except that the simple select statements have WHERE clauses attached
|
||||
# to them. Sometimes the WHERE clause may be satisfied using the same
|
||||
# index used for ORDER BY, sometimes not.
|
||||
#
|
||||
set iOuterLoop 1
|
||||
foreach indexes [list {
|
||||
/* Do not create any indexes. */
|
||||
} {
|
||||
CREATE INDEX i1 ON t1(a)
|
||||
} {
|
||||
DROP INDEX i1;
|
||||
CREATE INDEX i1 ON t1(b, a)
|
||||
} {
|
||||
CREATE INDEX i2 ON t2(d DESC, e COLLATE REVERSE ASC);
|
||||
} {
|
||||
CREATE INDEX i3 ON t1(a DESC);
|
||||
}] {
|
||||
do_test select9-2.$iOuterLoop.1 {
|
||||
execsql $indexes
|
||||
} {}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.2 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION SELECT * FROM t2 WHERE d>=5 ORDER BY 1
|
||||
} {1 one I 2 two II 3 {} {} 4 four IV 5 ten XX 6 {} {} 7 fourteen XXVIII 8 sixteen XXXII 9 {} {} 10 twenty XL}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.2 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION SELECT * FROM t2 WHERE d>=5 ORDER BY 2, 1
|
||||
} {3 {} {} 6 {} {} 9 {} {} 4 four IV 7 fourteen XXVIII 1 one I 8 sixteen XXXII 5 ten XX 10 twenty XL 2 two II}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.3 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION SELECT * FROM t2 WHERE d>=5
|
||||
ORDER BY 2 COLLATE reverse, 1
|
||||
} {3 {} {} 6 {} {} 9 {} {} 2 two II 10 twenty XL 5 ten XX 8 sixteen XXXII 1 one I 7 fourteen XXVIII 4 four IV}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.4 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION ALL SELECT * FROM t2 WHERE d>=5 ORDER BY 1
|
||||
} {1 one I 2 two II 3 {} {} 4 four IV 5 ten XX 6 {} {} 7 fourteen XXVIII 8 sixteen XXXII 9 {} {} 10 twenty XL}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.5 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION ALL SELECT * FROM t2 WHERE d>=5 ORDER BY 2, 1
|
||||
} {3 {} {} 6 {} {} 9 {} {} 4 four IV 7 fourteen XXVIII 1 one I 8 sixteen XXXII 5 ten XX 10 twenty XL 2 two II}
|
||||
|
||||
test_compound_select_flippable select9-2.$iOuterLoop.6 {
|
||||
SELECT * FROM t1 WHERE a<5 UNION ALL SELECT * FROM t2 WHERE d>=5
|
||||
ORDER BY 2 COLLATE reverse, 1
|
||||
} {3 {} {} 6 {} {} 9 {} {} 2 two II 10 twenty XL 5 ten XX 8 sixteen XXXII 1 one I 7 fourteen XXVIII 4 four IV}
|
||||
|
||||
test_compound_select select9-2.$iOuterLoop.4 {
|
||||
SELECT a FROM t1 WHERE a<8 EXCEPT SELECT d FROM t2 WHERE d<=3 ORDER BY 1
|
||||
} {4 5 6 7}
|
||||
|
||||
test_compound_select select9-2.$iOuterLoop.4 {
|
||||
SELECT a FROM t1 WHERE a<8 INTERSECT SELECT d FROM t2 WHERE d<=3 ORDER BY 1
|
||||
} {1 2 3}
|
||||
|
||||
}
|
||||
|
||||
do_test select9-2.X {
|
||||
execsql {
|
||||
DROP INDEX i1;
|
||||
DROP INDEX i2;
|
||||
DROP INDEX i3;
|
||||
}
|
||||
} {}
|
||||
|
||||
# This procedure executes the SQL. Then it checks the generated program
|
||||
# for the SQL and appends a "nosort" to the result if the program contains the
|
||||
# SortCallback opcode. If the program does not contain the SortCallback
|
||||
# opcode it appends "sort"
|
||||
#
|
||||
proc cksort {sql} {
|
||||
set ::sqlite_sort_count 0
|
||||
set data [execsql $sql]
|
||||
if {$::sqlite_sort_count} {set x sort} {set x nosort}
|
||||
lappend data $x
|
||||
return $data
|
||||
}
|
||||
|
||||
# If the right indexes exist, the following query:
|
||||
#
|
||||
# SELECT t1.a FROM t1 UNION ALL SELECT t2.d FROM t2 ORDER BY 1
|
||||
#
|
||||
# can use indexes to run without doing a in-memory sort operation.
|
||||
# This block of tests (select9-3.*) is used to check if the same
|
||||
# is possible with:
|
||||
#
|
||||
# CREATE VIEW v1 AS SELECT a FROM t1 UNION ALL SELECT d FROM t2
|
||||
# SELECT a FROM v1 ORDER BY 1
|
||||
#
|
||||
# It turns out that it is.
|
||||
#
|
||||
do_test select9-3.1 {
|
||||
cksort { SELECT a FROM t1 ORDER BY 1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10 sort}
|
||||
do_test select9-3.2 {
|
||||
execsql { CREATE INDEX i1 ON t1(a) }
|
||||
cksort { SELECT a FROM t1 ORDER BY 1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10 nosort}
|
||||
do_test select9-3.3 {
|
||||
cksort { SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 5 }
|
||||
} {1 1 2 2 3 sort}
|
||||
do_test select9-3.4 {
|
||||
execsql { CREATE INDEX i2 ON t2(d) }
|
||||
cksort { SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 5 }
|
||||
} {1 1 2 2 3 nosort}
|
||||
do_test select9-3.5 {
|
||||
execsql { CREATE VIEW v1 AS SELECT a FROM t1 UNION ALL SELECT d FROM t2 }
|
||||
cksort { SELECT a FROM v1 ORDER BY 1 LIMIT 5 }
|
||||
} {1 1 2 2 3 nosort}
|
||||
do_test select9-3.X {
|
||||
execsql {
|
||||
DROP INDEX i1;
|
||||
DROP INDEX i2;
|
||||
DROP VIEW v1;
|
||||
}
|
||||
} {}
|
||||
|
||||
# This block of tests is the same as the preceding one, except that
|
||||
# "UNION" is tested instead of "UNION ALL".
|
||||
#
|
||||
do_test select9-4.1 {
|
||||
cksort { SELECT a FROM t1 ORDER BY 1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10 sort}
|
||||
do_test select9-4.2 {
|
||||
execsql { CREATE INDEX i1 ON t1(a) }
|
||||
cksort { SELECT a FROM t1 ORDER BY 1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10 nosort}
|
||||
do_test select9-4.3 {
|
||||
cksort { SELECT a FROM t1 UNION SELECT d FROM t2 ORDER BY 1 LIMIT 5 }
|
||||
} {1 2 3 4 5 sort}
|
||||
do_test select9-4.4 {
|
||||
execsql { CREATE INDEX i2 ON t2(d) }
|
||||
cksort { SELECT a FROM t1 UNION SELECT d FROM t2 ORDER BY 1 LIMIT 5 }
|
||||
} {1 2 3 4 5 nosort}
|
||||
do_test select9-4.5 {
|
||||
execsql { CREATE VIEW v1 AS SELECT a FROM t1 UNION SELECT d FROM t2 }
|
||||
cksort { SELECT a FROM v1 ORDER BY 1 LIMIT 5 }
|
||||
} {1 2 3 4 5 sort}
|
||||
do_test select9-4.X {
|
||||
execsql {
|
||||
DROP INDEX i1;
|
||||
DROP INDEX i2;
|
||||
DROP VIEW v1;
|
||||
}
|
||||
} {}
|
||||
|
||||
# Testing to make sure that queries involving a view of a compound select
|
||||
# are planned efficiently. This detects a problem reported on the mailing
|
||||
# list on 2012-04-26. See
|
||||
#
|
||||
# http://www.mail-archive.com/sqlite-users%40sqlite.org/msg69746.html
|
||||
#
|
||||
# For additional information.
|
||||
#
|
||||
do_test select9-5.1 {
|
||||
db eval {
|
||||
CREATE TABLE t51(x, y);
|
||||
CREATE TABLE t52(x, y);
|
||||
CREATE VIEW v5 as
|
||||
SELECT x, y FROM t51
|
||||
UNION ALL
|
||||
SELECT x, y FROM t52;
|
||||
CREATE INDEX t51x ON t51(x);
|
||||
CREATE INDEX t52x ON t52(x);
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM v5 WHERE x='12345' ORDER BY y;
|
||||
}
|
||||
} {~/SCAN/} ;# Uses indices with "*"
|
||||
do_test select9-5.2 {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT x, y FROM v5 WHERE x='12345' ORDER BY y;
|
||||
}
|
||||
} {~/SCAN/} ;# Uses indices with "x, y"
|
||||
do_test select9-5.3 {
|
||||
db eval {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT x, y FROM v5 WHERE +x='12345' ORDER BY y;
|
||||
}
|
||||
} {/SCAN/} ;# Full table scan if the "+x" prevents index usage.
|
||||
|
||||
# 2013-07-09: Ticket [490a4b7235624298]:
|
||||
# "WHERE 0" on the first element of a UNION causes an assertion fault
|
||||
#
|
||||
do_execsql_test select9-6.1 {
|
||||
CREATE TABLE t61(a);
|
||||
CREATE TABLE t62(b);
|
||||
INSERT INTO t61 VALUES(111);
|
||||
INSERT INTO t62 VALUES(222);
|
||||
SELECT a FROM t61 WHERE 0 UNION SELECT b FROM t62;
|
||||
} {222}
|
||||
do_execsql_test select9-6.2 {
|
||||
SELECT a FROM t61 WHERE 0 UNION ALL SELECT b FROM t62;
|
||||
} {222}
|
||||
do_execsql_test select9-6.3 {
|
||||
SELECT a FROM t61 UNION SELECT b FROM t62 WHERE 0;
|
||||
} {111}
|
||||
|
||||
|
||||
|
||||
finish_test
|
1510
testing/sqlite3/selectA.test
Normal file
1510
testing/sqlite3/selectA.test
Normal file
File diff suppressed because it is too large
Load diff
426
testing/sqlite3/selectB.test
Normal file
426
testing/sqlite3/selectB.test
Normal file
|
@ -0,0 +1,426 @@
|
|||
# 2008 June 24
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# $Id: selectB.test,v 1.10 2009/04/02 16:59:47 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !compound {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc test_transform {testname sql1 sql2 results} {
|
||||
set ::vdbe1 [list]
|
||||
set ::vdbe2 [list]
|
||||
db eval "explain $sql1" { lappend ::vdbe1 $opcode }
|
||||
db eval "explain $sql2" { lappend ::vdbe2 $opcode }
|
||||
|
||||
do_test $testname.transform {
|
||||
set ::vdbe1
|
||||
} $::vdbe2
|
||||
|
||||
set ::sql1 $sql1
|
||||
do_test $testname.sql1 {
|
||||
execsql $::sql1
|
||||
} $results
|
||||
|
||||
set ::sql2 $sql2
|
||||
do_test $testname.sql2 {
|
||||
execsql $::sql2
|
||||
} $results
|
||||
}
|
||||
|
||||
do_test selectB-1.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
CREATE TABLE t2(d, e, f);
|
||||
|
||||
INSERT INTO t1 VALUES( 2, 4, 6);
|
||||
INSERT INTO t1 VALUES( 8, 10, 12);
|
||||
INSERT INTO t1 VALUES(14, 16, 18);
|
||||
|
||||
INSERT INTO t2 VALUES(3, 6, 9);
|
||||
INSERT INTO t2 VALUES(12, 15, 18);
|
||||
INSERT INTO t2 VALUES(21, 24, 27);
|
||||
}
|
||||
} {}
|
||||
|
||||
for {set ii 1} {$ii <= 2} {incr ii} {
|
||||
|
||||
if {$ii == 2} {
|
||||
do_test selectB-2.1 {
|
||||
execsql {
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
CREATE INDEX i2 ON t2(d);
|
||||
}
|
||||
} {}
|
||||
}
|
||||
|
||||
test_transform selectB-$ii.2 {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2
|
||||
} {2 8 14 3 12 21}
|
||||
|
||||
test_transform selectB-$ii.3 {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1
|
||||
} {2 3 8 12 14 21}
|
||||
|
||||
test_transform selectB-$ii.4 {
|
||||
SELECT * FROM
|
||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
WHERE a>10 ORDER BY 1
|
||||
} {
|
||||
SELECT a FROM t1 WHERE a>10 UNION ALL SELECT d FROM t2 WHERE d>10 ORDER BY 1
|
||||
} {12 14 21}
|
||||
|
||||
test_transform selectB-$ii.5 {
|
||||
SELECT * FROM
|
||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
WHERE a>10 ORDER BY a
|
||||
} {
|
||||
SELECT a FROM t1 WHERE a>10
|
||||
UNION ALL
|
||||
SELECT d FROM t2 WHERE d>10
|
||||
ORDER BY a
|
||||
} {12 14 21}
|
||||
|
||||
test_transform selectB-$ii.6 {
|
||||
SELECT * FROM
|
||||
(SELECT a FROM t1 UNION ALL SELECT d FROM t2 WHERE d > 12)
|
||||
WHERE a>10 ORDER BY a
|
||||
} {
|
||||
SELECT a FROM t1 WHERE a>10
|
||||
UNION ALL
|
||||
SELECT d FROM t2 WHERE d>12 AND d>10
|
||||
ORDER BY a
|
||||
} {14 21}
|
||||
|
||||
test_transform selectB-$ii.7 {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
||||
LIMIT 2
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2
|
||||
} {2 3}
|
||||
|
||||
test_transform selectB-$ii.8 {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2) ORDER BY 1
|
||||
LIMIT 2 OFFSET 3
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 LIMIT 2 OFFSET 3
|
||||
} {12 14}
|
||||
|
||||
test_transform selectB-$ii.9 {
|
||||
SELECT * FROM (
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1
|
||||
)
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1
|
||||
} {2 8 14 3 12 21 6 12 18}
|
||||
|
||||
test_transform selectB-$ii.10 {
|
||||
SELECT * FROM (
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1
|
||||
) ORDER BY 1
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1
|
||||
ORDER BY 1
|
||||
} {2 3 6 8 12 12 14 18 21}
|
||||
|
||||
test_transform selectB-$ii.11 {
|
||||
SELECT * FROM (
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 UNION ALL SELECT c FROM t1
|
||||
) WHERE a>=10 ORDER BY 1 LIMIT 3
|
||||
} {
|
||||
SELECT a FROM t1 WHERE a>=10 UNION ALL SELECT d FROM t2 WHERE d>=10
|
||||
UNION ALL SELECT c FROM t1 WHERE c>=10
|
||||
ORDER BY 1 LIMIT 3
|
||||
} {12 12 14}
|
||||
|
||||
test_transform selectB-$ii.12 {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2 LIMIT 2)
|
||||
} {
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 LIMIT 2
|
||||
} {2 8}
|
||||
|
||||
# An ORDER BY in a compound subqueries defeats flattening. Ticket #3773
|
||||
# test_transform selectB-$ii.13 {
|
||||
# SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY a ASC)
|
||||
# } {
|
||||
# SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 ASC
|
||||
# } {2 3 8 12 14 21}
|
||||
#
|
||||
# test_transform selectB-$ii.14 {
|
||||
# SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY a DESC)
|
||||
# } {
|
||||
# SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 DESC
|
||||
# } {21 14 12 8 3 2}
|
||||
#
|
||||
# test_transform selectB-$ii.14 {
|
||||
# SELECT * FROM (
|
||||
# SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY a DESC
|
||||
# ) LIMIT 2 OFFSET 2
|
||||
# } {
|
||||
# SELECT a FROM t1 UNION ALL SELECT d FROM t2 ORDER BY 1 DESC
|
||||
# LIMIT 2 OFFSET 2
|
||||
# } {12 8}
|
||||
#
|
||||
# test_transform selectB-$ii.15 {
|
||||
# SELECT * FROM (
|
||||
# SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY a ASC, e DESC
|
||||
# )
|
||||
# } {
|
||||
# SELECT a, b FROM t1 UNION ALL SELECT d, e FROM t2 ORDER BY a ASC, e DESC
|
||||
# } {2 4 3 6 8 10 12 15 14 16 21 24}
|
||||
}
|
||||
|
||||
do_test selectB-3.0 {
|
||||
execsql {
|
||||
DROP INDEX i1;
|
||||
DROP INDEX i2;
|
||||
}
|
||||
} {}
|
||||
|
||||
for {set ii 3} {$ii <= 6} {incr ii} {
|
||||
|
||||
switch $ii {
|
||||
4 {
|
||||
optimization_control db query-flattener off
|
||||
}
|
||||
5 {
|
||||
optimization_control db query-flattener on
|
||||
do_test selectB-5.0 {
|
||||
execsql {
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
CREATE INDEX i2 ON t1(b);
|
||||
CREATE INDEX i3 ON t1(c);
|
||||
CREATE INDEX i4 ON t2(d);
|
||||
CREATE INDEX i5 ON t2(e);
|
||||
CREATE INDEX i6 ON t2(f);
|
||||
}
|
||||
} {}
|
||||
}
|
||||
6 {
|
||||
optimization_control db query-flattener off
|
||||
}
|
||||
}
|
||||
|
||||
do_test selectB-$ii.1 {
|
||||
execsql {
|
||||
SELECT DISTINCT * FROM
|
||||
(SELECT c FROM t1 UNION ALL SELECT e FROM t2)
|
||||
ORDER BY 1;
|
||||
}
|
||||
} {6 12 15 18 24}
|
||||
|
||||
do_test selectB-$ii.2 {
|
||||
execsql {
|
||||
SELECT c, count(*) FROM
|
||||
(SELECT c FROM t1 UNION ALL SELECT e FROM t2)
|
||||
GROUP BY c ORDER BY 1;
|
||||
}
|
||||
} {6 2 12 1 15 1 18 1 24 1}
|
||||
do_test selectB-$ii.3 {
|
||||
execsql {
|
||||
SELECT c, count(*) FROM
|
||||
(SELECT c FROM t1 UNION ALL SELECT e FROM t2)
|
||||
GROUP BY c HAVING count(*)>1;
|
||||
}
|
||||
} {6 2}
|
||||
do_test selectB-$ii.4 {
|
||||
execsql {
|
||||
SELECT t4.c, t3.a FROM
|
||||
(SELECT c FROM t1 UNION ALL SELECT e FROM t2) AS t4, t1 AS t3
|
||||
WHERE t3.a=14
|
||||
ORDER BY 1
|
||||
}
|
||||
} {6 14 6 14 12 14 15 14 18 14 24 14}
|
||||
|
||||
do_test selectB-$ii.5 {
|
||||
execsql {
|
||||
SELECT d FROM t2
|
||||
EXCEPT
|
||||
SELECT a FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
}
|
||||
} {}
|
||||
do_test selectB-$ii.6 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
EXCEPT
|
||||
SELECT * FROM (SELECT a FROM t1 UNION ALL SELECT d FROM t2)
|
||||
}
|
||||
} {}
|
||||
do_test selectB-$ii.7 {
|
||||
execsql {
|
||||
SELECT c FROM t1
|
||||
EXCEPT
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
}
|
||||
} {12}
|
||||
do_test selectB-$ii.8 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
EXCEPT
|
||||
SELECT c FROM t1
|
||||
}
|
||||
} {9 15 24 27}
|
||||
do_test selectB-$ii.9 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
EXCEPT
|
||||
SELECT c FROM t1
|
||||
ORDER BY c DESC
|
||||
}
|
||||
} {27 24 15 9}
|
||||
|
||||
do_test selectB-$ii.10 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
UNION
|
||||
SELECT c FROM t1
|
||||
ORDER BY c DESC
|
||||
}
|
||||
} {27 24 18 15 12 9 6}
|
||||
do_test selectB-$ii.11 {
|
||||
execsql {
|
||||
SELECT c FROM t1
|
||||
UNION
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
ORDER BY c
|
||||
}
|
||||
} {6 9 12 15 18 24 27}
|
||||
do_test selectB-$ii.12 {
|
||||
execsql {
|
||||
SELECT c FROM t1 UNION SELECT e FROM t2 UNION ALL SELECT f FROM t2
|
||||
ORDER BY c
|
||||
}
|
||||
} {6 9 12 15 18 18 24 27}
|
||||
do_test selectB-$ii.13 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
UNION
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
ORDER BY 1
|
||||
}
|
||||
} {6 9 15 18 24 27}
|
||||
|
||||
do_test selectB-$ii.14 {
|
||||
execsql {
|
||||
SELECT c FROM t1
|
||||
INTERSECT
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
ORDER BY 1
|
||||
}
|
||||
} {6 18}
|
||||
do_test selectB-$ii.15 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
INTERSECT
|
||||
SELECT c FROM t1
|
||||
ORDER BY 1
|
||||
}
|
||||
} {6 18}
|
||||
do_test selectB-$ii.16 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
INTERSECT
|
||||
SELECT * FROM (SELECT e FROM t2 UNION ALL SELECT f FROM t2)
|
||||
ORDER BY 1
|
||||
}
|
||||
} {6 9 15 18 24 27}
|
||||
|
||||
do_test selectB-$ii.17 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 LIMIT 4
|
||||
) LIMIT 2
|
||||
}
|
||||
} {2 8}
|
||||
|
||||
do_test selectB-$ii.18 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT a FROM t1 UNION ALL SELECT d FROM t2 LIMIT 4 OFFSET 2
|
||||
) LIMIT 2
|
||||
}
|
||||
} {14 3}
|
||||
|
||||
do_test selectB-$ii.19 {
|
||||
execsql {
|
||||
SELECT * FROM (
|
||||
SELECT DISTINCT (a/10) FROM t1 UNION ALL SELECT DISTINCT(d%2) FROM t2
|
||||
)
|
||||
}
|
||||
} {0 1 1 0}
|
||||
|
||||
do_test selectB-$ii.20 {
|
||||
execsql {
|
||||
SELECT DISTINCT * FROM (
|
||||
SELECT DISTINCT (a/10) FROM t1 UNION ALL SELECT DISTINCT(d%2) FROM t2
|
||||
)
|
||||
}
|
||||
} {0 1}
|
||||
|
||||
do_test selectB-$ii.21 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2) ORDER BY a+b
|
||||
}
|
||||
} {2 4 6 3 6 9 8 10 12 12 15 18 14 16 18 21 24 27}
|
||||
|
||||
do_test selectB-$ii.22 {
|
||||
execsql {
|
||||
SELECT * FROM (SELECT 345 UNION ALL SELECT d FROM t2) ORDER BY 1;
|
||||
}
|
||||
} {3 12 21 345}
|
||||
|
||||
do_test selectB-$ii.23 {
|
||||
execsql {
|
||||
SELECT x, y FROM (
|
||||
SELECT a AS x, b AS y FROM t1
|
||||
UNION ALL
|
||||
SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 JOIN t2 ON (c=d)
|
||||
UNION ALL
|
||||
SELECT a*100, b*100 FROM t1
|
||||
) ORDER BY 1;
|
||||
}
|
||||
} {2 4 8 10 14 16 80.1 180.1 200 400 800 1000 1400 1600}
|
||||
|
||||
do_test selectB-$ii.24 {
|
||||
execsql {
|
||||
SELECT x, y FROM (
|
||||
SELECT a AS x, b AS y FROM t1
|
||||
UNION ALL
|
||||
SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d)
|
||||
UNION ALL
|
||||
SELECT a*100, b*100 FROM t1
|
||||
) ORDER BY 1;
|
||||
}
|
||||
} {2 4 8 10 14 16 20.1 {} 80.1 180.1 140.1 {} 200 400 800 1000 1400 1600}
|
||||
|
||||
do_test selectB-$ii.25 {
|
||||
execsql {
|
||||
SELECT x+y FROM (
|
||||
SELECT a AS x, b AS y FROM t1
|
||||
UNION ALL
|
||||
SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d)
|
||||
UNION ALL
|
||||
SELECT a*100, b*100 FROM t1
|
||||
) WHERE y+x NOT NULL ORDER BY 1;
|
||||
}
|
||||
} {6 18 30 260.2 600 1800 3000}
|
||||
}
|
||||
|
||||
finish_test
|
275
testing/sqlite3/selectC.test
Normal file
275
testing/sqlite3/selectC.test
Normal file
|
@ -0,0 +1,275 @@
|
|||
# 2008 September 16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# $Id: selectC.test,v 1.5 2009/05/17 15:26:21 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix selectC
|
||||
|
||||
# Ticket #
|
||||
do_test selectC-1.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES(1,'aaa','bbb');
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 VALUES(2,'ccc','ddd');
|
||||
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE y IN ('aaabbb','xxx');
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.2 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE b||c IN ('aaabbb','xxx');
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.3 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE y='aaabbb'
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.4 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE b||c='aaabbb'
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.5 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE x=2
|
||||
}
|
||||
} {2 cccddd}
|
||||
do_test selectC-1.6 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE a=2
|
||||
}
|
||||
} {2 cccddd}
|
||||
do_test selectC-1.7 {
|
||||
execsql {
|
||||
SELECT DISTINCT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE +y='aaabbb'
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.8 {
|
||||
execsql {
|
||||
SELECT a AS x, b||c AS y
|
||||
FROM t1
|
||||
GROUP BY x, y
|
||||
HAVING y='aaabbb'
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.9 {
|
||||
execsql {
|
||||
SELECT a AS x, b||c AS y
|
||||
FROM t1
|
||||
GROUP BY x, y
|
||||
HAVING b||c='aaabbb'
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.10 {
|
||||
execsql {
|
||||
SELECT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE y='aaabbb'
|
||||
GROUP BY x, y
|
||||
}
|
||||
} {1 aaabbb}
|
||||
do_test selectC-1.11 {
|
||||
execsql {
|
||||
SELECT a AS x, b||c AS y
|
||||
FROM t1
|
||||
WHERE b||c='aaabbb'
|
||||
GROUP BY x, y
|
||||
}
|
||||
} {1 aaabbb}
|
||||
proc longname_toupper x {return [string toupper $x]}
|
||||
db function uppercaseconversionfunctionwithaverylongname longname_toupper
|
||||
do_test selectC-1.12.1 {
|
||||
execsql {
|
||||
SELECT DISTINCT upper(b) AS x
|
||||
FROM t1
|
||||
ORDER BY x
|
||||
}
|
||||
} {AAA CCC}
|
||||
do_test selectC-1.12.2 {
|
||||
execsql {
|
||||
SELECT DISTINCT uppercaseconversionfunctionwithaverylongname(b) AS x
|
||||
FROM t1
|
||||
ORDER BY x
|
||||
}
|
||||
} {AAA CCC}
|
||||
do_test selectC-1.13.1 {
|
||||
execsql {
|
||||
SELECT upper(b) AS x
|
||||
FROM t1
|
||||
GROUP BY x
|
||||
ORDER BY x
|
||||
}
|
||||
} {AAA CCC}
|
||||
do_test selectC-1.13.2 {
|
||||
execsql {
|
||||
SELECT uppercaseconversionfunctionwithaverylongname(b) AS x
|
||||
FROM t1
|
||||
GROUP BY x
|
||||
ORDER BY x
|
||||
}
|
||||
} {AAA CCC}
|
||||
do_test selectC-1.14.1 {
|
||||
execsql {
|
||||
SELECT upper(b) AS x
|
||||
FROM t1
|
||||
ORDER BY x DESC
|
||||
}
|
||||
} {CCC AAA AAA}
|
||||
do_test selectC-1.14.2 {
|
||||
execsql {
|
||||
SELECT uppercaseconversionfunctionwithaverylongname(b) AS x
|
||||
FROM t1
|
||||
ORDER BY x DESC
|
||||
}
|
||||
} {CCC AAA AAA}
|
||||
|
||||
# The following query used to leak memory. Verify that has been fixed.
|
||||
#
|
||||
ifcapable trigger&&compound {
|
||||
do_test selectC-2.1 {
|
||||
catchsql {
|
||||
CREATE TABLE t21a(a,b);
|
||||
INSERT INTO t21a VALUES(1,2);
|
||||
CREATE TABLE t21b(n);
|
||||
CREATE TRIGGER r21 AFTER INSERT ON t21b BEGIN
|
||||
SELECT a FROM t21a WHERE a>new.x UNION ALL
|
||||
SELECT b FROM t21a WHERE b>new.x ORDER BY 1 LIMIT 2;
|
||||
END;
|
||||
INSERT INTO t21b VALUES(6);
|
||||
}
|
||||
} {1 {no such column: new.x}}
|
||||
}
|
||||
|
||||
# Check that ticket [883034dcb5] is fixed.
|
||||
#
|
||||
do_test selectC-3.1 {
|
||||
execsql {
|
||||
CREATE TABLE person (
|
||||
org_id TEXT NOT NULL,
|
||||
nickname TEXT NOT NULL,
|
||||
license TEXT,
|
||||
CONSTRAINT person_pk PRIMARY KEY (org_id, nickname),
|
||||
CONSTRAINT person_license_uk UNIQUE (license)
|
||||
);
|
||||
INSERT INTO person VALUES('meyers', 'jack', '2GAT123');
|
||||
INSERT INTO person VALUES('meyers', 'hill', 'V345FMP');
|
||||
INSERT INTO person VALUES('meyers', 'jim', '2GAT138');
|
||||
INSERT INTO person VALUES('smith', 'maggy', '');
|
||||
INSERT INTO person VALUES('smith', 'jose', 'JJZ109');
|
||||
INSERT INTO person VALUES('smith', 'jack', 'THX138');
|
||||
INSERT INTO person VALUES('lakeside', 'dave', '953OKG');
|
||||
INSERT INTO person VALUES('lakeside', 'amy', NULL);
|
||||
INSERT INTO person VALUES('lake-apts', 'tom', NULL);
|
||||
INSERT INTO person VALUES('acorn', 'hideo', 'CQB421');
|
||||
|
||||
SELECT
|
||||
org_id,
|
||||
count((NOT (org_id IS NULL)) AND (NOT (nickname IS NULL)))
|
||||
FROM person
|
||||
WHERE (CASE WHEN license != '' THEN 1 ELSE 0 END)
|
||||
GROUP BY 1;
|
||||
}
|
||||
} {acorn 1 lakeside 1 meyers 3 smith 2}
|
||||
do_test selectC-3.2 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||
INSERT INTO t2 VALUES('abc', 'xxx');
|
||||
INSERT INTO t2 VALUES('def', 'yyy');
|
||||
SELECT a, max(b || a) FROM t2 WHERE (b||b||b)!='value' GROUP BY a;
|
||||
}
|
||||
} {abc xxxabc def yyydef}
|
||||
do_test selectC-3.3 {
|
||||
execsql {
|
||||
SELECT b, max(a || b) FROM t2 WHERE (b||b||b)!='value' GROUP BY a;
|
||||
}
|
||||
} {xxx abcxxx yyy defyyy}
|
||||
|
||||
|
||||
proc udf {} { incr ::udf }
|
||||
set ::udf 0
|
||||
db function udf udf
|
||||
|
||||
do_execsql_test selectC-4.1 {
|
||||
create table t_distinct_bug (a, b, c);
|
||||
insert into t_distinct_bug values ('1', '1', 'a');
|
||||
insert into t_distinct_bug values ('1', '2', 'b');
|
||||
insert into t_distinct_bug values ('1', '3', 'c');
|
||||
insert into t_distinct_bug values ('1', '1', 'd');
|
||||
insert into t_distinct_bug values ('1', '2', 'e');
|
||||
insert into t_distinct_bug values ('1', '3', 'f');
|
||||
} {}
|
||||
|
||||
do_execsql_test selectC-4.2 {
|
||||
select a from (select distinct a, b from t_distinct_bug)
|
||||
} {1 1 1}
|
||||
|
||||
do_execsql_test selectC-4.2b {
|
||||
CREATE VIEW v42b AS SELECT DISTINCT a, b FROM t_distinct_bug;
|
||||
SELECT a FROM v42b;
|
||||
} {1 1 1}
|
||||
|
||||
do_execsql_test selectC-4.3 {
|
||||
select a, udf() from (select distinct a, b from t_distinct_bug)
|
||||
} {1 1 1 2 1 3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that the problem in ticket #190c2507 has been fixed.
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE x1(a);
|
||||
CREATE TABLE x2(b);
|
||||
CREATE TABLE x3(c);
|
||||
CREATE VIEW vvv AS SELECT b FROM x2 ORDER BY 1;
|
||||
|
||||
INSERT INTO x1 VALUES('a'), ('b');
|
||||
INSERT INTO x2 VALUES(22), (23), (25), (24), (21);
|
||||
INSERT INTO x3 VALUES(302), (303), (301);
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
CREATE TABLE x4 AS SELECT b FROM vvv UNION ALL SELECT c from x3;
|
||||
SELECT * FROM x4;
|
||||
} {21 22 23 24 25 302 303 301}
|
||||
|
||||
do_execsql_test 5.2 {
|
||||
SELECT * FROM x1, x4
|
||||
} {
|
||||
a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301
|
||||
b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301
|
||||
}
|
||||
|
||||
do_execsql_test 5.3 {
|
||||
SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3) ORDER BY 1,2;
|
||||
} {
|
||||
a 21 a 22 a 23 a 24 a 25 a 301 a 302 a 303
|
||||
b 21 b 22 b 23 b 24 b 25 b 301 b 302 b 303
|
||||
}
|
||||
|
||||
finish_test
|
174
testing/sqlite3/selectD.test
Normal file
174
testing/sqlite3/selectD.test
Normal file
|
@ -0,0 +1,174 @@
|
|||
# 2012 December 19
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for name resolution in SELECT
|
||||
# statements that have parenthesized FROM clauses.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
|
||||
for {set i 1} {$i<=2} {incr i} {
|
||||
db close
|
||||
forcedelete test$i.db
|
||||
sqlite3 db test$i.db
|
||||
if {$i==2} {
|
||||
optimization_control db query-flattener off
|
||||
}
|
||||
do_test selectD-$i.0 {
|
||||
db eval {
|
||||
ATTACH ':memory:' AS aux1;
|
||||
CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(111,'x1');
|
||||
CREATE TABLE t2(a,b); INSERT INTO t2 VALUES(222,'x2');
|
||||
CREATE TEMP TABLE t3(a,b); INSERT INTO t3 VALUES(333,'x3');
|
||||
CREATE TABLE main.t4(a,b); INSERT INTO main.t4 VALUES(444,'x4');
|
||||
CREATE TABLE aux1.t4(a,b); INSERT INTO aux1.t4 VALUES(555,'x5');
|
||||
}
|
||||
} {}
|
||||
do_test selectD-$i.1 {
|
||||
db eval {
|
||||
SELECT *
|
||||
FROM (t1), (t2), (t3), (t4)
|
||||
WHERE t4.a=t3.a+111
|
||||
AND t3.a=t2.a+111
|
||||
AND t2.a=t1.a+111;
|
||||
}
|
||||
} {111 x1 222 x2 333 x3 444 x4}
|
||||
do_test selectD-$i.2.1 {
|
||||
db eval {
|
||||
SELECT *
|
||||
FROM t1 JOIN (t2 JOIN (t3 JOIN t4 ON t4.a=t3.a+111)
|
||||
ON t3.a=t2.a+111)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {111 x1 222 x2 333 x3 444 x4}
|
||||
do_test selectD-$i.2.2 {
|
||||
db eval {
|
||||
SELECT t3.a
|
||||
FROM t1 JOIN (t2 JOIN (t3 JOIN t4 ON t4.a=t3.a+111)
|
||||
ON t3.a=t2.a+111)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {333}
|
||||
do_test selectD-$i.2.3 {
|
||||
db eval {
|
||||
SELECT t3.*
|
||||
FROM t1 JOIN (t2 JOIN (t3 JOIN t4 ON t4.a=t3.a+111)
|
||||
ON t3.a=t2.a+111)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {333 x3}
|
||||
do_test selectD-$i.2.3 {
|
||||
db eval {
|
||||
SELECT t3.*, t2.*
|
||||
FROM t1 JOIN (t2 JOIN (t3 JOIN t4 ON t4.a=t3.a+111)
|
||||
ON t3.a=t2.a+111)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {333 x3 222 x2}
|
||||
do_test selectD-$i.2.4 {
|
||||
db eval {
|
||||
SELECT *
|
||||
FROM t1 JOIN (t2 JOIN (main.t4 JOIN aux1.t4 ON aux1.t4.a=main.t4.a+111)
|
||||
ON main.t4.a=t2.a+222)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {111 x1 222 x2 444 x4 555 x5}
|
||||
do_test selectD-$i.2.5 {
|
||||
db eval {
|
||||
SELECT *
|
||||
FROM t1 JOIN (t2 JOIN (main.t4 AS x JOIN aux1.t4 ON aux1.t4.a=x.a+111)
|
||||
ON x.a=t2.a+222)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {111 x1 222 x2 444 x4 555 x5}
|
||||
do_test selectD-$i.2.6 {
|
||||
catchsql {
|
||||
SELECT *
|
||||
FROM t1 JOIN (t2 JOIN (main.t4 JOIN aux.t4 ON aux.t4.a=main.t4.a+111)
|
||||
ON main.t4.a=t2.a+222)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {1 {no such table: aux.t4}}
|
||||
do_test selectD-$i.2.7 {
|
||||
db eval {
|
||||
SELECT x.a, y.b
|
||||
FROM t1 JOIN (t2 JOIN (main.t4 x JOIN aux1.t4 y ON y.a=x.a+111)
|
||||
ON x.a=t2.a+222)
|
||||
ON t2.a=t1.a+111;
|
||||
}
|
||||
} {444 x5}
|
||||
do_test selectD-$i.3 {
|
||||
db eval {
|
||||
UPDATE t2 SET a=111;
|
||||
UPDATE t3 SET a=111;
|
||||
UPDATE t4 SET a=111;
|
||||
SELECT *
|
||||
FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING(a)) USING (a)) USING (a);
|
||||
}
|
||||
} {111 x1 x2 x3 x4}
|
||||
do_test selectD-$i.4 {
|
||||
db eval {
|
||||
UPDATE t2 SET a=111;
|
||||
UPDATE t3 SET a=111;
|
||||
UPDATE t4 SET a=111;
|
||||
SELECT *
|
||||
FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 USING(a))
|
||||
USING (a))
|
||||
USING (a);
|
||||
}
|
||||
} {111 x1 x2 x3 x4}
|
||||
do_test selectD-$i.5 {
|
||||
db eval {
|
||||
UPDATE t3 SET a=222;
|
||||
UPDATE t4 SET a=222;
|
||||
SELECT *
|
||||
FROM (t1 LEFT JOIN t2 USING(a)) JOIN (t3 LEFT JOIN t4 USING(a))
|
||||
ON t1.a=t3.a-111;
|
||||
}
|
||||
} {111 x1 x2 222 x3 x4}
|
||||
do_test selectD-$i.6 {
|
||||
db eval {
|
||||
UPDATE t4 SET a=333;
|
||||
SELECT *
|
||||
FROM (t1 LEFT JOIN t2 USING(a)) JOIN (t3 LEFT JOIN t4 USING(a))
|
||||
ON t1.a=t3.a-111;
|
||||
}
|
||||
} {111 x1 x2 222 x3 {}}
|
||||
do_test selectD-$i.7 {
|
||||
db eval {
|
||||
SELECT t1.*, t2.*, t3.*, t4.b
|
||||
FROM (t1 LEFT JOIN t2 USING(a)) JOIN (t3 LEFT JOIN t4 USING(a))
|
||||
ON t1.a=t3.a-111;
|
||||
}
|
||||
} {111 x1 111 x2 222 x3 {}}
|
||||
}
|
||||
|
||||
# The following test was added on 2013-04-24 in order to verify that
|
||||
# the datatypes and affinities of sub-sub-queries are set prior to computing
|
||||
# the datatypes and affinities of the parent sub-queries because the
|
||||
# latter computation depends on the former.
|
||||
#
|
||||
do_execsql_test selectD-4.1 {
|
||||
CREATE TABLE t41(a INTEGER PRIMARY KEY, b INTEGER);
|
||||
CREATE TABLE t42(d INTEGER PRIMARY KEY, e INTEGER);
|
||||
CREATE TABLE t43(f INTEGER PRIMARY KEY, g INTEGER);
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT *
|
||||
FROM t41
|
||||
LEFT JOIN (SELECT count(*) AS cnt, x1.d
|
||||
FROM (t42 INNER JOIN t43 ON d=g) AS x1
|
||||
WHERE x1.d>5
|
||||
GROUP BY x1.d) AS x2
|
||||
ON t41.b=x2.d;
|
||||
} {/SEARCH x2 USING AUTOMATIC/}
|
||||
|
||||
finish_test
|
100
testing/sqlite3/selectE.test
Normal file
100
testing/sqlite3/selectE.test
Normal file
|
@ -0,0 +1,100 @@
|
|||
# 2013-05-07
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for compound SELECT statements
|
||||
# that have ORDER BY clauses with collating sequences that differ
|
||||
# from the collating sequence used for comparison in the compound.
|
||||
#
|
||||
# Ticket 6709574d2a8d8b9be3a9cb1afbf4ff2de48ea4e7:
|
||||
# drh added on 2013-05-06 15:21:16:
|
||||
#
|
||||
# In the code shown below (which is intended to be run from the
|
||||
# sqlite3.exe command-line tool) the three SELECT statements should all
|
||||
# generate the same answer. But the third one does not. It is as if the
|
||||
# COLLATE clause on the ORDER BY somehow got pulled into the EXCEPT
|
||||
# operator. Note that the ".print" commands are instructions to the
|
||||
# sqlite3.exe shell program to output delimiter lines so that you can more
|
||||
# easily tell where the output of one query ends and the next query
|
||||
# begins.
|
||||
#
|
||||
# CREATE TABLE t1(a);
|
||||
# INSERT INTO t1 VALUES('abc'),('def');
|
||||
# CREATE TABLE t2(a);
|
||||
# INSERT INTO t2 VALUES('DEF');
|
||||
#
|
||||
# SELECT a FROM t1 EXCEPT SELECT a FROM t2 ORDER BY a;
|
||||
# .print -----
|
||||
# SELECT a FROM (SELECT a FROM t1 EXCEPT SELECT a FROM t2)
|
||||
# ORDER BY a COLLATE nocase;
|
||||
# .print -----
|
||||
# SELECT a FROM t1 EXCEPT SELECT a FROM t2 ORDER BY a COLLATE nocase;
|
||||
#
|
||||
# Bisecting shows that this problem was introduced in SQLite version 3.6.0
|
||||
# by check-in [8bbfa97837a74ef] on 2008-06-15.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test selectE-1.0 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES('abc'),('def'),('ghi');
|
||||
CREATE TABLE t2(a);
|
||||
INSERT INTO t2 VALUES('DEF'),('abc');
|
||||
CREATE TABLE t3(a);
|
||||
INSERT INTO t3 VALUES('def'),('jkl');
|
||||
|
||||
SELECT a FROM t1 EXCEPT SELECT a FROM t2
|
||||
ORDER BY a COLLATE nocase;
|
||||
}
|
||||
} {def ghi}
|
||||
do_test selectE-1.1 {
|
||||
db eval {
|
||||
SELECT a FROM t2 EXCEPT SELECT a FROM t3
|
||||
ORDER BY a COLLATE nocase;
|
||||
}
|
||||
} {abc DEF}
|
||||
do_test selectE-1.2 {
|
||||
db eval {
|
||||
SELECT a FROM t2 EXCEPT SELECT a FROM t3
|
||||
ORDER BY a COLLATE binary;
|
||||
}
|
||||
} {DEF abc}
|
||||
do_test selectE-1.3 {
|
||||
db eval {
|
||||
SELECT a FROM t2 EXCEPT SELECT a FROM t3
|
||||
ORDER BY a;
|
||||
}
|
||||
} {DEF abc}
|
||||
|
||||
do_test selectE-2.1 {
|
||||
db eval {
|
||||
DELETE FROM t2;
|
||||
DELETE FROM t3;
|
||||
INSERT INTO t2 VALUES('ABC'),('def'),('GHI'),('jkl');
|
||||
INSERT INTO t3 SELECT lower(a) FROM t2;
|
||||
SELECT a COLLATE nocase FROM t2 EXCEPT SELECT a FROM t3
|
||||
ORDER BY 1
|
||||
}
|
||||
} {}
|
||||
do_test selectE-2.2 {
|
||||
db eval {
|
||||
SELECT a COLLATE nocase FROM t2 EXCEPT SELECT a FROM t3
|
||||
ORDER BY 1 COLLATE binary
|
||||
}
|
||||
} {}
|
||||
|
||||
do_catchsql_test selectE-3.1 {
|
||||
SELECT 1 EXCEPT SELECT 2 ORDER BY 1 COLLATE nocase EXCEPT SELECT 3;
|
||||
} {1 {ORDER BY clause should come after EXCEPT not before}}
|
||||
|
||||
|
||||
finish_test
|
49
testing/sqlite3/selectF.test
Normal file
49
testing/sqlite3/selectF.test
Normal file
|
@ -0,0 +1,49 @@
|
|||
# 2014-03-03
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file verifies that an OP_Copy operation is used instead of OP_SCopy
|
||||
# in a compound select in a case where the source register might be changed
|
||||
# before the copy is used.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix selectF
|
||||
|
||||
do_execsql_test 1 {
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO "t1" VALUES(1,'one','I');
|
||||
CREATE TABLE t2(d, e, f);
|
||||
INSERT INTO "t2" VALUES(5,'ten','XX');
|
||||
INSERT INTO "t2" VALUES(6,NULL,NULL);
|
||||
|
||||
CREATE INDEX i1 ON t1(b, a);
|
||||
COMMIT;
|
||||
}
|
||||
|
||||
#explain_i {
|
||||
# SELECT * FROM t2
|
||||
# UNION ALL
|
||||
# SELECT * FROM t1 WHERE a<5
|
||||
# ORDER BY 2, 1
|
||||
#}
|
||||
|
||||
do_execsql_test 2 {
|
||||
SELECT * FROM t2
|
||||
UNION ALL
|
||||
SELECT * FROM t1 WHERE a<5
|
||||
ORDER BY 2, 1
|
||||
} {6 {} {} 1 one I 5 ten XX}
|
||||
|
||||
|
||||
|
||||
finish_test
|
59
testing/sqlite3/selectG.test
Normal file
59
testing/sqlite3/selectG.test
Normal file
|
@ -0,0 +1,59 @@
|
|||
# 2015-01-05
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file verifies that INSERT operations with a very large number of
|
||||
# VALUE terms works and does not hit the SQLITE_LIMIT_COMPOUND_SELECT limit.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix selectG
|
||||
|
||||
# Do an INSERT with a VALUES clause that contains 100,000 entries. Verify
|
||||
# that this insert happens quickly (in less than 10 seconds). Actually, the
|
||||
# insert will normally happen in less than 0.5 seconds on a workstation, but
|
||||
# we allow plenty of overhead for slower machines. The speed test checks
|
||||
# for an O(N*N) inefficiency that was once in the code and that would make
|
||||
# the insert run for over a minute.
|
||||
#
|
||||
do_test 100 {
|
||||
set sql "CREATE TABLE t1(x);\nINSERT INTO t1(x) VALUES"
|
||||
for {set i 1} {$i<100000} {incr i} {
|
||||
append sql "($i),"
|
||||
}
|
||||
append sql "($i);"
|
||||
set microsec [lindex [time {db eval $sql}] 0]
|
||||
db eval {
|
||||
SELECT count(x), sum(x), avg(x), $microsec<10000000 FROM t1;
|
||||
}
|
||||
} {100000 5000050000 50000.5 1}
|
||||
|
||||
# 2018-01-14. A 100K-entry VALUES clause within a scalar expression does
|
||||
# not cause processor stack overflow.
|
||||
#
|
||||
do_test 110 {
|
||||
set sql "SELECT (VALUES"
|
||||
for {set i 1} {$i<100000} {incr i} {
|
||||
append sql "($i),"
|
||||
}
|
||||
append sql "($i));"
|
||||
db eval $sql
|
||||
} {1}
|
||||
|
||||
# Only the left-most term of a multi-valued VALUES within a scalar
|
||||
# expression is evaluated.
|
||||
#
|
||||
do_test 120 {
|
||||
set n [llength [split [db eval "explain $sql"] \n]]
|
||||
expr {$n<10}
|
||||
} {1}
|
||||
|
||||
finish_test
|
145
testing/sqlite3/selectH.test
Normal file
145
testing/sqlite3/selectH.test
Normal file
|
@ -0,0 +1,145 @@
|
|||
# 2023-02-16
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for the omit-unused-subquery-column optimization.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix selectH
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
CREATE TABLE t1(
|
||||
c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
|
||||
c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
|
||||
c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
|
||||
c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
|
||||
c40, c41, c42, c43, c44, c45, c46, c47, c48, c49,
|
||||
c50, c51, c52, c53, c54, c55, c56, c57, c58, c59,
|
||||
c60, c61, c62, c63, c64, c65
|
||||
);
|
||||
INSERT INTO t1 VALUES(
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65
|
||||
);
|
||||
CREATE INDEX t1c60 ON t1(c60);
|
||||
}
|
||||
|
||||
# The SQL counter(N) function adjusts the value of the global
|
||||
# TCL variable ::selectH_cnt by the value N and returns the new
|
||||
# value. By putting calls to counter(N) as unused columns in a
|
||||
# view or subquery, we can check to see if the counter gets incremented,
|
||||
# and if not that means that the unused column was omitted.
|
||||
#
|
||||
unset -nocomplain selectH_cnt
|
||||
set selectH_cnt 0
|
||||
proc selectH_counter {amt} {
|
||||
global selectH_cnt
|
||||
incr selectH_cnt $amt
|
||||
return $selectH_cnt
|
||||
}
|
||||
db func counter selectH_counter
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
SELECT DISTINCT c44 FROM (
|
||||
SELECT c0 AS a, *, counter(1) FROM t1
|
||||
UNION ALL
|
||||
SELECT c1 AS a, *, counter(1) FROM t1
|
||||
) WHERE c60=60;
|
||||
} {44}
|
||||
do_test 1.3 {
|
||||
set ::selectH_cnt
|
||||
} {0}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
SELECT a FROM (
|
||||
SELECT counter(1) AS cnt, c15 AS a, *, c62 AS b FROM t1
|
||||
UNION ALL
|
||||
SELECT counter(1) AS cnt, c16 AS a, *, c61 AS b FROM t1
|
||||
ORDER BY b
|
||||
);
|
||||
} {16 15}
|
||||
do_test 2.2 {
|
||||
set ::selectH_cnt
|
||||
} {0}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
CREATE VIEW v1 AS
|
||||
SELECT c16 AS a, *, counter(1) AS x FROM t1
|
||||
UNION ALL
|
||||
SELECT c17 AS a, *, counter(1) AS x FROM t1
|
||||
UNION ALL
|
||||
SELECT c18 AS a, *, counter(1) AS x FROM t1
|
||||
UNION ALL
|
||||
SELECT c19 AS a, *, counter(1) AS x FROM t1;
|
||||
SELECT count(*) FROM v1 WHERE c60=60;
|
||||
} {4}
|
||||
do_test 3.2 {
|
||||
set ::selectH_cnt
|
||||
} {0}
|
||||
do_execsql_test 3.3 {
|
||||
SELECT count(a) FROM v1 WHERE c60=60;
|
||||
} {4}
|
||||
do_execsql_test 3.4 {
|
||||
SELECT a FROM v1 WHERE c60=60;
|
||||
} {16 17 18 19}
|
||||
do_test 3.5 {
|
||||
set ::selectH_cnt
|
||||
} {0}
|
||||
do_execsql_test 3.6 {
|
||||
SELECT x FROM v1 WHERE c60=60;
|
||||
} {1 2 3 4}
|
||||
do_test 3.7 {
|
||||
set ::selectH_cnt
|
||||
} {4}
|
||||
|
||||
# 2023-02-25 dbsqlfuzz bf1d3ed6e0e0dd8766027797d43db40c776d2b15
|
||||
#
|
||||
do_execsql_test 4.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
|
||||
SELECT 1 FROM (SELECT DISTINCT name COLLATE rtrim FROM sqlite_schema
|
||||
UNION ALL SELECT a FROM t1);
|
||||
} {1 1}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
SELECT DISTINCT name COLLATE rtrim FROM sqlite_schema
|
||||
UNION ALL
|
||||
SELECT a FROM t1
|
||||
} {v1 t1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# forum post https://sqlite.org/forum/forumpost/b83c7b2168
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1 (val1);
|
||||
INSERT INTO t1 VALUES(4);
|
||||
INSERT INTO t1 VALUES(5);
|
||||
CREATE TABLE t2 (val2);
|
||||
}
|
||||
do_execsql_test 5.1 {
|
||||
SELECT DISTINCT val1 FROM t1 UNION ALL SELECT val2 FROM t2;
|
||||
} {
|
||||
4 5
|
||||
}
|
||||
do_execsql_test 5.2 {
|
||||
SELECT count(1234) FROM (
|
||||
SELECT DISTINCT val1 FROM t1 UNION ALL SELECT val2 FROM t2
|
||||
)
|
||||
} {2}
|
||||
|
||||
finish_test
|
Loading…
Add table
Add a link
Reference in a new issue