aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl
diff options
context:
space:
mode:
authordan miller2007-10-20 02:49:29 +0000
committerdan miller2007-10-20 02:49:29 +0000
commite36d23a85ebff914d74bb541558c2b6082b78edb (patch)
tree54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl
parent* Fixed an issue whereby avatar chat distances were being calculated against ... (diff)
downloadopensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl329
1 files changed, 329 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl b/libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl
new file mode 100644
index 0000000..9091389
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/www/nulls.tcl
@@ -0,0 +1,329 @@
1#
2# Run this script to generated a nulls.html output file
3#
4set rcsid {$Id: nulls.tcl,v 1.8 2004/10/10 17:24:55 drh Exp $}
5source common.tcl
6header {NULL Handling in SQLite}
7puts {
8<h2>NULL Handling in SQLite Versus Other Database Engines</h2>
9
10<p>
11The goal is
12to make SQLite handle NULLs in a standards-compliant way.
13But the descriptions in the SQL standards on how to handle
14NULLs seem ambiguous.
15It is not clear from the standards documents exactly how NULLs should
16be handled in all circumstances.
17</p>
18
19<p>
20So instead of going by the standards documents, various popular
21SQL engines were tested to see how they handle NULLs. The idea
22was to make SQLite work like all the other engines.
23A SQL test script was developed and run by volunteers on various
24SQL RDBMSes and the results of those tests were used to deduce
25how each engine processed NULL values.
26The original tests were run in May of 2002.
27A copy of the test script is found at the end of this document.
28</p>
29
30<p>
31SQLite was originally coded in such a way that the answer to
32all questions in the chart below would be "Yes". But the
33experiments run on other SQL engines showed that none of them
34worked this way. So SQLite was modified to work the same as
35Oracle, PostgreSQL, and DB2. This involved making NULLs
36indistinct for the purposes of the SELECT DISTINCT statement and
37for the UNION operator in a SELECT. NULLs are still distinct
38in a UNIQUE column. This seems somewhat arbitrary, but the desire
39to be compatible with other engines outweighted that objection.
40</p>
41
42<p>
43It is possible to make SQLite treat NULLs as distinct for the
44purposes of the SELECT DISTINCT and UNION. To do so, one should
45change the value of the NULL_ALWAYS_DISTINCT #define in the
46<tt>sqliteInt.h</tt> source file and recompile.
47</p>
48
49<blockquote>
50<p>
51<i>Update 2003-07-13:</i>
52Since this document was originally written some of the database engines
53tested have been updated and users have been kind enough to send in
54corrections to the chart below. The original data showed a wide variety
55of behaviors, but over time the range of behaviors has converged toward
56the PostgreSQL/Oracle model. The only significant difference
57is that Informix and MS-SQL both threat NULLs as
58indistinct in a UNIQUE column.
59</p>
60
61<p>
62The fact that NULLs are distinct for UNIQUE columns but are indistinct for
63SELECT DISTINCT and UNION continues to be puzzling. It seems that NULLs
64should be either distinct everywhere or nowhere. And the SQL standards
65documents suggest that NULLs should be distinct everywhere. Yet as of
66this writing, no SQL engine tested treats NULLs as distinct in a SELECT
67DISTINCT statement or in a UNION.
68</p>
69</blockquote>
70
71
72<p>
73The following table shows the results of the NULL handling experiments.
74</p>
75
76<table border=1 cellpadding=3 width="100%">
77<tr><th>&nbsp&nbsp;</th>
78<th>SQLite</th>
79<th>PostgreSQL</th>
80<th>Oracle</th>
81<th>Informix</th>
82<th>DB2</th>
83<th>MS-SQL</th>
84<th>OCELOT</th>
85</tr>
86
87<tr><td>Adding anything to null gives null</td>
88<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
89<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
90<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
91<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
92<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
93<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
94<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
95</tr>
96<tr><td>Multiplying null by zero gives null</td>
97<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
98<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
99<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
100<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
101<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
102<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
103<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
104</tr>
105<tr><td>nulls are distinct in a UNIQUE column</td>
106<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
107<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
108<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
109<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
110<td valign="center" align="center" bgcolor="#aaaad2">(Note 4)</td>
111<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
112<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
113</tr>
114<tr><td>nulls are distinct in SELECT DISTINCT</td>
115<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
116<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
117<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
118<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
119<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
120<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
121<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
122</tr>
123<tr><td>nulls are distinct in a UNION</td>
124<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
125<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
126<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
127<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
128<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
129<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
130<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
131</tr>
132<tr><td>"CASE WHEN null THEN 1 ELSE 0 END" is 0?</td>
133<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
134<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
135<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
136<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
137<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
138<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
139<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
140</tr>
141<tr><td>"null OR true" is true</td>
142<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
143<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
144<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
145<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
146<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
147<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
148<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
149</tr>
150<tr><td>"not (null AND false)" is true</td>
151<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
152<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
153<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
154<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
155<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
156<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
157<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
158</tr>
159</table>
160
161<table border=1 cellpadding=3 width="100%">
162<tr><th>&nbsp&nbsp;</th>
163<th>MySQL<br>3.23.41</th>
164<th>MySQL<br>4.0.16</th>
165<th>Firebird</th>
166<th>SQL<br>Anywhere</th>
167<th>Borland<br>Interbase</th>
168</tr>
169
170<tr><td>Adding anything to null gives null</td>
171<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
172<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
173<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
174<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
175<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
176</tr>
177<tr><td>Multiplying null by zero gives null</td>
178<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
179<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
180<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
181<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
182<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
183</tr>
184<tr><td>nulls are distinct in a UNIQUE column</td>
185<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
186<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
187<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
188<td valign="center" align="center" bgcolor="#aaaad2">(Note 4)</td>
189<td valign="center" align="center" bgcolor="#aaaad2">(Note 4)</td>
190</tr>
191<tr><td>nulls are distinct in SELECT DISTINCT</td>
192<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
193<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
194<td valign="center" align="center" bgcolor="#c7a9a9">No (Note 1)</td>
195<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
196<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
197</tr>
198<tr><td>nulls are distinct in a UNION</td>
199<td valign="center" align="center" bgcolor="#aaaad2">(Note 3)</td>
200<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
201<td valign="center" align="center" bgcolor="#c7a9a9">No (Note 1)</td>
202<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
203<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
204</tr>
205<tr><td>"CASE WHEN null THEN 1 ELSE 0 END" is 0?</td>
206<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
207<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
208<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
209<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
210<td valign="center" align="center" bgcolor="#aaaad2">(Note 5)</td>
211</tr>
212<tr><td>"null OR true" is true</td>
213<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
214<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
215<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
216<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
217<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
218</tr>
219<tr><td>"not (null AND false)" is true</td>
220<td valign="center" align="center" bgcolor="#c7a9a9">No</td>
221<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
222<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
223<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
224<td valign="center" align="center" bgcolor="#a9c7a9">Yes</td>
225</tr>
226</table>
227
228<table border=0 align="right" cellpadding=0 cellspacing=0>
229<tr>
230<td valign="top" rowspan=5>Notes:&nbsp;&nbsp;</td>
231<td>1.&nbsp;</td>
232<td>Older versions of firebird omits all NULLs from SELECT DISTINCT
233and from UNION.</td>
234</tr>
235<tr><td>2.&nbsp;</td>
236<td>Test data unavailable.</td>
237</tr>
238<tr><td>3.&nbsp;</td>
239<td>MySQL version 3.23.41 does not support UNION.</td>
240</tr>
241<tr><td>4.&nbsp;</td>
242<td>DB2, SQL Anywhere, and Borland Interbase
243do not allow NULLs in a UNIQUE column.</td>
244</tr>
245<tr><td>5.&nbsp;</td>
246<td>Borland Interbase does not support CASE expressions.</td>
247</tr>
248</table>
249<br clear="both">
250
251<p>&nbsp;</p>
252<p>
253The following script was used to gather information for the table
254above.
255</p>
256
257<pre>
258-- I have about decided that SQL's treatment of NULLs is capricious and cannot be
259-- deduced by logic. It must be discovered by experiment. To that end, I have
260-- prepared the following script to test how various SQL databases deal with NULL.
261-- My aim is to use the information gather from this script to make SQLite as much
262-- like other databases as possible.
263--
264-- If you could please run this script in your database engine and mail the results
265-- to me at drh@hwaci.com, that will be a big help. Please be sure to identify the
266-- database engine you use for this test. Thanks.
267--
268-- If you have to change anything to get this script to run with your database
269-- engine, please send your revised script together with your results.
270--
271
272-- Create a test table with data
273create table t1(a int, b int, c int);
274insert into t1 values(1,0,0);
275insert into t1 values(2,0,1);
276insert into t1 values(3,1,0);
277insert into t1 values(4,1,1);
278insert into t1 values(5,null,0);
279insert into t1 values(6,null,1);
280insert into t1 values(7,null,null);
281
282-- Check to see what CASE does with NULLs in its test expressions
283select a, case when b<>0 then 1 else 0 end from t1;
284select a+10, case when not b<>0 then 1 else 0 end from t1;
285select a+20, case when b<>0 and c<>0 then 1 else 0 end from t1;
286select a+30, case when not (b<>0 and c<>0) then 1 else 0 end from t1;
287select a+40, case when b<>0 or c<>0 then 1 else 0 end from t1;
288select a+50, case when not (b<>0 or c<>0) then 1 else 0 end from t1;
289select a+60, case b when c then 1 else 0 end from t1;
290select a+70, case c when b then 1 else 0 end from t1;
291
292-- What happens when you multiple a NULL by zero?
293select a+80, b*0 from t1;
294select a+90, b*c from t1;
295
296-- What happens to NULL for other operators?
297select a+100, b+c from t1;
298
299-- Test the treatment of aggregate operators
300select count(*), count(b), sum(b), avg(b), min(b), max(b) from t1;
301
302-- Check the behavior of NULLs in WHERE clauses
303select a+110 from t1 where b<10;
304select a+120 from t1 where not b>10;
305select a+130 from t1 where b<10 OR c=1;
306select a+140 from t1 where b<10 AND c=1;
307select a+150 from t1 where not (b<10 AND c=1);
308select a+160 from t1 where not (c=1 AND b<10);
309
310-- Check the behavior of NULLs in a DISTINCT query
311select distinct b from t1;
312
313-- Check the behavior of NULLs in a UNION query
314select b from t1 union select b from t1;
315
316-- Create a new table with a unique column. Check to see if NULLs are considered
317-- to be distinct.
318create table t2(a int, b int unique);
319insert into t2 values(1,1);
320insert into t2 values(2,null);
321insert into t2 values(3,null);
322select * from t2;
323
324drop table t1;
325drop table t2;
326</pre>
327}
328
329footer $rcsid