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 #***********************************************************************
14 # Make sure IEEE floating point NaN values are handled properly.
15 # SQLite should always convert NaN into NULL.
17 # Also verify that the decimal to IEEE754 binary conversion routines
18 # correctly generate 0.0, +Inf, and -Inf as appropriate for numbers
21 # $Id: nan.test,v 1.5 2008/09/18 11:30:13 danielk1977 Exp $
24 set testdir [file dirname $argv0]
25 source $testdir/tester.tcl
27 # Do not use a codec for tests in this file, as the database file is
28 # manipulated directly using tcl scripts (using the [hexio_write] command).
34 PRAGMA auto_vacuum=OFF;
35 PRAGMA page_size=1024;
36 CREATE TABLE t1(x FLOAT);
38 set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
39 sqlite3_bind_double $::STMT 1 NaN
42 db eval {SELECT x, typeof(x) FROM t1}
44 if {$tcl_platform(platform) != "symbian"} {
45 do_realnum_test nan-1.1.2 {
46 sqlite3_bind_double $::STMT 1 +Inf
49 db eval {SELECT x, typeof(x) FROM t1}
51 do_realnum_test nan-1.1.3 {
52 sqlite3_bind_double $::STMT 1 -Inf
55 db eval {SELECT x, typeof(x) FROM t1}
56 } {{} null inf real -inf real}
57 do_realnum_test nan-1.1.4 {
58 sqlite3_bind_double $::STMT 1 -NaN
61 db eval {SELECT x, typeof(x) FROM t1}
62 } {{} null inf real -inf real {} null}
63 do_realnum_test nan-1.1.5 {
64 sqlite3_bind_double $::STMT 1 NaN0
67 db eval {SELECT x, typeof(x) FROM t1}
68 } {{} null inf real -inf real {} null {} null}
69 do_realnum_test nan-1.1.6 {
70 sqlite3_bind_double $::STMT 1 -NaN0
73 db eval {SELECT x, typeof(x) FROM t1}
74 } {{} null inf real -inf real {} null {} null {} null}
78 SELECT x, typeof(x) FROM t1;
80 } {{} null {} null {} null {} null {} null {} null}
83 # The following block of tests, nan-1.2.*, are the same as the nan-1.1.*
84 # tests above, except that the SELECT queries used to validate data
85 # convert floating point values to text internally before returning them
86 # to Tcl. This allows the tests to be run on platforms where Tcl has
87 # problems converting "inf" and "-inf" from floating point to text format.
88 # It also tests the internal float->text conversion routines a bit.
94 sqlite3_bind_double $::STMT 1 NaN
97 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
100 sqlite3_bind_double $::STMT 1 +Inf
102 sqlite3_reset $::STMT
103 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
106 sqlite3_bind_double $::STMT 1 -Inf
108 sqlite3_reset $::STMT
109 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
110 } {{} null Inf real -Inf real}
112 sqlite3_bind_double $::STMT 1 -NaN
114 sqlite3_reset $::STMT
115 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
116 } {{} null Inf real -Inf real {} null}
118 sqlite3_bind_double $::STMT 1 NaN0
120 sqlite3_reset $::STMT
121 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
122 } {{} null Inf real -Inf real {} null {} null}
124 sqlite3_bind_double $::STMT 1 -NaN0
126 sqlite3_reset $::STMT
127 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
128 } {{} null Inf real -Inf real {} null {} null {} null}
132 SELECT CAST(x AS text), typeof(x) FROM t1;
134 } {{} null {} null {} null {} null {} null {} null}
140 sqlite3_bind_double $::STMT 1 NaN
142 sqlite3_reset $::STMT
143 db eval {SELECT x, typeof(x) FROM t1}
145 sqlite3_finalize $::STMT
147 # SQLite always converts NaN into NULL so it is not possible to write
148 # a NaN value into the database file using SQLite. The following series
149 # of tests writes a normal floating point value (0.5) into the database,
150 # then writes directly into the database file to change the 0.5 into NaN.
151 # Then it reads the value of the database to verify it is converted into
154 if {![nonzero_reserved_bytes]} {
158 INSERT INTO t1 VALUES(0.5);
159 PRAGMA auto_vacuum=OFF;
160 PRAGMA page_size=1024;
163 hexio_read test.db 2040 8
167 SELECT x, typeof(x) FROM t1
172 hexio_write test.db 2040 FFF8000000000000
174 db eval {SELECT x, typeof(x) FROM t1}
178 hexio_write test.db 2040 7FF8000000000000
180 db eval {SELECT x, typeof(x) FROM t1}
184 hexio_write test.db 2040 FFFFFFFFFFFFFFFF
186 db eval {SELECT x, typeof(x) FROM t1}
190 hexio_write test.db 2040 7FFFFFFFFFFFFFFF
192 db eval {SELECT x, typeof(x) FROM t1}
196 # Verify that the sqlite3AtoF routine is able to handle extreme
200 db eval {DELETE FROM t1}
201 db eval "INSERT INTO t1 VALUES([string repeat 9 307].0)"
202 db eval {SELECT x, typeof(x) FROM t1}
205 db eval {DELETE FROM t1}
206 db eval "INSERT INTO t1 VALUES([string repeat 9 308].0)"
207 db eval {SELECT x, typeof(x) FROM t1}
210 db eval {DELETE FROM t1}
211 db eval "INSERT INTO t1 VALUES(-[string repeat 9 307].0)"
212 db eval {SELECT x, typeof(x) FROM t1}
215 db eval {DELETE FROM t1}
216 db eval "INSERT INTO t1 VALUES(-[string repeat 9 308].0)"
217 db eval {SELECT x, typeof(x) FROM t1}
220 db eval {DELETE FROM t1}
221 set big -[string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
222 db eval "INSERT INTO t1 VALUES($big)"
223 db eval {SELECT x, typeof(x) FROM t1}
226 db eval {DELETE FROM t1}
227 set big [string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
228 db eval "INSERT INTO t1 VALUES($big)"
229 db eval {SELECT x, typeof(x) FROM t1}
232 if {$tcl_platform(platform) != "symbian"} {
233 # Do not run these tests on Symbian, as the Tcl port doesn't like to
234 # convert from floating point value "-inf" to a string.
236 do_realnum_test nan-4.7 {
237 db eval {DELETE FROM t1}
238 db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
239 db eval {SELECT x, typeof(x) FROM t1}
241 do_realnum_test nan-4.8 {
242 db eval {DELETE FROM t1}
243 db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
244 db eval {SELECT x, typeof(x) FROM t1}
248 db eval {DELETE FROM t1}
249 db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
250 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
253 db eval {DELETE FROM t1}
254 db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
255 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
259 db eval {DELETE FROM t1}
260 db eval "INSERT INTO t1 VALUES(1234.5[string repeat 0 10000]12345)"
261 db eval {SELECT x, typeof(x) FROM t1}
264 db eval {DELETE FROM t1}
265 db eval "INSERT INTO t1 VALUES(-1234.5[string repeat 0 10000]12345)"
266 db eval {SELECT x, typeof(x) FROM t1}
269 db eval {DELETE FROM t1}
270 set small [string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
271 db eval "INSERT INTO t1 VALUES($small)"
272 db eval {SELECT x, typeof(x) FROM t1}
275 db eval {DELETE FROM t1}
277 -[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
278 db eval "INSERT INTO t1 VALUES($small)"
279 db eval {SELECT x, typeof(x) FROM t1}
282 # These tests test some really, really small floating point numbers.
284 if {$tcl_platform(platform) != "symbian"} {
285 # These two are not run on symbian because tcl has trouble converting
286 # the very small numbers back to text form (probably due to a difference
287 # in the sprintf() implementation).
290 db eval {DELETE FROM t1}
292 [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
293 db eval "INSERT INTO t1 VALUES($small)"
294 db eval {SELECT x, typeof(x) FROM t1}
295 } {9.88131291682493e-324 real}
297 db eval {DELETE FROM t1}
299 -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
300 db eval "INSERT INTO t1 VALUES($small)"
301 db eval {SELECT x, typeof(x) FROM t1}
302 } {-9.88131291682493e-324 real}
305 db eval {DELETE FROM t1}
306 set small [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
307 db eval "INSERT INTO t1 VALUES($small)"
308 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
309 } {9.88131291682493e-324 real}
311 db eval {DELETE FROM t1}
313 -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
314 db eval "INSERT INTO t1 VALUES($small)"
315 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
316 } {-9.88131291682493e-324 real}
318 do_realnum_test nan-4.20 {
319 db eval {DELETE FROM t1}
320 set big [string repeat 9 10000].0e-9000
321 db eval "INSERT INTO t1 VALUES($big)"
322 db eval {SELECT x, typeof(x) FROM t1}
325 do_realnum_test nan-4.30 {
328 INSERT INTO t1 VALUES('2.5e+9999');
329 SELECT x, typeof(x) FROM t1;
332 do_realnum_test nan-4.31 {
335 INSERT INTO t1 VALUES('2.5e+10000');
336 SELECT x, typeof(x) FROM t1;
340 do_realnum_test nan-4.32 {
343 INSERT INTO t1 VALUES('2.5e-9999');
344 SELECT x, typeof(x) FROM t1;
347 do_realnum_test nan-4.33 {
350 INSERT INTO t1 VALUES('2.5e-10000');
351 SELECT x, typeof(x) FROM t1;
354 do_realnum_test nan-4.34 {
357 INSERT INTO t1 VALUES('2.5e2147483650');
358 SELECT x, typeof(x) FROM t1;
361 do_realnum_test nan-4.35 {
364 INSERT INTO t1 VALUES('2.5e-2147483650');
365 SELECT x, typeof(x) FROM t1;
369 do_realnum_test nan-4.40 {
371 SELECT cast('-1e999' AS real);