blob: 27fa04a3517a8106427018a62483243bb7ee3cb6 [file] [log] [blame]
drh2eaf93d2008-04-29 00:15:20 +00001# 2008 April 28
2#
3# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
5#
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.
9#
10#***********************************************************************
11#
12# Ticket #3060
13#
14# Make sure IEEE floating point NaN values are handled properly.
15# SQLite should always convert NaN into NULL.
16#
drha06f17f2008-05-11 11:07:06 +000017# Also verify that the decimal to IEEE754 binary conversion routines
18# correctly generate 0.0, +Inf, and -Inf as appropriate for numbers
19# out of range.
20#
danielk1977b11bcfd2008-09-18 11:30:12 +000021# $Id: nan.test,v 1.5 2008/09/18 11:30:13 danielk1977 Exp $
drh2eaf93d2008-04-29 00:15:20 +000022#
23
24set testdir [file dirname $argv0]
25source $testdir/tester.tcl
26
dan68928b62010-06-22 13:46:43 +000027# 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).
29#
30do_not_use_codec
31
danielk197789bae3e2008-09-17 16:14:10 +000032do_test nan-1.1.1 {
drh2eaf93d2008-04-29 00:15:20 +000033 db eval {
drhb7d63622008-05-01 18:01:46 +000034 PRAGMA auto_vacuum=OFF;
35 PRAGMA page_size=1024;
drh2eaf93d2008-04-29 00:15:20 +000036 CREATE TABLE t1(x FLOAT);
37 }
drha06f17f2008-05-11 11:07:06 +000038 set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
39 sqlite3_bind_double $::STMT 1 NaN
40 sqlite3_step $::STMT
41 sqlite3_reset $::STMT
drh2eaf93d2008-04-29 00:15:20 +000042 db eval {SELECT x, typeof(x) FROM t1}
43} {{} null}
danielk197789bae3e2008-09-17 16:14:10 +000044if {$tcl_platform(platform) != "symbian"} {
dan33f53792011-05-05 19:44:22 +000045 do_realnum_test nan-1.1.2 {
danielk197789bae3e2008-09-17 16:14:10 +000046 sqlite3_bind_double $::STMT 1 +Inf
47 sqlite3_step $::STMT
48 sqlite3_reset $::STMT
49 db eval {SELECT x, typeof(x) FROM t1}
50 } {{} null inf real}
dan33f53792011-05-05 19:44:22 +000051 do_realnum_test nan-1.1.3 {
danielk197789bae3e2008-09-17 16:14:10 +000052 sqlite3_bind_double $::STMT 1 -Inf
53 sqlite3_step $::STMT
54 sqlite3_reset $::STMT
55 db eval {SELECT x, typeof(x) FROM t1}
56 } {{} null inf real -inf real}
dan33f53792011-05-05 19:44:22 +000057 do_realnum_test nan-1.1.4 {
danielk197789bae3e2008-09-17 16:14:10 +000058 sqlite3_bind_double $::STMT 1 -NaN
59 sqlite3_step $::STMT
60 sqlite3_reset $::STMT
61 db eval {SELECT x, typeof(x) FROM t1}
62 } {{} null inf real -inf real {} null}
dan33f53792011-05-05 19:44:22 +000063 do_realnum_test nan-1.1.5 {
danielk197789bae3e2008-09-17 16:14:10 +000064 sqlite3_bind_double $::STMT 1 NaN0
65 sqlite3_step $::STMT
66 sqlite3_reset $::STMT
67 db eval {SELECT x, typeof(x) FROM t1}
68 } {{} null inf real -inf real {} null {} null}
dan33f53792011-05-05 19:44:22 +000069 do_realnum_test nan-1.1.6 {
danielk197789bae3e2008-09-17 16:14:10 +000070 sqlite3_bind_double $::STMT 1 -NaN0
71 sqlite3_step $::STMT
72 sqlite3_reset $::STMT
73 db eval {SELECT x, typeof(x) FROM t1}
74 } {{} null inf real -inf real {} null {} null {} null}
shaneh100efa32010-07-07 16:20:38 +000075 do_test nan-1.1.7 {
danielk197789bae3e2008-09-17 16:14:10 +000076 db eval {
77 UPDATE t1 SET x=x-x;
78 SELECT x, typeof(x) FROM t1;
79 }
80 } {{} null {} null {} null {} null {} null {} null}
81}
82
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.
89#
90do_test nan-1.2.1 {
91 db eval {
92 DELETE FROM T1;
93 }
94 sqlite3_bind_double $::STMT 1 NaN
95 sqlite3_step $::STMT
96 sqlite3_reset $::STMT
97 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
98} {{} null}
99do_test nan-1.2.2 {
drha06f17f2008-05-11 11:07:06 +0000100 sqlite3_bind_double $::STMT 1 +Inf
101 sqlite3_step $::STMT
102 sqlite3_reset $::STMT
danielk197789bae3e2008-09-17 16:14:10 +0000103 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
104} {{} null Inf real}
105do_test nan-1.2.3 {
drha06f17f2008-05-11 11:07:06 +0000106 sqlite3_bind_double $::STMT 1 -Inf
107 sqlite3_step $::STMT
108 sqlite3_reset $::STMT
danielk197789bae3e2008-09-17 16:14:10 +0000109 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
110} {{} null Inf real -Inf real}
111do_test nan-1.2.4 {
drha06f17f2008-05-11 11:07:06 +0000112 sqlite3_bind_double $::STMT 1 -NaN
113 sqlite3_step $::STMT
114 sqlite3_reset $::STMT
danielk197789bae3e2008-09-17 16:14:10 +0000115 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
116} {{} null Inf real -Inf real {} null}
117do_test nan-1.2.5 {
drha06f17f2008-05-11 11:07:06 +0000118 sqlite3_bind_double $::STMT 1 NaN0
119 sqlite3_step $::STMT
120 sqlite3_reset $::STMT
danielk197789bae3e2008-09-17 16:14:10 +0000121 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
122} {{} null Inf real -Inf real {} null {} null}
shaneh100efa32010-07-07 16:20:38 +0000123do_test nan-1.2.6 {
drha06f17f2008-05-11 11:07:06 +0000124 sqlite3_bind_double $::STMT 1 -NaN0
125 sqlite3_step $::STMT
126 sqlite3_reset $::STMT
danielk197789bae3e2008-09-17 16:14:10 +0000127 db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
128} {{} null Inf real -Inf real {} null {} null {} null}
shaneh100efa32010-07-07 16:20:38 +0000129do_test nan-1.2.7 {
drh2eaf93d2008-04-29 00:15:20 +0000130 db eval {
131 UPDATE t1 SET x=x-x;
danielk197789bae3e2008-09-17 16:14:10 +0000132 SELECT CAST(x AS text), typeof(x) FROM t1;
drh2eaf93d2008-04-29 00:15:20 +0000133 }
drha06f17f2008-05-11 11:07:06 +0000134} {{} null {} null {} null {} null {} null {} null}
drh2eaf93d2008-04-29 00:15:20 +0000135
136do_test nan-2.1 {
137 db eval {
138 DELETE FROM T1;
139 }
drha06f17f2008-05-11 11:07:06 +0000140 sqlite3_bind_double $::STMT 1 NaN
141 sqlite3_step $::STMT
142 sqlite3_reset $::STMT
drh2eaf93d2008-04-29 00:15:20 +0000143 db eval {SELECT x, typeof(x) FROM t1}
144} {{} null}
drha06f17f2008-05-11 11:07:06 +0000145sqlite3_finalize $::STMT
drh2eaf93d2008-04-29 00:15:20 +0000146
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
152# NULL.
153#
drh7da56b42016-03-14 18:34:42 +0000154if {![nonzero_reserved_bytes]} {
155 do_test nan-3.1 {
156 db eval {
157 DELETE FROM t1;
158 INSERT INTO t1 VALUES(0.5);
159 PRAGMA auto_vacuum=OFF;
160 PRAGMA page_size=1024;
161 VACUUM;
162 }
163 hexio_read test.db 2040 8
164 } {3FE0000000000000}
165 do_test nan-3.2 {
166 db eval {
167 SELECT x, typeof(x) FROM t1
168 }
169 } {0.5 real}
170 do_test nan-3.3 {
171 db close
172 hexio_write test.db 2040 FFF8000000000000
173 sqlite3 db test.db
174 db eval {SELECT x, typeof(x) FROM t1}
175 } {{} null}
176 do_test nan-3.4 {
177 db close
178 hexio_write test.db 2040 7FF8000000000000
179 sqlite3 db test.db
180 db eval {SELECT x, typeof(x) FROM t1}
181 } {{} null}
182 do_test nan-3.5 {
183 db close
184 hexio_write test.db 2040 FFFFFFFFFFFFFFFF
185 sqlite3 db test.db
186 db eval {SELECT x, typeof(x) FROM t1}
187 } {{} null}
188 do_test nan-3.6 {
189 db close
190 hexio_write test.db 2040 7FFFFFFFFFFFFFFF
191 sqlite3 db test.db
192 db eval {SELECT x, typeof(x) FROM t1}
193 } {{} null}
194}
drha06f17f2008-05-11 11:07:06 +0000195
196# Verify that the sqlite3AtoF routine is able to handle extreme
197# numbers.
198#
199do_test nan-4.1 {
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}
203} {1e+307 real}
204do_test nan-4.2 {
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}
208} {1e+308 real}
209do_test nan-4.3 {
210 db eval {DELETE FROM t1}
drha06f17f2008-05-11 11:07:06 +0000211 db eval "INSERT INTO t1 VALUES(-[string repeat 9 307].0)"
212 db eval {SELECT x, typeof(x) FROM t1}
213} {-1e+307 real}
danielk197789bae3e2008-09-17 16:14:10 +0000214do_test nan-4.4 {
drha06f17f2008-05-11 11:07:06 +0000215 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}
218} {-1e+308 real}
danielk197789bae3e2008-09-17 16:14:10 +0000219do_test nan-4.5 {
drha06f17f2008-05-11 11:07:06 +0000220 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}
224} {-1e+308 real}
danielk197789bae3e2008-09-17 16:14:10 +0000225do_test nan-4.6 {
drha06f17f2008-05-11 11:07:06 +0000226 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}
230} {1e+308 real}
231
danielk197789bae3e2008-09-17 16:14:10 +0000232if {$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.
235 #
dan33f53792011-05-05 19:44:22 +0000236 do_realnum_test nan-4.7 {
danielk197789bae3e2008-09-17 16:14:10 +0000237 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}
240 } {inf real}
dan33f53792011-05-05 19:44:22 +0000241 do_realnum_test nan-4.8 {
danielk197789bae3e2008-09-17 16:14:10 +0000242 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}
245 } {-inf real}
246}
247do_test nan-4.9 {
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}
251} {Inf real}
252do_test nan-4.10 {
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}
256} {-Inf real}
drha06f17f2008-05-11 11:07:06 +0000257
shaneh100efa32010-07-07 16:20:38 +0000258do_test nan-4.11 {
drha06f17f2008-05-11 11:07:06 +0000259 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}
262} {1234.5 real}
shaneh100efa32010-07-07 16:20:38 +0000263do_test nan-4.12 {
drha06f17f2008-05-11 11:07:06 +0000264 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}
267} {-1234.5 real}
shaneh100efa32010-07-07 16:20:38 +0000268do_test nan-4.13 {
drha06f17f2008-05-11 11:07:06 +0000269 db eval {DELETE FROM t1}
drha06f17f2008-05-11 11:07:06 +0000270 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}
273} {0.0 real}
shaneh100efa32010-07-07 16:20:38 +0000274do_test nan-4.14 {
drha06f17f2008-05-11 11:07:06 +0000275 db eval {DELETE FROM t1}
276 set small \
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}
280} {0.0 real}
281
danielk1977b11bcfd2008-09-18 11:30:12 +0000282# These tests test some really, really small floating point numbers.
283#
284if {$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).
288 #
shaneh100efa32010-07-07 16:20:38 +0000289 do_test nan-4.15 {
danielk1977b11bcfd2008-09-18 11:30:12 +0000290 db eval {DELETE FROM t1}
291 set small \
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}
shaneh100efa32010-07-07 16:20:38 +0000296 do_test nan-4.16 {
danielk1977b11bcfd2008-09-18 11:30:12 +0000297 db eval {DELETE FROM t1}
298 set small \
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}
303}
shaneh100efa32010-07-07 16:20:38 +0000304do_test nan-4.17 {
danielk1977b11bcfd2008-09-18 11:30:12 +0000305 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}
shaneh100efa32010-07-07 16:20:38 +0000310do_test nan-4.18 {
danielk1977b11bcfd2008-09-18 11:30:12 +0000311 db eval {DELETE FROM t1}
312 set small \
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}
317
dan33f53792011-05-05 19:44:22 +0000318do_realnum_test nan-4.20 {
drha06f17f2008-05-11 11:07:06 +0000319 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}
shane6085f5e2009-08-21 02:13:14 +0000323} {inf real}
drha06f17f2008-05-11 11:07:06 +0000324
drh57db4a72011-10-17 20:41:46 +0000325do_realnum_test nan-4.30 {
326 db eval {
327 DELETE FROM t1;
328 INSERT INTO t1 VALUES('2.5e+9999');
329 SELECT x, typeof(x) FROM t1;
330 }
331} {inf real}
332do_realnum_test nan-4.31 {
333 db eval {
334 DELETE FROM t1;
335 INSERT INTO t1 VALUES('2.5e+10000');
336 SELECT x, typeof(x) FROM t1;
337 }
338} {inf real}
339
340do_realnum_test nan-4.32 {
341 db eval {
342 DELETE FROM t1;
343 INSERT INTO t1 VALUES('2.5e-9999');
344 SELECT x, typeof(x) FROM t1;
345 }
346} {0.0 real}
347do_realnum_test nan-4.33 {
348 db eval {
349 DELETE FROM t1;
350 INSERT INTO t1 VALUES('2.5e-10000');
351 SELECT x, typeof(x) FROM t1;
352 }
353} {0.0 real}
354do_realnum_test nan-4.34 {
355 db eval {
356 DELETE FROM t1;
357 INSERT INTO t1 VALUES('2.5e2147483650');
358 SELECT x, typeof(x) FROM t1;
359 }
360} {inf real}
361do_realnum_test nan-4.35 {
362 db eval {
363 DELETE FROM t1;
364 INSERT INTO t1 VALUES('2.5e-2147483650');
365 SELECT x, typeof(x) FROM t1;
366 }
367} {0.0 real}
368
369
370
drha06f17f2008-05-11 11:07:06 +0000371
drh2eaf93d2008-04-29 00:15:20 +0000372
373finish_test