]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure a CAST to "NUMERIC" results in an integer if the value can be
authordrh <drh@noemail.net>
Mon, 10 Jun 2019 18:33:16 +0000 (18:33 +0000)
committerdrh <drh@noemail.net>
Mon, 10 Jun 2019 18:33:16 +0000 (18:33 +0000)
losslessly expressed as an integer, as the documentation requires.
Ticket [dd6bffbfb6e61db9].

FossilOrigin-Name: c0c90961b4fa1c1185772d04fe1915bc1a1af27ed8ddb8db1c524bf90d68ccbf

manifest
manifest.uuid
src/vdbe.c
src/vdbemem.c
test/cast.test
test/e_expr.test

index 722c863cab0f3a8460d3f0e60becdabf706f2efc..1a36cae4413c70eec8a7902ff9da8e2b234cfad8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Handle\srenaming\sa\scolumn\sor\stable\swhen\sthe\sschema\scontains\sa\s(meaningless)\sindex\son\sthe\sconstant\sexpression\s('text'\sIN\s())\sor\s('text'\sNOT\sIN()).
-D 2019-06-10T15:34:16.336
+C Make\ssure\sa\sCAST\sto\s"NUMERIC"\sresults\sin\san\sinteger\sif\sthe\svalue\scan\sbe\nlosslessly\sexpressed\sas\san\sinteger,\sas\sthe\sdocumentation\srequires.\nTicket\s[dd6bffbfb6e61db9].
+D 2019-06-10T18:33:16.336
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -594,13 +594,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
 F src/util.c 11e0e5e43850e29571301a3f3b87f43ad69a8ebaef99c69f8ac23793230ab7f9
 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
-F src/vdbe.c 51989be8322328fabc04a257dc207427646a6c165c51c6fe2260e783b72a9f9c
+F src/vdbe.c 42a7966812a5c3305cadd3e1060a0e962d6674e4a647fcc153e8693ecf59af74
 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
 F src/vdbeaux.c 3a803d75875031309204df90977059b12ffb706d16b4baa5e2d99f4353962582
 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
-F src/vdbemem.c be520020f89c02de6e0a0df6767e37a4a2eeef3ec7bf9ae64ad6ba32005c19fb
+F src/vdbemem.c 44ef1a12855e0c866082622a60520d89194887b805390d8da3d9b5fd36897454
 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
@@ -723,7 +723,7 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
 F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b
 F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4
 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
-F test/cast.test 6505b8aecc0e17079536103328add23fe63418530d1f827e46c32e4151a29daf
+F test/cast.test 9fa79845ef0f701082bea0f86bfe4aa22bf714e8369862f227dfc8fd1c24879d
 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
 F test/check.test dcc952a127c394ce0de2aa634d26c78207e855327cc63a24d3638ca8fbfa641e
 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
@@ -821,7 +821,7 @@ F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76
 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
 F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
 F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
-F test/e_expr.test 8cd7d85270cc7b1bca4cad6dc1c65f2d414b8851d0a13eb4eed0aa27a3516b9a
+F test/e_expr.test 628c1c5990e7df71bee17c83afcf59f31c3d34914b829ac098ee3a72b2f1d061
 F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe
 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
@@ -1830,7 +1830,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 94b58ab059cba9771e75f16d1460f313104a8fb879f9f8805725d362aa58cbcd
-R 690f23cd3c9b330abd9f7860557c7bc2
-U dan
-Z 9f6778172efe3826af7afd3381a81ce6
+P 567b13093956185b5d5e971b81ba4788fd9d26c03688f643b380f0f1c1a94da0
+R e1f8a32b710aa9d301370151b67c84ba
+U drh
+Z a526308cb484ae4690504962aa2e9239
index 4c3d0191a5042326924d23705fd2fc5020c939b0..1e38aae0f1c788b2dc784dd828e545208417cb64 100644 (file)
@@ -1 +1 @@
-567b13093956185b5d5e971b81ba4788fd9d26c03688f643b380f0f1c1a94da0
\ No newline at end of file
+c0c90961b4fa1c1185772d04fe1915bc1a1af27ed8ddb8db1c524bf90d68ccbf
\ No newline at end of file
index 55656f2a68102835faf25980b4ebb8520a8f8968..d37ba1ccebd2b552eb0a4712966f77301143f0a2 100644 (file)
@@ -285,17 +285,8 @@ static VdbeCursor *allocateCursor(
 static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
   i64 iValue = (double)rValue;
   if( sqlite3RealSameAsInt(rValue,iValue) ){
-    testcase( iValue<-2251799813685248 );
-    testcase( iValue==-2251799813685248 );
-    testcase( iValue==-2251799813685247 );
-    testcase( iValue>-2251799813685247 && iValue<+2251799813685247 );
-    testcase( iValue==+2251799813685247 );
-    testcase( iValue==+2251799813685248 );
-    testcase( iValue>+2251799813685248 );
-    if( iValue > -2251799813685248 && iValue < 2251799813685248 ){
-      *piValue = iValue;
-      return 1;
-    }
+    *piValue = iValue;
+    return 1;
   }
   return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
 }
