From: drh Date: Thu, 30 Sep 2010 17:33:11 +0000 (+0000) Subject: Do correct affinity transformations on floating point values which have X-Git-Tag: version-3.7.4~122^2~4 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=025586a259b68a5a81ad1114ec19881e996a2a54;p=thirdparty%2Fsqlite.git Do correct affinity transformations on floating point values which have a decimal point at the beginning or end of the mantissa. Ticket [3998683a16a7076e08f5]. FossilOrigin-Name: ca154f97a590745539b2cbfd77eb319fd7392a40 --- diff --git a/manifest b/manifest index 24b3c8385d..607886fbf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Changes\sto\sremove\ssqlite3FitsIn64Bits(). -D 2010-09-30T16:51:26 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Do\scorrect\saffinity\stransformations\son\sfloating\spoint\svalues\swhich\shave\na\sdecimal\spoint\sat\sthe\sbeginning\sor\send\sof\sthe\smantissa.\nTicket\s[3998683a16a7076e08f5]. +D 2010-09-30T17:33:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +226,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 0cca1dff4d04bbb378e0a7c2d342396363e9f0b4 +F src/util.c cd78524566fe45671863eee78685969a4bfd4e4c F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c 447577ca9db7cccac30dd8ea07aeb6a4ddee9cde F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 @@ -337,7 +340,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/date.test 6354b883f922c38046a8efbad187cc95df6da023 +F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff F test/dbstatus.test 175b088308f2ce3f7afb8208f25c10878ee05921 F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test f7629d9eb245dfca170169cc5c7a735dec34aeb4 @@ -461,7 +464,7 @@ F test/incrblob_err.test c577c91d4ed9e8336cdb188b15d6ee2a6fe9604e F test/incrvacuum.test 453d1e490d8f5ad2c9b3a54282a0690d6ae56462 F test/incrvacuum2.test 9e22a794899c91b7d8c8e12eaacac8df249faafe F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291 -F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad +F test/index.test df7c00c6edd9504ab71c83a9514f1c5ca0fa54d8 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/indexedby.test 5a1180602f2e72c481467bd4cae05dae5dc36f47 @@ -660,6 +663,7 @@ F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 5741cd48de500347a437ba1be58c8335e83c5a5e F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac +F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 @@ -870,7 +874,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ce6cc16e3a151a0c67855abde1411422dfcc8828 -R f10482e4b62453ab01ff046fc673997a -U shaneh -Z e009fe1b0e7c264af8f0ee9d5e4c3177 +P 43fef1cab6315f837782ea601d5a2aeb9843ab3c +R 9f0571eacddb9a3dd22902b2fc6da09d +U drh +Z c3bfcfff0e351511af94c6133a9e5932 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMpMncoxKgR168RlERApVjAJ9CgWo7czjJJMuzPPhDGIuxcWDpSACeLMY+ +2nv8gkZ9kYhTsRmCj46G7ik= +=tJZ/ +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 8a49352421..8e6154f471 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43fef1cab6315f837782ea601d5a2aeb9843ab3c \ No newline at end of file +ca154f97a590745539b2cbfd77eb319fd7392a40 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 2fa178f507..4b603b3086 100644 --- a/src/util.c +++ b/src/util.c @@ -239,35 +239,47 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ /* ** The string z[] is an text representation of a real number. -** Convert this string to a double. +** Convert this string to a double and write it into *pResult. ** ** The string z[] is length bytes in length (bytes, not characters) and ** uses the encoding enc. The string is not necessarily zero-terminated. ** ** Return TRUE if the result is a valid real number (or integer) and FALSE -** if the string is empty or contains extraneous text. +** if the string is empty or contains extraneous text. Valid numbers +** are in one of these formats: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Leading and trailing whitespace is ignored for the purpose of determining +** validity. +** +** If some prefix of the input string is a valid number, this routine +** returns FALSE but it still converts the prefix and writes the result +** into *pResult. */ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr = (enc==SQLITE_UTF8?1:2); const char *zEnd = z + length; /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; + *pResult = 0.0; /* Default return value, in case of an error */ + if( enc==SQLITE_UTF16BE ) z++; /* skip leading spaces */ while( z=zEnd ){ - *pResult = 0.0; - return 0; - } + if( z>=zEnd ) return 0; /* get sign of significand */ if( *z=='-' ){ @@ -308,6 +320,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ /* if exponent is present */ if( *z=='e' || *z=='E' ){ z+=incr; + eValid = 0; if( z>=zEnd ) goto do_atof_calc; /* get sign of exponent */ if( *z=='-' ){ @@ -320,9 +333,15 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ while( z=zEnd && sqlite3Isdigit(z[-incr]); + /* return true if number and no extra non-whitespace chracters after */ + return z>=zEnd && nDigits>0 && eValid; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ diff --git a/test/date.test b/test/date.test index 29b5ed4d1d..9bfec12626 100644 --- a/test/date.test +++ b/test/date.test @@ -84,7 +84,7 @@ for {set i 0} {$i<1000} {incr i} { datetest 2.3 {date('2003-10-22','weekday 0')} 2003-10-26 datetest 2.4 {date('2003-10-22','weekday 1')} 2003-10-27 datetest 2.4a {date('2003-10-22','weekday 1')} 2003-10-27 -datetest 2.4b {date('2003-10-22','weekday 1x')} 2003-10-27 +datetest 2.4b {date('2003-10-22','weekday 1x')} NULL datetest 2.4c {date('2003-10-22','weekday -1')} NULL datetest 2.4d {date('2003-10-22','weakday 1x')} NULL datetest 2.4e {date('2003-10-22','weekday ')} NULL diff --git a/test/index.test b/test/index.test index a278ac8889..0a41a6de3e 100644 --- a/test/index.test +++ b/test/index.test @@ -532,10 +532,19 @@ do_test index-15.2 { INSERT INTO t1 VALUES('+',9); INSERT INTO t1 VALUES('+12347.E+02',10); INSERT INTO t1 VALUES('+12347E+02',11); - SELECT b FROM t1 ORDER BY a; + INSERT INTO t1 VALUES('+.125E+04',12); + INSERT INTO t1 VALUES('-.125E+04',13); + INSERT INTO t1 VALUES('.125E+0',14); + INSERT INTO t1 VALUES('.125',15); + SELECT b FROM t1 ORDER BY a, b; } -} {8 5 2 1 3 6 11 9 10 4 7} -integrity_check index-15.1 +} {13 14 15 12 8 5 2 1 3 6 10 11 9 4 7} +do_test index-15.3 { + execsql { + SELECT b FROM t1 WHERE typeof(a) IN ('integer','real') ORDER BY b; + } +} {1 2 3 5 6 8 10 11 12 13 14 15} +integrity_check index-15.4 # The following tests - index-16.* - test that when a table definition # includes qualifications that specify the same constraint twice only a diff --git a/test/tkt-3998683a16.test b/test/tkt-3998683a16.test new file mode 100644 index 0000000000..919dc23368 --- /dev/null +++ b/test/tkt-3998683a16.test @@ -0,0 +1,46 @@ +# 2010 September 30 +# +# 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. +# +#*********************************************************************** +# +# This file implements regression tests for SQLite library. Specifically, +# it tests that ticket [3998683a16a7076e08f5585c1f4816414c8c653a] where in +# floating point values with a decimal point at the beginning or end +# of the mantissa are used. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt-3998683a16.1 { + db eval { + CREATE TABLE t1(x, y REAL); + INSERT INTO t1 VALUES(1, '1.0'); + INSERT INTO t1 VALUES(2, '.125'); + INSERT INTO t1 VALUES(3, '123.'); + INSERT INTO t1 VALUES(4, '123.e+2'); + INSERT INTO t1 VALUES(5, '.125e+3'); + INSERT INTO t1 VALUES(6, '123e4'); + INSERT INTO t1 VALUES(11, ' 1.0'); + INSERT INTO t1 VALUES(12, ' .125'); + INSERT INTO t1 VALUES(13, ' 123.'); + INSERT INTO t1 VALUES(14, ' 123.e+2'); + INSERT INTO t1 VALUES(15, ' .125e+3'); + INSERT INTO t1 VALUES(16, ' 123e4'); + INSERT INTO t1 VALUES(21, '1.0 '); + INSERT INTO t1 VALUES(22, '.125 '); + INSERT INTO t1 VALUES(23, '123. '); + INSERT INTO t1 VALUES(24, '123.e+2 '); + INSERT INTO t1 VALUES(25, '.125e+3 '); + INSERT INTO t1 VALUES(26, '123e4 '); + SELECT x FROM t1 WHERE typeof(y)=='real' ORDER BY x; + } +} {1 2 3 4 5 6 11 12 13 14 15 16 21 22 23 24 25 26} + +finish_test