3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the SELECT statement.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set ::testprefix rowvalue2
20 CREATE TABLE t1(a, b, c);
21 INSERT INTO t1 VALUES(0, 0, 0);
22 INSERT INTO t1 VALUES(0, 1, 1);
23 INSERT INTO t1 VALUES(1, 0, 2);
24 INSERT INTO t1 VALUES(1, 1, 3);
26 CREATE INDEX i1 ON t1(a, b);
29 do_execsql_test 1.1.1 { SELECT c FROM t1 WHERE (a, b) >= (1, 0) } {2 3}
30 do_execsql_test 1.1.2 { SELECT c FROM t1 WHERE (a, b) > (1, 0) } {3}
32 #-------------------------------------------------------------------------
34 do_execsql_test 2.0.1 {
35 CREATE TABLE t2(a INTEGER, b INTEGER, c INTEGER, d INTEGER);
36 CREATE INDEX i2 ON t2(a, b, c);
42 execsql { INSERT INTO t2 VALUES($a, $b, $c, $c + $b*4 + $a*16); }
47 SELECT d FROM t2 WHERE (a, b) > (2, 2);
48 } [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>2) }]
51 SELECT d FROM t2 WHERE (a, b) >= (2, 2);
52 } [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>=2) }]
55 SELECT d FROM t2 WHERE a=1 AND (b, c) >= (1, 2);
56 } [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>=2)) }]
59 SELECT d FROM t2 WHERE a=1 AND (b, c) > (1, 2);
60 } [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>2)) }]
62 #-------------------------------------------------------------------------
65 airfare airfield airfields airflow airfoil
66 airfoils airframe airframes airily airing
67 airings airless airlift airlifts airline
68 airliner airlines airlock airlocks airmail
69 airmails airman airmen airplane airplanes
71 arraignment arraignments arraigns arrange arranged
72 arrangement arrangements arranger arrangers arranges
73 arranging arrant array arrayed arrays
74 arrears arrest arrested arrester arresters
75 arresting arrestingly arrestor arrestors arrests
77 edifices edit edited editing edition
78 editions editor editorial editorially editorials
79 editors edits educable educate educated
80 educates educating education educational educationally
81 educations educator educators eel eelgrass
85 execsql { CREATE TABLE t3(a, b, c, w); }
87 set a [string range $w 0 2]
88 set b [string range $w 3 5]
89 set c [string range $w 6 end]
90 execsql { INSERT INTO t3 VALUES($a, $b, $c, $w) }
97 IDX2 { CREATE INDEX i3 ON t3(a, b, c); }
98 IDX3 { CREATE INDEX i3 ON t3(a, b); }
99 IDX4 { CREATE INDEX i3 ON t3(a); }
101 execsql { DROP INDEX IF EXISTS i3 }
105 set a [string range $w 0 2]
106 set b [string range $w 3 5]
107 set c [string range $w 6 end]
109 foreach op [list > >= < <= == IS] {
110 do_execsql_test 3.1.$tn.$w.$op [subst -novar {
111 SELECT rowid FROM t3 WHERE (a, b, c) [set op] ($a, $b, $c)
113 }] [db eval [subst -novar {
114 SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid
117 do_execsql_test 3.1.$tn.$w.$op.subselect [subst -novar {
118 SELECT rowid FROM t3 WHERE (a, b, c) [set op] (
119 SELECT a, b, c FROM t3 WHERE w = $w
122 }] [db eval [subst -novar {
123 SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid
130 #-------------------------------------------------------------------------
133 do_execsql_test 4.0 {
134 CREATE TABLE t4(a, b, c);
135 INSERT INTO t4 VALUES(NULL, NULL, NULL);
136 INSERT INTO t4 VALUES(NULL, NULL, 0);
137 INSERT INTO t4 VALUES(NULL, NULL, 1);
138 INSERT INTO t4 VALUES(NULL, 0, NULL);
139 INSERT INTO t4 VALUES(NULL, 0, 0);
140 INSERT INTO t4 VALUES(NULL, 0, 1);
141 INSERT INTO t4 VALUES(NULL, 1, NULL);
142 INSERT INTO t4 VALUES(NULL, 1, 0);
143 INSERT INTO t4 VALUES(NULL, 1, 1);
145 INSERT INTO t4 VALUES( 0, NULL, NULL);
146 INSERT INTO t4 VALUES( 0, NULL, 0);
147 INSERT INTO t4 VALUES( 0, NULL, 1);
148 INSERT INTO t4 VALUES( 0, 0, NULL);
149 INSERT INTO t4 VALUES( 0, 0, 0);
150 INSERT INTO t4 VALUES( 0, 0, 1);
151 INSERT INTO t4 VALUES( 0, 1, NULL);
152 INSERT INTO t4 VALUES( 0, 1, 0);
153 INSERT INTO t4 VALUES( 0, 1, 1);
155 INSERT INTO t4 VALUES( 1, NULL, NULL);
156 INSERT INTO t4 VALUES( 1, NULL, 0);
157 INSERT INTO t4 VALUES( 1, NULL, 1);
158 INSERT INTO t4 VALUES( 1, 0, NULL);
159 INSERT INTO t4 VALUES( 1, 0, 0);
160 INSERT INTO t4 VALUES( 1, 0, 1);
161 INSERT INTO t4 VALUES( 1, 1, NULL);
162 INSERT INTO t4 VALUES( 1, 1, 0);
163 INSERT INTO t4 VALUES( 1, 1, 1);
166 proc make_expr1 {cList vList op} {
167 return "([join $cList ,]) $op ([join $vList ,])"
170 proc make_expr3 {cList vList op} {
171 set n [llength $cList]
174 foreach c [lrange $cList 0 end-1] v [lrange $vList 0 end-1] {
175 lappend aList "$c == $v"
177 lappend aList "[lindex $cList end] $op [lindex $vList end]"
179 return "([join $aList { AND }])"
182 proc make_expr2 {cList vList op} {
188 foreach c $cList v $vList { lappend aList "($c $op $v)" }
189 set ret [join $aList " AND "]
194 for {set i 0} {$i < [llength $cList]} {incr i} {
195 lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $op]
197 set ret [join $oList " OR "]
201 set o2 [string range $op 0 0]
203 for {set i 0} {$i < [llength $cList]-1} {incr i} {
204 lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $o2]
206 lappend oList [make_expr3 $cList $vList $op]
207 set ret [join $oList " OR "]
212 error "Unknown op: $op"
221 IDX2 { CREATE INDEX i4 ON t4(a, b, c); }
222 IDX3 { CREATE INDEX i4 ON t4(a, b); }
223 IDX4 { CREATE INDEX i4 ON t4(a); }
225 execsql { DROP INDEX IF EXISTS i4 }
228 foreach {tn2 vector} {
238 foreach op { IS == < <= > >= } {
239 set e1 [make_expr1 {a b c} $vector $op]
240 set e2 [make_expr2 {a b c} $vector $op]
242 do_execsql_test 4.$tn.$tn2.$op \
243 "SELECT rowid FROM t4 WHERE $e2 ORDER BY +rowid" [
244 db eval "SELECT rowid FROM t4 WHERE $e1 ORDER BY +rowid"
250 do_execsql_test 5.0 {
251 CREATE TABLE r1(a TEXT, iB TEXT);
252 CREATE TABLE r2(x TEXT, zY INTEGER);
253 CREATE INDEX r1ab ON r1(a, iB);
255 INSERT INTO r1 VALUES(35, 35);
256 INSERT INTO r2 VALUES(35, 36);
257 INSERT INTO r2 VALUES(35, 4);
258 INSERT INTO r2 VALUES(35, 35);
261 foreach {tn lhs rhs} {
268 foreach op { IS == < <= > >= } {
269 set e1 [make_expr1 $lhs $rhs $op]
270 set e2 [make_expr2 $lhs $rhs $op]
271 do_execsql_test 5.$tn.$op \
272 "SELECT * FROM r1, r2 WHERE $e2 ORDER BY iB" [db eval \
273 "SELECT * FROM r1, r2 WHERE $e1 ORDER BY iB"