diff --git a/manifest b/manifest index 6ee6171401..540a396ba9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\stests\sfor\smalformed\sUTF-8.\s(CVS\s4011) -D 2007-05-15T18:35:21 +C Keep\sthe\sfull\sprecision\sof\sintegers\sif\spossible\swhen\scasting\sto\s"numeric".\nTicket\s#2364.\s(CVS\s4012) +D 2007-05-16T11:55:57 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -132,14 +132,14 @@ F src/update.c 3359041db390a8f856d67272f299600e2104f350 F src/utf.c b881fe54498f6a35de424a62f8e071b621111728 F src/util.c a44710b94da6d0d606521a5e1fd40c8067282c74 F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef -F src/vdbe.c 5deb4cdccd57065ccf8a2e5c704e8473c90d204b +F src/vdbe.c 55b1d46273584bb4739e923562a71069237f9f97 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h bddb7931fc1216fda6f6720e18d2a9b1e0f8fc96 F src/vdbeapi.c f89d6bc5264e66f44589e454fbeeee96854d0dd3 F src/vdbeaux.c 62011e2ccf5fa9b3dcc7fa6ff5f0e0638d324a70 F src/vdbeblob.c 96f3572fdc45eda5be06e6372b612bc30742d9f0 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f -F src/vdbemem.c 01237a4844106b9da838fc313bf1f86ddc6b0679 +F src/vdbemem.c f04d1a25a71c41f86cad9d4dcc81abcd2a9ff403 F src/vtab.c c5ebebf615b2f29499fbe97a584c4bb342632aa0 F src/where.c f3920748cc650fc25ac916215500bdb90dee568e F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 @@ -185,7 +185,7 @@ F test/capi2.test 7ecc9b342cc9ec27b53bbf95724cf2e5874fd496 F test/capi3.test 1675323145d128e5942a9faffcfd5cf4e219a33f F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4 F test/capi3c.test 96e35164739c6fe3357fa36f0fe74bc23abc8ef7 -F test/cast.test f88e7b6946e9a467cf4bb142d92bb65a83747fc2 +F test/cast.test 6f5073af07723d15d51568508739e99855fd0fa3 F test/check.test e5ea0c1a06c10e81e3434ca029e2c4a562f2b673 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate2.test 701d9651c5707024fd86a20649af9ea55e2c0eb8 @@ -492,7 +492,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P f84d9dab110c4415d9b772f8043397640162b6b2 -R 53fa1bf671cabc8be454726443bd9326 +P 448d3ef670dce6d27c7d7b1be58088d45f8b6274 +R c8d1b4af067fdea86c8ef5e23b538719 U drh -Z 08fe10d1e019c102afe7db67bcfd77dd +Z 5f8f6c00eb0bad475fb07ee3737fa3b6 diff --git a/manifest.uuid b/manifest.uuid index 13fa24868b..792e474af7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -448d3ef670dce6d27c7d7b1be58088d45f8b6274 \ No newline at end of file +2ac985a38034da87b0fa3837976e1f2164b22672 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 68279dbbad..f00517e8f4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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.618 2007/05/12 12:08:51 drh Exp $ +** $Id: vdbe.c,v 1.619 2007/05/16 11:55:57 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1509,7 +1509,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, no-push */ */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, no-push */ assert( pTos>=p->aStack ); - if( (pTos->flags & MEM_Null)==0 ){ + if( (pTos->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){ sqlite3VdbeMemNumerify(pTos); } break; @@ -1763,8 +1763,10 @@ case OP_Or: { /* same as TK_OR, no-push */ case OP_Negative: /* same as TK_UMINUS, no-push */ case OP_AbsValue: { assert( pTos>=p->aStack ); + if( (pTos->flags & (MEM_Real|MEM_Int|MEM_Null))==0 ){ + sqlite3VdbeMemNumerify(pTos); + } if( pTos->flags & MEM_Real ){ - neg_abs_real_case: Release(pTos); if( pOp->opcode==OP_Negative || pTos->r<0.0 ){ pTos->r = -pTos->r; @@ -1776,11 +1778,6 @@ case OP_AbsValue: { pTos->u.i = -pTos->u.i; } pTos->flags = MEM_Int; - }else if( pTos->flags & MEM_Null ){ - /* Do nothing */ - }else{ - sqlite3VdbeMemNumerify(pTos); - goto neg_abs_real_case; } break; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 668eb2b546..e6e52f15bc 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -362,8 +362,20 @@ int sqlite3VdbeMemRealify(Mem *pMem){ ** Invalidate any prior representations. */ int sqlite3VdbeMemNumerify(Mem *pMem){ - sqlite3VdbeMemRealify(pMem); - sqlite3VdbeIntegerAffinity(pMem); + double r1, r2; + i64 i; + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + r1 = sqlite3VdbeRealValue(pMem); + i = (i64)r1; + r2 = (double)i; + if( r1==r2 ){ + sqlite3VdbeMemIntegerify(pMem); + }else{ + pMem->r = r1; + pMem->flags = MEM_Real; + sqlite3VdbeMemRelease(pMem); + } return SQLITE_OK; } diff --git a/test/cast.test b/test/cast.test index 75f4d03d91..0767e31ba6 100644 --- a/test/cast.test +++ b/test/cast.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CAST operator. # -# $Id: cast.test,v 1.5 2006/03/03 19:12:30 drh Exp $ +# $Id: cast.test,v 1.6 2007/05/16 11:55:57 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -192,5 +192,75 @@ do_test cast-2.2 { execsql {SELECT CAST(' -123.456' AS real)} } -123.456 +# ticket #2364. Use full percision integers if possible when casting +# to numeric. Do not fallback to real (and the corresponding 48-bit +# mantissa) unless absolutely necessary. +# +do_test cast-3.1 { + execsql {SELECT CAST(9223372036854774800 AS integer)} +} 9223372036854774800 +do_test cast-3.2 { + execsql {SELECT CAST(9223372036854774800 AS numeric)} +} 9223372036854774800 +do_test cast-3.3 { + execsql {SELECT CAST(9223372036854774800 AS real)} +} 9.22337203685477e+18 +do_test cast-3.4 { + execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)} +} 9223372036854774784 +do_test cast-3.5 { + execsql {SELECT CAST(-9223372036854774800 AS integer)} +} -9223372036854774800 +do_test cast-3.6 { + execsql {SELECT CAST(-9223372036854774800 AS numeric)} +} -9223372036854774800 +do_test cast-3.7 { + execsql {SELECT CAST(-9223372036854774800 AS real)} +} -9.22337203685477e+18 +do_test cast-3.8 { + execsql {SELECT CAST(CAST(-9223372036854774800 AS real) AS integer)} +} -9223372036854774784 +do_test cast-3.11 { + execsql {SELECT CAST('9223372036854774800' AS integer)} +} 9223372036854774800 +do_test cast-3.12 { + execsql {SELECT CAST('9223372036854774800' AS numeric)} +} 9223372036854774800 +do_test cast-3.13 { + execsql {SELECT CAST('9223372036854774800' AS real)} +} 9.22337203685477e+18 +do_test cast-3.14 { + execsql {SELECT CAST(CAST('9223372036854774800' AS real) AS integer)} +} 9223372036854774784 +do_test cast-3.15 { + execsql {SELECT CAST('-9223372036854774800' AS integer)} +} -9223372036854774800 +do_test cast-3.16 { + execsql {SELECT CAST('-9223372036854774800' AS numeric)} +} -9223372036854774800 +do_test cast-3.17 { + execsql {SELECT CAST('-9223372036854774800' AS real)} +} -9.22337203685477e+18 +do_test cast-3.18 { + execsql {SELECT CAST(CAST('-9223372036854774800' AS real) AS integer)} +} -9223372036854774784 +if {[db eval {PRAGMA encoding}]=="UTF-8"} { + do_test cast-3.21 { + execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS integer)} + } 9223372036854774800 + do_test cast-3.22 { + execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS numeric)} + } 9223372036854774800 + do_test cast-3.23 { + execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS real)} + } 9.22337203685477e+18 + do_test cast-3.24 { + execsql {SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS real) AS integer)} + } 9223372036854774784 +} +do_test case-3.31 { + execsql {SELECT CAST(NULL AS numeric)} +} {{}} + finish_test