123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- # 2008 April 28
- #
- # The author disclaims copyright to this source code. In place of
- # a legal notice, here is a blessing:
- #
- # May you do good and not evil.
- # May you find forgiveness for yourself and forgive others.
- # May you share freely, never taking more than you give.
- #
- #***********************************************************************
- #
- # Ticket #3060
- #
- # Make sure IEEE floating point NaN values are handled properly.
- # SQLite should always convert NaN into NULL.
- #
- # Also verify that the decimal to IEEE754 binary conversion routines
- # correctly generate 0.0, +Inf, and -Inf as appropriate for numbers
- # out of range.
- #
- # $Id: nan.test,v 1.5 2008/09/18 11:30:13 danielk1977 Exp $
- #
- set testdir [file dirname $argv0]
- source $testdir/tester.tcl
- # Do not use a codec for tests in this file, as the database file is
- # manipulated directly using tcl scripts (using the [hexio_write] command).
- #
- do_not_use_codec
- do_test nan-1.1.1 {
- db eval {
- PRAGMA auto_vacuum=OFF;
- PRAGMA page_size=1024;
- CREATE TABLE t1(x FLOAT);
- }
- set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
- sqlite3_bind_double $::STMT 1 NaN
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- if {$tcl_platform(platform) != "symbian"} {
- do_realnum_test nan-1.1.2 {
- sqlite3_bind_double $::STMT 1 +Inf
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null inf real}
- do_realnum_test nan-1.1.3 {
- sqlite3_bind_double $::STMT 1 -Inf
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null inf real -inf real}
- do_realnum_test nan-1.1.4 {
- sqlite3_bind_double $::STMT 1 -NaN
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null inf real -inf real {} null}
- do_realnum_test nan-1.1.5 {
- sqlite3_bind_double $::STMT 1 NaN0
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null inf real -inf real {} null {} null}
- do_realnum_test nan-1.1.6 {
- sqlite3_bind_double $::STMT 1 -NaN0
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null inf real -inf real {} null {} null {} null}
- do_test nan-1.1.7 {
- db eval {
- UPDATE t1 SET x=x-x;
- SELECT x, typeof(x) FROM t1;
- }
- } {{} null {} null {} null {} null {} null {} null}
- }
- # The following block of tests, nan-1.2.*, are the same as the nan-1.1.*
- # tests above, except that the SELECT queries used to validate data
- # convert floating point values to text internally before returning them
- # to Tcl. This allows the tests to be run on platforms where Tcl has
- # problems converting "inf" and "-inf" from floating point to text format.
- # It also tests the internal float->text conversion routines a bit.
- #
- do_test nan-1.2.1 {
- db eval {
- DELETE FROM T1;
- }
- sqlite3_bind_double $::STMT 1 NaN
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null}
- do_test nan-1.2.2 {
- sqlite3_bind_double $::STMT 1 +Inf
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null Inf real}
- do_test nan-1.2.3 {
- sqlite3_bind_double $::STMT 1 -Inf
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null Inf real -Inf real}
- do_test nan-1.2.4 {
- sqlite3_bind_double $::STMT 1 -NaN
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null Inf real -Inf real {} null}
- do_test nan-1.2.5 {
- sqlite3_bind_double $::STMT 1 NaN0
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null Inf real -Inf real {} null {} null}
- do_test nan-1.2.6 {
- sqlite3_bind_double $::STMT 1 -NaN0
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {{} null Inf real -Inf real {} null {} null {} null}
- do_test nan-1.2.7 {
- db eval {
- UPDATE t1 SET x=x-x;
- SELECT CAST(x AS text), typeof(x) FROM t1;
- }
- } {{} null {} null {} null {} null {} null {} null}
- do_test nan-2.1 {
- db eval {
- DELETE FROM T1;
- }
- sqlite3_bind_double $::STMT 1 NaN
- sqlite3_step $::STMT
- sqlite3_reset $::STMT
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- sqlite3_finalize $::STMT
- # SQLite always converts NaN into NULL so it is not possible to write
- # a NaN value into the database file using SQLite. The following series
- # of tests writes a normal floating point value (0.5) into the database,
- # then writes directly into the database file to change the 0.5 into NaN.
- # Then it reads the value of the database to verify it is converted into
- # NULL.
- #
- do_test nan-3.1 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES(0.5);
- PRAGMA auto_vacuum=OFF;
- PRAGMA page_size=1024;
- VACUUM;
- }
- hexio_read test.db 2040 8
- } {3FE0000000000000}
- do_test nan-3.2 {
- db eval {
- SELECT x, typeof(x) FROM t1
- }
- } {0.5 real}
- do_test nan-3.3 {
- db close
- hexio_write test.db 2040 FFF8000000000000
- sqlite3 db test.db
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- do_test nan-3.4 {
- db close
- hexio_write test.db 2040 7FF8000000000000
- sqlite3 db test.db
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- do_test nan-3.5 {
- db close
- hexio_write test.db 2040 FFFFFFFFFFFFFFFF
- sqlite3 db test.db
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- do_test nan-3.6 {
- db close
- hexio_write test.db 2040 7FFFFFFFFFFFFFFF
- sqlite3 db test.db
- db eval {SELECT x, typeof(x) FROM t1}
- } {{} null}
- # Verify that the sqlite3AtoF routine is able to handle extreme
- # numbers.
- #
- do_test nan-4.1 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES([string repeat 9 307].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {1e+307 real}
- do_test nan-4.2 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES([string repeat 9 308].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {1e+308 real}
- do_test nan-4.3 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(-[string repeat 9 307].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-1e+307 real}
- do_test nan-4.4 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(-[string repeat 9 308].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-1e+308 real}
- do_test nan-4.5 {
- db eval {DELETE FROM t1}
- set big -[string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
- db eval "INSERT INTO t1 VALUES($big)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-1e+308 real}
- do_test nan-4.6 {
- db eval {DELETE FROM t1}
- set big [string repeat 0 10000][string repeat 9 308].[string repeat 0 10000]
- db eval "INSERT INTO t1 VALUES($big)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {1e+308 real}
- if {$tcl_platform(platform) != "symbian"} {
- # Do not run these tests on Symbian, as the Tcl port doesn't like to
- # convert from floating point value "-inf" to a string.
- #
- do_realnum_test nan-4.7 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {inf real}
- do_realnum_test nan-4.8 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-inf real}
- }
- do_test nan-4.9 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES([string repeat 9 309].0)"
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {Inf real}
- do_test nan-4.10 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(-[string repeat 9 309].0)"
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {-Inf real}
- do_test nan-4.11 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(1234.5[string repeat 0 10000]12345)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {1234.5 real}
- do_test nan-4.12 {
- db eval {DELETE FROM t1}
- db eval "INSERT INTO t1 VALUES(-1234.5[string repeat 0 10000]12345)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-1234.5 real}
- do_test nan-4.13 {
- db eval {DELETE FROM t1}
- set small [string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {0.0 real}
- do_test nan-4.14 {
- db eval {DELETE FROM t1}
- set small \
- -[string repeat 0 10000].[string repeat 0 324][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {0.0 real}
- # These tests test some really, really small floating point numbers.
- #
- if {$tcl_platform(platform) != "symbian"} {
- # These two are not run on symbian because tcl has trouble converting
- # the very small numbers back to text form (probably due to a difference
- # in the sprintf() implementation).
- #
- do_test nan-4.15 {
- db eval {DELETE FROM t1}
- set small \
- [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {9.88131291682493e-324 real}
- do_test nan-4.16 {
- db eval {DELETE FROM t1}
- set small \
- -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {-9.88131291682493e-324 real}
- }
- do_test nan-4.17 {
- db eval {DELETE FROM t1}
- set small [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {9.88131291682493e-324 real}
- do_test nan-4.18 {
- db eval {DELETE FROM t1}
- set small \
- -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000]
- db eval "INSERT INTO t1 VALUES($small)"
- db eval {SELECT CAST(x AS text), typeof(x) FROM t1}
- } {-9.88131291682493e-324 real}
- do_realnum_test nan-4.20 {
- db eval {DELETE FROM t1}
- set big [string repeat 9 10000].0e-9000
- db eval "INSERT INTO t1 VALUES($big)"
- db eval {SELECT x, typeof(x) FROM t1}
- } {inf real}
- do_realnum_test nan-4.30 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e+9999');
- SELECT x, typeof(x) FROM t1;
- }
- } {inf real}
- do_realnum_test nan-4.31 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e+10000');
- SELECT x, typeof(x) FROM t1;
- }
- } {inf real}
- do_realnum_test nan-4.32 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e-9999');
- SELECT x, typeof(x) FROM t1;
- }
- } {0.0 real}
- do_realnum_test nan-4.33 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e-10000');
- SELECT x, typeof(x) FROM t1;
- }
- } {0.0 real}
- do_realnum_test nan-4.34 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e2147483650');
- SELECT x, typeof(x) FROM t1;
- }
- } {inf real}
- do_realnum_test nan-4.35 {
- db eval {
- DELETE FROM t1;
- INSERT INTO t1 VALUES('2.5e-2147483650');
- SELECT x, typeof(x) FROM t1;
- }
- } {0.0 real}
-
- finish_test
|