sl@0
|
1 |
# 2008 April 28
|
sl@0
|
2 |
#
|
sl@0
|
3 |
# Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
|
sl@0
|
4 |
#
|
sl@0
|
5 |
# The author disclaims copyright to this source code. In place of
|
sl@0
|
6 |
# a legal notice, here is a blessing:
|
sl@0
|
7 |
#
|
sl@0
|
8 |
# May you do good and not evil.
|
sl@0
|
9 |
# May you find forgiveness for yourself and forgive others.
|
sl@0
|
10 |
# May you share freely, never taking more than you give.
|
sl@0
|
11 |
#
|
sl@0
|
12 |
#***********************************************************************
|
sl@0
|
13 |
#
|
sl@0
|
14 |
# Ticket #3060
|
sl@0
|
15 |
#
|
sl@0
|
16 |
# Make sure IEEE floating point NaN values are handled properly.
|
sl@0
|
17 |
# SQLite should always convert NaN into NULL.
|
sl@0
|
18 |
#
|
sl@0
|
19 |
# Also verify that the decimal to IEEE754 binary conversion routines
|
sl@0
|
20 |
# correctly generate 0.0, +Inf, and -Inf as appropriate for numbers
|
sl@0
|
21 |
# out of range.
|
sl@0
|
22 |
#
|
sl@0
|
23 |
# $Id: nan.test,v 1.5 2008/09/18 11:30:13 danielk1977 Exp $
|
sl@0
|
24 |
#
|
sl@0
|
25 |
|
sl@0
|
26 |
set testdir [file dirname $argv0]
|
sl@0
|
27 |
source $testdir/tester.tcl
|
sl@0
|
28 |
|
sl@0
|
29 |
do_test nan-1.1.1 {
|
sl@0
|
30 |
db eval {
|
sl@0
|
31 |
PRAGMA auto_vacuum=OFF;
|
sl@0
|
32 |
PRAGMA page_size=1024;
|
sl@0
|
33 |
CREATE TABLE t1(x FLOAT);
|
sl@0
|
34 |
}
|
sl@0
|
35 |
set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
|
sl@0
|
36 |
sqlite3_bind_double $::STMT 1 NaN
|
sl@0
|
37 |
sqlite3_step $::STMT
|
sl@0
|
38 |
sqlite3_reset $::STMT
|
sl@0
|
39 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
40 |
} {{} null}
|
sl@0
|
41 |
if {$tcl_platform(platform) != "symbian"} {
|
sl@0
|
42 |
do_test nan-1.1.2 {
|
sl@0
|
43 |
sqlite3_bind_double $::STMT 1 +Inf
|
sl@0
|
44 |
sqlite3_step $::STMT
|
sl@0
|
45 |
sqlite3_reset $::STMT
|
sl@0
|
46 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
47 |
} {{} null inf real}
|
sl@0
|
48 |
do_test nan-1.1.3 {
|
sl@0
|
49 |
sqlite3_bind_double $::STMT 1 -Inf
|
sl@0
|
50 |
sqlite3_step $::STMT
|
sl@0
|
51 |
sqlite3_reset $::STMT
|
sl@0
|
52 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
53 |
} {{} null inf real -inf real}
|
sl@0
|
54 |
do_test nan-1.1.4 {
|
sl@0
|
55 |
sqlite3_bind_double $::STMT 1 -NaN
|
sl@0
|
56 |
sqlite3_step $::STMT
|
sl@0
|
57 |
sqlite3_reset $::STMT
|
sl@0
|
58 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
59 |
} {{} null inf real -inf real {} null}
|
sl@0
|
60 |
do_test nan-1.1.5 {
|
sl@0
|
61 |
sqlite3_bind_double $::STMT 1 NaN0
|
sl@0
|
62 |
sqlite3_step $::STMT
|
sl@0
|
63 |
sqlite3_reset $::STMT
|
sl@0
|
64 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
65 |
} {{} null inf real -inf real {} null {} null}
|
sl@0
|
66 |
do_test nan-1.1.5 {
|
sl@0
|
67 |
sqlite3_bind_double $::STMT 1 -NaN0
|
sl@0
|
68 |
sqlite3_step $::STMT
|
sl@0
|
69 |
sqlite3_reset $::STMT
|
sl@0
|
70 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
71 |
} {{} null inf real -inf real {} null {} null {} null}
|
sl@0
|
72 |
do_test nan-1.1.6 {
|
sl@0
|
73 |
db eval {
|
sl@0
|
74 |
UPDATE t1 SET x=x-x;
|
sl@0
|
75 |
SELECT x, typeof(x) FROM t1;
|
sl@0
|
76 |
}
|
sl@0
|
77 |
} {{} null {} null {} null {} null {} null {} null}
|
sl@0
|
78 |
}
|
sl@0
|
79 |
|
sl@0
|
80 |
# The following block of tests, nan-1.2.*, are the same as the nan-1.1.*
|
sl@0
|
81 |
# tests above, except that the SELECT queries used to validate data
|
sl@0
|
82 |
# convert floating point values to text internally before returning them
|
sl@0
|
83 |
# to Tcl. This allows the tests to be run on platforms where Tcl has
|
sl@0
|
84 |
# problems converting "inf" and "-inf" from floating point to text format.
|
sl@0
|
85 |
# It also tests the internal float->text conversion routines a bit.
|
sl@0
|
86 |
#
|
sl@0
|
87 |
do_test nan-1.2.1 {
|
sl@0
|
88 |
db eval {
|
sl@0
|
89 |
DELETE FROM T1;
|
sl@0
|
90 |
}
|
sl@0
|
91 |
sqlite3_bind_double $::STMT 1 NaN
|
sl@0
|
92 |
sqlite3_step $::STMT
|
sl@0
|
93 |
sqlite3_reset $::STMT
|
sl@0
|
94 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
95 |
} {{} null}
|
sl@0
|
96 |
do_test nan-1.2.2 {
|
sl@0
|
97 |
sqlite3_bind_double $::STMT 1 +Inf
|
sl@0
|
98 |
sqlite3_step $::STMT
|
sl@0
|
99 |
sqlite3_reset $::STMT
|
sl@0
|
100 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
101 |
} {{} null Inf real}
|
sl@0
|
102 |
do_test nan-1.2.3 {
|
sl@0
|
103 |
sqlite3_bind_double $::STMT 1 -Inf
|
sl@0
|
104 |
sqlite3_step $::STMT
|
sl@0
|
105 |
sqlite3_reset $::STMT
|
sl@0
|
106 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
107 |
} {{} null Inf real -Inf real}
|
sl@0
|
108 |
do_test nan-1.2.4 {
|
sl@0
|
109 |
sqlite3_bind_double $::STMT 1 -NaN
|
sl@0
|
110 |
sqlite3_step $::STMT
|
sl@0
|
111 |
sqlite3_reset $::STMT
|
sl@0
|
112 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
113 |
} {{} null Inf real -Inf real {} null}
|
sl@0
|
114 |
do_test nan-1.2.5 {
|
sl@0
|
115 |
sqlite3_bind_double $::STMT 1 NaN0
|
sl@0
|
116 |
sqlite3_step $::STMT
|
sl@0
|
117 |
sqlite3_reset $::STMT
|
sl@0
|
118 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
119 |
} {{} null Inf real -Inf real {} null {} null}
|
sl@0
|
120 |
do_test nan-1.2.5 {
|
sl@0
|
121 |
sqlite3_bind_double $::STMT 1 -NaN0
|
sl@0
|
122 |
sqlite3_step $::STMT
|
sl@0
|
123 |
sqlite3_reset $::STMT
|
sl@0
|
124 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
125 |
} {{} null Inf real -Inf real {} null {} null {} null}
|
sl@0
|
126 |
do_test nan-1.2.6 {
|
sl@0
|
127 |
db eval {
|
sl@0
|
128 |
UPDATE t1 SET x=x-x;
|
sl@0
|
129 |
SELECT CAST(x AS text), typeof(x) FROM t1;
|
sl@0
|
130 |
}
|
sl@0
|
131 |
} {{} null {} null {} null {} null {} null {} null}
|
sl@0
|
132 |
|
sl@0
|
133 |
do_test nan-2.1 {
|
sl@0
|
134 |
db eval {
|
sl@0
|
135 |
DELETE FROM T1;
|
sl@0
|
136 |
}
|
sl@0
|
137 |
sqlite3_bind_double $::STMT 1 NaN
|
sl@0
|
138 |
sqlite3_step $::STMT
|
sl@0
|
139 |
sqlite3_reset $::STMT
|
sl@0
|
140 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
141 |
} {{} null}
|
sl@0
|
142 |
sqlite3_finalize $::STMT
|
sl@0
|
143 |
|
sl@0
|
144 |
# SQLite always converts NaN into NULL so it is not possible to write
|
sl@0
|
145 |
# a NaN value into the database file using SQLite. The following series
|
sl@0
|
146 |
# of tests writes a normal floating point value (0.5) into the database,
|
sl@0
|
147 |
# then writes directly into the database file to change the 0.5 into NaN.
|
sl@0
|
148 |
# Then it reads the value of the database to verify it is converted into
|
sl@0
|
149 |
# NULL.
|
sl@0
|
150 |
#
|
sl@0
|
151 |
do_test nan-3.1 {
|
sl@0
|
152 |
db eval {
|
sl@0
|
153 |
DELETE FROM t1;
|
sl@0
|
154 |
INSERT INTO t1 VALUES(0.5);
|
sl@0
|
155 |
PRAGMA auto_vacuum=OFF;
|
sl@0
|
156 |
PRAGMA page_size=1024;
|
sl@0
|
157 |
VACUUM;
|
sl@0
|
158 |
}
|
sl@0
|
159 |
hexio_read test.db 2040 8
|
sl@0
|
160 |
} {3FE0000000000000}
|
sl@0
|
161 |
do_test nan-3.2 {
|
sl@0
|
162 |
db eval {
|
sl@0
|
163 |
SELECT x, typeof(x) FROM t1
|
sl@0
|
164 |
}
|
sl@0
|
165 |
} {0.5 real}
|
sl@0
|
166 |
do_test nan-3.3 {
|
sl@0
|
167 |
db close
|
sl@0
|
168 |
hexio_write test.db 2040 FFF8000000000000
|
sl@0
|
169 |
sqlite3 db test.db
|
sl@0
|
170 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
171 |
} {{} null}
|
sl@0
|
172 |
do_test nan-3.4 {
|
sl@0
|
173 |
db close
|
sl@0
|
174 |
hexio_write test.db 2040 7FF8000000000000
|
sl@0
|
175 |
sqlite3 db test.db
|
sl@0
|
176 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
177 |
} {{} null}
|
sl@0
|
178 |
do_test nan-3.5 {
|
sl@0
|
179 |
db close
|
sl@0
|
180 |
hexio_write test.db 2040 FFFFFFFFFFFFFFFF
|
sl@0
|
181 |
sqlite3 db test.db
|
sl@0
|
182 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
183 |
} {{} null}
|
sl@0
|
184 |
do_test nan-3.6 {
|
sl@0
|
185 |
db close
|
sl@0
|
186 |
hexio_write test.db 2040 7FFFFFFFFFFFFFFF
|
sl@0
|
187 |
sqlite3 db test.db
|
sl@0
|
188 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
189 |
} {{} null}
|
sl@0
|
190 |
|
sl@0
|
191 |
# Verify that the sqlite3AtoF routine is able to handle extreme
|
sl@0
|
192 |
# numbers.
|
sl@0
|
193 |
#
|
sl@0
|
194 |
do_test nan-4.1 {
|
sl@0
|
195 |
db eval {DELETE FROM t1}
|
sl@0
|
196 |
db eval "INSERT INTO t1 VALUES([string repeat 9 307].0)"
|
sl@0
|
197 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
198 |
} {1e+307 real}
|
sl@0
|
199 |
do_test nan-4.2 {
|
sl@0
|
200 |
db eval {DELETE FROM t1}
|
sl@0
|
201 |
db eval "INSERT INTO t1 VALUES([string repeat 9 308].0)"
|
sl@0
|
202 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
203 |
} {1e+308 real}
|
sl@0
|
204 |
do_test nan-4.3 {
|
sl@0
|
205 |
db eval {DELETE FROM t1}
|
sl@0
|
206 |
db eval "INSERT INTO t1 VALUES(-[string repeat 9 307].0)"
|
sl@0
|
207 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
208 |
} {-1e+307 real}
|
sl@0
|
209 |
do_test nan-4.4 {
|
sl@0
|
210 |
db eval {DELETE FROM t1}
|
sl@0
|
211 |
db eval "INSERT INTO t1 VALUES(-[string repeat 9 308].0)"
|
sl@0
|
212 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
213 |
} {-1e+308 real}
|
sl@0
|
214 |
do_test nan-4.5 {
|
sl@0
|
215 |
db eval {DELETE FROM t1}
|
sl@0
|
216 |
set big -[string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
|
sl@0
|
217 |
db eval "INSERT INTO t1 VALUES($big)"
|
sl@0
|
218 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
219 |
} {-1e+308 real}
|
sl@0
|
220 |
do_test nan-4.6 {
|
sl@0
|
221 |
db eval {DELETE FROM t1}
|
sl@0
|
222 |
set big [string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
|
sl@0
|
223 |
db eval "INSERT INTO t1 VALUES($big)"
|
sl@0
|
224 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
225 |
} {1e+308 real}
|
sl@0
|
226 |
|
sl@0
|
227 |
if {$tcl_platform(platform) != "symbian"} {
|
sl@0
|
228 |
# Do not run these tests on Symbian, as the Tcl port doesn't like to
|
sl@0
|
229 |
# convert from floating point value "-inf" to a string.
|
sl@0
|
230 |
#
|
sl@0
|
231 |
do_test nan-4.7 {
|
sl@0
|
232 |
db eval {DELETE FROM t1}
|
sl@0
|
233 |
db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
|
sl@0
|
234 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
235 |
} {inf real}
|
sl@0
|
236 |
do_test nan-4.8 {
|
sl@0
|
237 |
db eval {DELETE FROM t1}
|
sl@0
|
238 |
db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
|
sl@0
|
239 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
240 |
} {-inf real}
|
sl@0
|
241 |
}
|
sl@0
|
242 |
do_test nan-4.9 {
|
sl@0
|
243 |
db eval {DELETE FROM t1}
|
sl@0
|
244 |
db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
|
sl@0
|
245 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
246 |
} {Inf real}
|
sl@0
|
247 |
do_test nan-4.10 {
|
sl@0
|
248 |
db eval {DELETE FROM t1}
|
sl@0
|
249 |
db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
|
sl@0
|
250 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
251 |
} {-Inf real}
|
sl@0
|
252 |
|
sl@0
|
253 |
do_test nan-4.10 {
|
sl@0
|
254 |
db eval {DELETE FROM t1}
|
sl@0
|
255 |
db eval "INSERT INTO t1 VALUES(1234.5[string repeat 0 10000]12345)"
|
sl@0
|
256 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
257 |
} {1234.5 real}
|
sl@0
|
258 |
do_test nan-4.11 {
|
sl@0
|
259 |
db eval {DELETE FROM t1}
|
sl@0
|
260 |
db eval "INSERT INTO t1 VALUES(-1234.5[string repeat 0 10000]12345)"
|
sl@0
|
261 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
262 |
} {-1234.5 real}
|
sl@0
|
263 |
do_test nan-4.12 {
|
sl@0
|
264 |
db eval {DELETE FROM t1}
|
sl@0
|
265 |
set small [string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
|
sl@0
|
266 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
267 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
268 |
} {0.0 real}
|
sl@0
|
269 |
do_test nan-4.13 {
|
sl@0
|
270 |
db eval {DELETE FROM t1}
|
sl@0
|
271 |
set small \
|
sl@0
|
272 |
-[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
|
sl@0
|
273 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
274 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
275 |
} {0.0 real}
|
sl@0
|
276 |
|
sl@0
|
277 |
# These tests test some really, really small floating point numbers.
|
sl@0
|
278 |
#
|
sl@0
|
279 |
if {$tcl_platform(platform) != "symbian"} {
|
sl@0
|
280 |
# These two are not run on symbian because tcl has trouble converting
|
sl@0
|
281 |
# the very small numbers back to text form (probably due to a difference
|
sl@0
|
282 |
# in the sprintf() implementation).
|
sl@0
|
283 |
#
|
sl@0
|
284 |
do_test nan-4.14 {
|
sl@0
|
285 |
db eval {DELETE FROM t1}
|
sl@0
|
286 |
set small \
|
sl@0
|
287 |
[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
|
sl@0
|
288 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
289 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
290 |
} {9.88131291682493e-324 real}
|
sl@0
|
291 |
do_test nan-4.15 {
|
sl@0
|
292 |
db eval {DELETE FROM t1}
|
sl@0
|
293 |
set small \
|
sl@0
|
294 |
-[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
|
sl@0
|
295 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
296 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
297 |
} {-9.88131291682493e-324 real}
|
sl@0
|
298 |
}
|
sl@0
|
299 |
#
|
sl@0
|
300 |
# Symbian OS: the next test fails due to problems in sprintf/printf formatting.
|
sl@0
|
301 |
if {$::tcl_platform(platform)!="symbian"} {
|
sl@0
|
302 |
do_test nan-4.16 {
|
sl@0
|
303 |
db eval {DELETE FROM t1}
|
sl@0
|
304 |
set small [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
|
sl@0
|
305 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
306 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
307 |
} {9.88131291682493e-324 real}
|
sl@0
|
308 |
}
|
sl@0
|
309 |
#
|
sl@0
|
310 |
# Symbian OS: the next test fails due to problems in sprintf/printf formatting.
|
sl@0
|
311 |
if {$::tcl_platform(platform)!="symbian"} {
|
sl@0
|
312 |
do_test nan-4.17 {
|
sl@0
|
313 |
db eval {DELETE FROM t1}
|
sl@0
|
314 |
set small \
|
sl@0
|
315 |
-[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
|
sl@0
|
316 |
db eval "INSERT INTO t1 VALUES($small)"
|
sl@0
|
317 |
db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
|
sl@0
|
318 |
} {-9.88131291682493e-324 real}
|
sl@0
|
319 |
}
|
sl@0
|
320 |
do_test nan-4.20 {
|
sl@0
|
321 |
db eval {DELETE FROM t1}
|
sl@0
|
322 |
set big [string repeat 9 10000].0e-9000
|
sl@0
|
323 |
db eval "INSERT INTO t1 VALUES($big)"
|
sl@0
|
324 |
db eval {SELECT x, typeof(x) FROM t1}
|
sl@0
|
325 |
} {{} null}
|
sl@0
|
326 |
|
sl@0
|
327 |
|
sl@0
|
328 |
|
sl@0
|
329 |
finish_test
|