-C Allow\sSQLITE_MAX_COLUMN\sto\sbe\sset\sto\szero\sat\scompile-time\sin\sorder\sto\ndisable\sthe\schecks.\s\sAlso\sSQLITE_MAX_EXPR_DEPTH.\s\sTicket\s#3069.\s(CVS\s5065)
-D 2008-04-28T20:35:49
+C Always\sconvert\sIEEE\sNaN\sinto\sNULL.\s\sTicket\s#3060.\s\sAdd\stest\scases\sto\sverify\nthat\sthis\sis\shappening.\s(CVS\s5066)
+D 2008-04-29T00:15:21
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
-F src/expr.c 6a6f37005921314b1ae7c3ed4fab03c58fd5e647
+F src/expr.c a896d1be67b2abe9759369cb7f3a3b7a1c21fc3f
F src/fault.c 83057e86815d473e526f7df0b0108dfdd022ff23
F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0
F src/hash.c 522a8f5a23cf18fe5845afee7263c5be76c25ca2
F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b
F src/util.c a3907b05dcc3720a6d71bb39e61d67b0d994b51f
F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
-F src/vdbe.c 1e0ee231e5b035195c6d0043f059fe7f3df563da
+F src/vdbe.c 26964ba7ed76d2a1c52747d601aaf2dc5b09b651
F src/vdbe.h bfd84bda447f39cb599302c7ec85067dae20453c
F src/vdbeInt.h 05316345da487b0cf540482576f9ae3337d133cd
F src/vdbeapi.c 0e1b5a808bb0e556f2a975eb7d11fd3153e922bf
-F src/vdbeaux.c 7a0d0f021ebc54ae581a4f1ba833a2bee576228e
+F src/vdbeaux.c aae523de91fb72a32a256253880739fe103ea76e
F src/vdbeblob.c 554736781ee273a8089c776e96bdb53e66f57ce6
F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
F src/vdbemem.c 8cdc5d4c9558338a2c5ae81135d0826136833b5e
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 26e0d948a413bca61ed031159907a03d64647409
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
+F test/nan.test bda46bce39d14bbe23b97feb390a0b54961a0de9
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/onefile.test 5af2867a8097cea08f15de5382b8d57d1219d8e3
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 76175199ac2fda57e616eb386ba0bad6aa9f74b4
-R dc8adbd3002ee68e412cd270901158fa
+P e6f71abb22fb74e5910d817caec98fa44070fc5f
+R e524df0bf8a8555789b9eeb5782f38f2
U drh
-Z 1669d55a9b3e668684a817ba98300199
+Z e4a613f256396e3f19a950003ad91fee
-e6f71abb22fb74e5910d817caec98fa44070fc5f
\ No newline at end of file
+9b07e59e510e2de39c2081653662fbc654ca6fbb
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.369 2008/04/25 00:08:38 drh Exp $
+** $Id: expr.c,v 1.370 2008/04/29 00:15:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
char *zV;
assert( !isdigit(z[n]) );
sqlite3AtoF(z, &value);
- if( negateFlag ) value = -value;
- zV = dup8bytes(v, (char*)&value);
- sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
+ if( sqlite3IsNaN(value) ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iMem);
+ }else{
+ if( negateFlag ) value = -value;
+ zV = dup8bytes(v, (char*)&value);
+ sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
+ }
}
}
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.736 2008/04/28 16:55:26 drh Exp $
+** $Id: vdbe.c,v 1.737 2008/04/29 00:15:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
*/
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
pOut->flags = MEM_Real;
+ assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->r = *pOp->p4.pReal;
break;
}
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
-** $Id: vdbeaux.c,v 1.380 2008/04/27 18:40:12 drh Exp $
+** $Id: vdbeaux.c,v 1.381 2008/04/29 00:15:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->r, &x, sizeof(x));
- pMem->flags = MEM_Real;
+ pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
}
return 8;
}
--- /dev/null
+# 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.
+#
+# $Id: nan.test,v 1.1 2008/04/29 00:15:21 drh Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# The ascii->float conversion routine in SQLite converts all digits
+# of a number to a long long double. Then it divids by 10**N where
+# N is the number of digits to the right of the decimal point. If
+# both the full number and 10**N are +Inf we will get +Inf/+Inf which
+# is NaN.
+#
+unset -nocomplain nan
+set nan 9.[string repeat 9 5000]
+
+unset -nocomplain inf
+set inf [string repeat 9 5000].0
+
+do_test nan-1.1 {
+ db eval {
+ CREATE TABLE t1(x FLOAT);
+ }
+ db eval "INSERT INTO t1 VALUES($nan)"
+ db eval {SELECT x, typeof(x) FROM t1}
+} {{} null}
+do_test nan-1.2 {
+ db eval "INSERT INTO t1 VALUES($inf)"
+ db eval {SELECT x, typeof(x) FROM t1}
+} {{} null inf real}
+do_test nan-1.3 {
+ db eval "INSERT INTO t1 VALUES(-$inf)"
+ db eval {SELECT x, typeof(x) FROM t1}
+} {{} null inf real -inf real}
+do_test nan-1.4 {
+ db eval {
+ UPDATE t1 SET x=x-x;
+ SELECT x, typeof(x) FROM t1;
+ }
+} {{} null {} null {} null}
+
+do_test nan-2.1 {
+ db eval {
+ DELETE FROM T1;
+ }
+ db eval "INSERT INTO t1 VALUES('$nan')"
+ db eval {SELECT x, typeof(x) FROM t1}
+} {{} null}
+
+# 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}
+
+finish_test