Fix a problem causing the recovery extension to use excessive memory and CPU time...
[sqlite.git] / test / nan.test
blob615a4ad22762939530fe714f6b3950cf3e2bf655
1 # 2008 April 28
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 #***********************************************************************
12 # Ticket #3060
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
19 # out of range.
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).
30 do_not_use_codec
32 do_test nan-1.1.1 {
33   db eval {
34     PRAGMA auto_vacuum=OFF;
35     PRAGMA page_size=1024;
36     CREATE TABLE t1(x FLOAT);
37   }
38   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
42   db eval {SELECT x, typeof(x) FROM t1}
43 } {{} null}
44 if {$tcl_platform(platform) != "symbian"} {
45   do_realnum_test nan-1.1.2 {
46     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}
51   do_realnum_test nan-1.1.3 {
52     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}
57   do_realnum_test nan-1.1.4 {
58     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}
63   do_realnum_test nan-1.1.5 {
64     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}
69   do_realnum_test nan-1.1.6 {
70     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}
75   do_test nan-1.1.7 {
76     db eval {
77       UPDATE t1 SET x=x-x;
78       SELECT x, typeof(x) FROM t1;
79     }
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.
90 do_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}
99 do_test nan-1.2.2 {
100   sqlite3_bind_double $::STMT 1 +Inf
101   sqlite3_step $::STMT
102   sqlite3_reset $::STMT
103   db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
104 } {{} null Inf real}
105 do_test nan-1.2.3 {
106   sqlite3_bind_double $::STMT 1 -Inf
107   sqlite3_step $::STMT
108   sqlite3_reset $::STMT
109   db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
110 } {{} null Inf real -Inf real}
111 do_test nan-1.2.4 {
112   sqlite3_bind_double $::STMT 1 -NaN
113   sqlite3_step $::STMT
114   sqlite3_reset $::STMT
115   db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
116 } {{} null Inf real -Inf real {} null}
117 do_test nan-1.2.5 {
118   sqlite3_bind_double $::STMT 1 NaN0
119   sqlite3_step $::STMT
120   sqlite3_reset $::STMT
121   db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
122 } {{} null Inf real -Inf real {} null {} null}
123 do_test nan-1.2.6 {
124   sqlite3_bind_double $::STMT 1 -NaN0
125   sqlite3_step $::STMT
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}
129 do_test nan-1.2.7 {
130   db eval {
131     UPDATE t1 SET x=x-x;
132     SELECT CAST(x AS text), typeof(x) FROM t1;
133   }
134 } {{} null {} null {} null {} null {} null {} null}
136 do_test nan-2.1 {
137   db eval {
138     DELETE FROM T1;
139   }
140   sqlite3_bind_double $::STMT 1 NaN
141   sqlite3_step $::STMT
142   sqlite3_reset $::STMT
143   db eval {SELECT x, typeof(x) FROM t1}
144 } {{} null}
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
152 # NULL.
154 if {![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}
196 # Verify that the sqlite3AtoF routine is able to handle extreme
197 # numbers.
199 do_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}
204 do_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}
209 do_test nan-4.3 {
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}
213 } {-1e+307 real}
214 do_test nan-4.4 {
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}
218 } {-1e+308 real}
219 do_test nan-4.5 {
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}
224 } {-1e+308 real}
225 do_test nan-4.6 {
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}
230 } {1e+308 real}
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.
235   #
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}
240   } {inf real}
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}
245   } {-inf real}
247 do_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}
252 do_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}
258 do_test nan-4.11 {
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}
262 } {1234.5 real}
263 do_test nan-4.12 {
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}
267 } {-1234.5 real}
268 do_test nan-4.13 {
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}
273 } {0.0 real}
274 do_test nan-4.14 {
275   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}
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).
288   #
289   do_test nan-4.15 {
290     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}
296   do_test nan-4.16 {
297     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}
304 do_test nan-4.17 {
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}
310 do_test nan-4.18 {
311   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}
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}
323 } {inf real}
325 do_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}
332 do_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}
340 do_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}
347 do_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}
354 do_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}
361 do_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}
369 do_realnum_test nan-4.40 {
370   db eval {
371     SELECT cast('-1e999' AS real);
372   }
373 } {-inf}
375 finish_test