xref: /onnv-gate/usr/src/lib/libsqlite/test/null.test (revision 4520:7dbeadedd7fe)
1*4520Snw141292
2*4520Snw141292#pragma ident	"%Z%%M%	%I%	%E% SMI"
3*4520Snw141292
4*4520Snw141292# 2001 September 15
5*4520Snw141292#
6*4520Snw141292# The author disclaims copyright to this source code.  In place of
7*4520Snw141292# a legal notice, here is a blessing:
8*4520Snw141292#
9*4520Snw141292#    May you do good and not evil.
10*4520Snw141292#    May you find forgiveness for yourself and forgive others.
11*4520Snw141292#    May you share freely, never taking more than you give.
12*4520Snw141292#
13*4520Snw141292#***********************************************************************
14*4520Snw141292# This file implements regression tests for SQLite library.
15*4520Snw141292#
16*4520Snw141292# This file implements tests for proper treatment of the special
17*4520Snw141292# value NULL.
18*4520Snw141292#
19*4520Snw141292
20*4520Snw141292set testdir [file dirname $argv0]
21*4520Snw141292source $testdir/tester.tcl
22*4520Snw141292
23*4520Snw141292# Create a table and some data to work with.
24*4520Snw141292#
25*4520Snw141292do_test null-1.0 {
26*4520Snw141292  execsql {
27*4520Snw141292    begin;
28*4520Snw141292    create table t1(a,b,c);
29*4520Snw141292    insert into t1 values(1,0,0);
30*4520Snw141292    insert into t1 values(2,0,1);
31*4520Snw141292    insert into t1 values(3,1,0);
32*4520Snw141292    insert into t1 values(4,1,1);
33*4520Snw141292    insert into t1 values(5,null,0);
34*4520Snw141292    insert into t1 values(6,null,1);
35*4520Snw141292    insert into t1 values(7,null,null);
36*4520Snw141292    commit;
37*4520Snw141292    select * from t1;
38*4520Snw141292  }
39*4520Snw141292} {1 0 0 2 0 1 3 1 0 4 1 1 5 {} 0 6 {} 1 7 {} {}}
40*4520Snw141292
41*4520Snw141292# Check for how arithmetic expressions handle NULL
42*4520Snw141292#
43*4520Snw141292do_test null-1.1 {
44*4520Snw141292  execsql {
45*4520Snw141292    select ifnull(a+b,99) from t1;
46*4520Snw141292  }
47*4520Snw141292} {1 2 4 5 99 99 99}
48*4520Snw141292do_test null-1.2 {
49*4520Snw141292  execsql {
50*4520Snw141292    select ifnull(b*c,99) from t1;
51*4520Snw141292  }
52*4520Snw141292} {0 0 0 1 99 99 99}
53*4520Snw141292
54*4520Snw141292# Check to see how the CASE expression handles NULL values.  The
55*4520Snw141292# first WHEN for which the test expression is TRUE is selected.
56*4520Snw141292# FALSE and UNKNOWN test expressions are skipped.
57*4520Snw141292#
58*4520Snw141292do_test null-2.1 {
59*4520Snw141292  execsql {
60*4520Snw141292    select ifnull(case when b<>0 then 1 else 0 end, 99) from t1;
61*4520Snw141292  }
62*4520Snw141292} {0 0 1 1 0 0 0}
63*4520Snw141292do_test null-2.2 {
64*4520Snw141292  execsql {
65*4520Snw141292    select ifnull(case when not b<>0 then 1 else 0 end, 99) from t1;
66*4520Snw141292  }
67*4520Snw141292} {1 1 0 0 0 0 0}
68*4520Snw141292do_test null-2.3 {
69*4520Snw141292  execsql {
70*4520Snw141292    select ifnull(case when b<>0 and c<>0 then 1 else 0 end, 99) from t1;
71*4520Snw141292  }
72*4520Snw141292} {0 0 0 1 0 0 0}
73*4520Snw141292do_test null-2.4 {
74*4520Snw141292  execsql {
75*4520Snw141292    select ifnull(case when not (b<>0 and c<>0) then 1 else 0 end, 99) from t1;
76*4520Snw141292  }
77*4520Snw141292} {1 1 1 0 1 0 0}
78*4520Snw141292do_test null-2.5 {
79*4520Snw141292  execsql {
80*4520Snw141292    select ifnull(case when b<>0 or c<>0 then 1 else 0 end, 99) from t1;
81*4520Snw141292  }
82*4520Snw141292} {0 1 1 1 0 1 0}
83*4520Snw141292do_test null-2.6 {
84*4520Snw141292  execsql {
85*4520Snw141292    select ifnull(case when not (b<>0 or c<>0) then 1 else 0 end, 99) from t1;
86*4520Snw141292  }
87*4520Snw141292} {1 0 0 0 0 0 0}
88*4520Snw141292do_test null-2.7 {
89*4520Snw141292  execsql {
90*4520Snw141292    select ifnull(case b when c then 1 else 0 end, 99) from t1;
91*4520Snw141292  }
92*4520Snw141292} {1 0 0 1 0 0 0}
93*4520Snw141292do_test null-2.8 {
94*4520Snw141292  execsql {
95*4520Snw141292    select ifnull(case c when b then 1 else 0 end, 99) from t1;
96*4520Snw141292  }
97*4520Snw141292} {1 0 0 1 0 0 0}
98*4520Snw141292
99*4520Snw141292# Check to see that NULL values are ignored in aggregate functions.
100*4520Snw141292# (except for min().)
101*4520Snw141292#
102*4520Snw141292do_test null-3.1 {
103*4520Snw141292  execsql {
104*4520Snw141292    select count(*), count(b), count(c), sum(b), sum(c),
105*4520Snw141292           avg(b), avg(c), min(b), max(b) from t1;
106*4520Snw141292  }
107*4520Snw141292} {7 4 6 2 3 0.5 0.5 0 1}
108*4520Snw141292
109*4520Snw141292# Check to see how WHERE clauses handle NULL values.  A NULL value
110*4520Snw141292# is the same as UNKNOWN.  The WHERE clause should only select those
111*4520Snw141292# rows that are TRUE.  FALSE and UNKNOWN rows are rejected.
112*4520Snw141292#
113*4520Snw141292do_test null-4.1 {
114*4520Snw141292  execsql {
115*4520Snw141292    select a from t1 where b<10
116*4520Snw141292  }
117*4520Snw141292} {1 2 3 4}
118*4520Snw141292do_test null-4.2 {
119*4520Snw141292  execsql {
120*4520Snw141292    select a from t1 where not b>10
121*4520Snw141292  }
122*4520Snw141292} {1 2 3 4}
123*4520Snw141292do_test null-4.3 {
124*4520Snw141292  execsql {
125*4520Snw141292    select a from t1 where b<10 or c=1;
126*4520Snw141292  }
127*4520Snw141292} {1 2 3 4 6}
128*4520Snw141292do_test null-4.4 {
129*4520Snw141292  execsql {
130*4520Snw141292    select a from t1 where b<10 and c=1;
131*4520Snw141292  }
132*4520Snw141292} {2 4}
133*4520Snw141292do_test null-4.5 {
134*4520Snw141292  execsql {
135*4520Snw141292    select a from t1 where not (b<10 and c=1);
136*4520Snw141292  }
137*4520Snw141292} {1 3 5}
138*4520Snw141292
139*4520Snw141292# The DISTINCT keyword on a SELECT statement should treat NULL values
140*4520Snw141292# as distinct
141*4520Snw141292#
142*4520Snw141292do_test null-5.1 {
143*4520Snw141292  execsql {
144*4520Snw141292    select distinct b from t1 order by b;
145*4520Snw141292  }
146*4520Snw141292} {{} 0 1}
147*4520Snw141292
148*4520Snw141292# A UNION to two queries should treat NULL values
149*4520Snw141292# as distinct
150*4520Snw141292#
151*4520Snw141292do_test null-6.1 {
152*4520Snw141292  execsql {
153*4520Snw141292    select b from t1 union select c from t1 order by c;
154*4520Snw141292  }
155*4520Snw141292} {{} 0 1}
156*4520Snw141292
157*4520Snw141292# The UNIQUE constraint only applies to non-null values
158*4520Snw141292#
159*4520Snw141292do_test null-7.1 {
160*4520Snw141292  execsql {
161*4520Snw141292    create table t2(a, b unique on conflict ignore);
162*4520Snw141292    insert into t2 values(1,1);
163*4520Snw141292    insert into t2 values(2,null);
164*4520Snw141292    insert into t2 values(3,null);
165*4520Snw141292    insert into t2 values(4,1);
166*4520Snw141292    select a from t2;
167*4520Snw141292  }
168*4520Snw141292} {1 2 3}
169*4520Snw141292do_test null-7.2 {
170*4520Snw141292  execsql {
171*4520Snw141292    create table t3(a, b, c, unique(b,c) on conflict ignore);
172*4520Snw141292    insert into t3 values(1,1,1);
173*4520Snw141292    insert into t3 values(2,null,1);
174*4520Snw141292    insert into t3 values(3,null,1);
175*4520Snw141292    insert into t3 values(4,1,1);
176*4520Snw141292    select a from t3;
177*4520Snw141292  }
178*4520Snw141292} {1 2 3}
179*4520Snw141292
180*4520Snw141292# Ticket #461 - Make sure nulls are handled correctly when doing a
181*4520Snw141292# lookup using an index.
182*4520Snw141292#
183*4520Snw141292do_test null-8.1 {
184*4520Snw141292  execsql {
185*4520Snw141292    CREATE TABLE t4(x,y);
186*4520Snw141292    INSERT INTO t4 VALUES(1,11);
187*4520Snw141292    INSERT INTO t4 VALUES(2,NULL);
188*4520Snw141292    SELECT x FROM t4 WHERE y=NULL;
189*4520Snw141292  }
190*4520Snw141292} {}
191*4520Snw141292do_test null-8.2 {
192*4520Snw141292  execsql {
193*4520Snw141292    SELECT x FROM t4 WHERE y IN (33,NULL);
194*4520Snw141292  }
195*4520Snw141292} {}
196*4520Snw141292do_test null-8.3 {
197*4520Snw141292  execsql {
198*4520Snw141292    SELECT x FROM t4 WHERE y<33 ORDER BY x;
199*4520Snw141292  }
200*4520Snw141292} {1}
201*4520Snw141292do_test null-8.4 {
202*4520Snw141292  execsql {
203*4520Snw141292    SELECT x FROM t4 WHERE y>6 ORDER BY x;
204*4520Snw141292  }
205*4520Snw141292} {1}
206*4520Snw141292do_test null-8.5 {
207*4520Snw141292  execsql {
208*4520Snw141292    SELECT x FROM t4 WHERE y!=33 ORDER BY x;
209*4520Snw141292  }
210*4520Snw141292} {1}
211*4520Snw141292do_test null-8.11 {
212*4520Snw141292  execsql {
213*4520Snw141292    CREATE INDEX t4i1 ON t4(y);
214*4520Snw141292    SELECT x FROM t4 WHERE y=NULL;
215*4520Snw141292  }
216*4520Snw141292} {}
217*4520Snw141292do_test null-8.12 {
218*4520Snw141292  execsql {
219*4520Snw141292    SELECT x FROM t4 WHERE y IN (33,NULL);
220*4520Snw141292  }
221*4520Snw141292} {}
222*4520Snw141292do_test null-8.13 {
223*4520Snw141292  execsql {
224*4520Snw141292    SELECT x FROM t4 WHERE y<33 ORDER BY x;
225*4520Snw141292  }
226*4520Snw141292} {1}
227*4520Snw141292do_test null-8.14 {
228*4520Snw141292  execsql {
229*4520Snw141292    SELECT x FROM t4 WHERE y>6 ORDER BY x;
230*4520Snw141292  }
231*4520Snw141292} {1}
232*4520Snw141292do_test null-8.15 {
233*4520Snw141292  execsql {
234*4520Snw141292    SELECT x FROM t4 WHERE y!=33 ORDER BY x;
235*4520Snw141292  }
236*4520Snw141292} {1}
237*4520Snw141292
238*4520Snw141292
239*4520Snw141292
240*4520Snw141292finish_test
241