index a139714a18cba85a3387434c4c2615ca3f35c97d..ab3c378d87a7ce521dfe034ac9c9e266045984a7 100644 (file)
@@ -699,7 +699,8 @@ int sqlite3VdbeMemRealify(Mem *pMem){
 */
 int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
   double r2 = (double)i;
-  return memcmp(&r1, &r2, sizeof(r1))==0;
+  return memcmp(&r1, &r2, sizeof(r1))==0
+      && i > -2251799813685248 && i < 2251799813685248;
 }
 
 /*
@@ -721,14 +722,9 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
     assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
     rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
-    if( rc<=0 ){
-      if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
-        pMem->u.i = ix;
-        MemSetTypeFlag(pMem, MEM_Int);
-      }else{
-        MemSetTypeFlag(pMem, MEM_Real);
-      }
-    }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
+    if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
+     || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
+    ){
       pMem->u.i = ix;
       MemSetTypeFlag(pMem, MEM_Int);
     }else{
index 8247636867a01fa7173cca20946aaa7137530dd7..6519d6db78e3fc57b24fb11e10aa0cf698e72108 100644 (file)
@@ -371,7 +371,8 @@ do_execsql_test cast-5.2 {
 do_execsql_test case-5.3 {
   SELECT CAST('123e+5' AS INTEGER);
   SELECT CAST('123e+5' AS NUMERIC);
-} {123 12300000.0}
+  SELECT CAST('123e+5' AS REAL);
+} {123 12300000 12300000.0}
 
 
 # The following does not have anything to do with the CAST operator,
@@ -415,4 +416,19 @@ do_execsql_test case-7.12 {
   SELECT '' - 1;
 } {-1}
 
+# 2019-06-10
+# https://www.sqlite.org/src/info/dd6bffbfb6e61db9
+#
+# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
+# first does a forced conversion into REAL but then further converts the
+# result into INTEGER if and only if the conversion from REAL to INTEGER
+# is lossless and reversible.
+#
+do_execsql_test cast-7.20 {
+  DROP TABLE IF EXISTS t0;
+  CREATE TABLE t0 (c0 TEXT);
+  INSERT INTO t0(c0) VALUES ('1.0');
+  SELECT CAST(c0 AS NUMERIC) FROM t0;
+} {1}
+
 finish_test
index 75618a6e06724175e3b418205f56ed615eda98e4..66725bd2ee7d262f4c9186b50e39d57fd3d853cb 100644 (file)
@@ -1650,7 +1650,7 @@ do_expr_test e_expr-31.2.4 {
 # is lossless and reversible.
 #
 do_expr_test e_expr-32.1.1 { CAST('45'   AS NUMERIC)  } integer 45
-do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC)  } real 45.0
+do_expr_test e_expr-32.1.2 { CAST('45.0' AS NUMERIC)  } integer 45
 do_expr_test e_expr-32.1.3 { CAST('45.2' AS NUMERIC)  } real 45.2
 do_expr_test e_expr-32.1.4 { CAST('11abc' AS NUMERIC) } integer 11
 do_expr_test e_expr-32.1.5 { CAST('11.1abc' AS NUMERIC) } real 11.1
@@ -1709,8 +1709,8 @@ do_execsql_test e_expr-32.2.8 {
  real 9.22337203685478e+18 \
  real 9.22337203685478e+18 \
  real 9.22337203685478e+18 \
real -5.0 \
real -5.0 \
integer -5 \
integer -5 \
 ]
 
 # EVIDENCE-OF: R-64550-29191 Note that the result from casting any