]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do correct affinity transformations on floating point values which have
authordrh <drh@noemail.net>
Thu, 30 Sep 2010 17:33:11 +0000 (17:33 +0000)
committerdrh <drh@noemail.net>
Thu, 30 Sep 2010 17:33:11 +0000 (17:33 +0000)
a decimal point at the beginning or end of the mantissa.
Ticket [3998683a16a7076e08f5].

FossilOrigin-Name: ca154f97a590745539b2cbfd77eb319fd7392a40

manifest
manifest.uuid
src/util.c
test/date.test
test/index.test
test/tkt-3998683a16.test [new file with mode: 0644]

index 24b3c8385d3eebc125593b199a8feecba3aa18a1..607886fbf260bea79c5a349a3d027c686063f3eb 100644 (file)
--- 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-----
index 8a4935242135e003b4f3f7e7a50b22b2033dff59..8e6154f471c021654737c0c1c3bf0168b92ebf1a 100644 (file)
@@ -1 +1 @@
-43fef1cab6315f837782ea601d5a2aeb9843ab3c
\ No newline at end of file
+ca154f97a590745539b2cbfd77eb319fd7392a40
\ No newline at end of file
index 2fa178f5074a253b5397119b4e73301901b78771..4b603b3086a09df25909c4d9e8630a2f22d7f209 100644 (file)
@@ -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 && sqlite3Isspace(*z) ) z+=incr;
-  if( 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) ){
       e = e*10 + (*z - '0');
       z+=incr;
+      eValid = 1;
     }
   }
 
+  /* skip trailing spaces */
+  if( nDigits && eValid ){
+    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
+  }
+
 do_atof_calc:
   /* adjust exponent by d, and update sign */
   e = (e*esign) + d;
@@ -382,8 +401,8 @@ do_atof_calc:
   /* store the result */
   *pResult = result;
 
-  /* return true if number and no extra chracters after */
-  return 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 */
index 29b5ed4d1d5d6a273ed8a0681db64072510c8e5b..9bfec12626b955bcc241dd03d76071e4eae4984a 100644 (file)
@@ -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
index a278ac8889cf535062155ae4bdbc9fe14622e1b7..0a41a6de3ee60e346a2cd843bf29118624ed910b 100644 (file)
@@ -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 (file)
index 0000000..919dc23
--- /dev/null
@@ -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