Change the REAL-to-INTEGER casting behavior so that if the REAL value

is greater than 9223372036854775807.0 then it is cast to the latest
possible integer, 9223372036854775807.  This is sensible and the way
most platforms work in hardware.  The former behavior was that oversize
REALs would be cast to the smallest possible integer, -9223372036854775808,
which is the way Intel hardware works.

FossilOrigin-Name: 6f53fc7106658d44edf63068f9a8522fa5a7688b
This commit is contained in:
drh 2013-11-26 15:45:02 +00:00
parent dad19c3204
commit de1a8b8c69
7 changed files with 25 additions and 41 deletions

View File

@ -1,5 +1,5 @@
C Better\ssupport\sfor\sUTF-8\spaths\son\sCygwin.
D 2013-11-26T00:28:50.946
C Change\sthe\sREAL-to-INTEGER\scasting\sbehavior\sso\sthat\sif\sthe\sREAL\svalue\nis\sgreater\sthan\s9223372036854775807.0\sthen\sit\sis\scast\sto\sthe\slatest\npossible\sinteger,\s9223372036854775807.\s\sThis\sis\ssensible\sand\sthe\sway\nmost\splatforms\swork\sin\shardware.\s\sThe\sformer\sbehavior\swas\sthat\soversize\nREALs\swould\sbe\scast\sto\sthe\ssmallest\spossible\sinteger,\s-9223372036854775808,\nwhich\sis\sthe\sway\sIntel\shardware\sworks.
D 2013-11-26T15:45:02.186
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -278,15 +278,15 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba
F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 23d0cfba65b6dadf39a0805d0fba266e8146d678
F src/vdbe.c 061d30aea5bbe70926236836be259ed217ee65c0
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
F src/vdbeaux.c a880c3c7d7c58543574ff7c96feddc5a1deaeae2
F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde
F src/vdbemem.c cd02a6ade205ebe989983b7e3d64a5358b8e5e1f
F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
@ -330,7 +330,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f
F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test d4dfe14001dfcb74cfbd7107f45a79fc1ab6183e
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
F test/e_expr.test 7d7feeadb555b49476e9ca4a145fcf7c0a81ce34
F test/e_expr.test 0808bc72c7b2a2fab4291418ecd73f4d09d7d671
F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0
@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 914e6c9d88828b66e8385c4a264702471faa34cf 484162b6e5a8ad9385fe2eb2a5254d13d7b0bc36
R 1b8f9bd2dcb67783ed3f85d3422a2824
U mistachkin
Z f0ab176076e12054e72ef7c2fe54ec51
P 9954327c0febc0ece46f62e05976330a1b82b48f
R 55fc64123fadbe14b9ab9765d23a7587
U drh
Z 850b84acf394562818ad72b52ff1802d

View File

@ -1 +1 @@
9954327c0febc0ece46f62e05976330a1b82b48f
6f53fc7106658d44edf63068f9a8522fa5a7688b

View File

@ -512,7 +512,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
u = u*10 + c - '0';
}
if( u>LARGEST_INT64 ){
*pNum = SMALLEST_INT64;
*pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
@ -543,7 +543,6 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
assert( (*pNum)==SMALLEST_INT64 );
return neg ? 0 : 2;
}
}

View File

@ -3514,7 +3514,9 @@ case OP_SeekGt: { /* jump, in3 */
** point number. */
assert( (pIn3->flags & MEM_Real)!=0 );
if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){
if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey)
|| (iKey==LARGEST_INT64 && pIn3->r>(double)iKey)
){
/* The P3 value is too large in magnitude to be expressed as an
** integer. */
res = 1;

View File

@ -303,15 +303,8 @@ void sqlite3VdbeMemRelease(Mem *p){
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is too large, return 0x8000000000000000.
**
** Most systems appear to do this simply by assigning
** variables and without the extra range tests. But
** there are reports that windows throws an expection
** if the floating point value is out of range. (See ticket #2880.)
** Because we do not completely understand the problem, we will
** take the conservative approach and always do range tests
** before attempting the conversion.
** If the double is out of range of a 64-bit signed integer then
** return the closest available 64-bit signed integer.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
@ -328,14 +321,10 @@ static i64 doubleToInt64(double r){
static const i64 maxInt = LARGEST_INT64;
static const i64 minInt = SMALLEST_INT64;
if( r<(double)minInt ){
return minInt;
}else if( r>(double)maxInt ){
/* minInt is correct here - not maxInt. It turns out that assigning
** a very large positive number to an integer results in a very large
** negative integer. This makes no sense, but it is what x86 hardware
** does so for compatibility we will do the same in software. */
if( r<=(double)minInt ){
return minInt;
}else if( r>=(double)maxInt ){
return maxInt;
}else{
return (i64)r;
}
@ -417,17 +406,11 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
**
** The second and third terms in the following conditional enforces
** the second condition under the assumption that addition overflow causes
** values to wrap around. On x86 hardware, the third term is always
** true and could be omitted. But we leave it in because other
** architectures might behave differently.
** values to wrap around.
*/
if( pMem->r==(double)pMem->u.i
&& pMem->u.i>SMALLEST_INT64
#if defined(__i486__) || defined(__x86_64__)
&& ALWAYS(pMem->u.i<LARGEST_INT64)
#else
&& pMem->u.i<LARGEST_INT64
#endif
){
pMem->flags |= MEM_Int;
}

View File

@ -216,7 +216,7 @@ do_test autoinc-2.27 {
} {t1 1238}
do_test autoinc-2.28 {
execsql {
UPDATE sqlite_sequence SET seq='12345678901234567890'
UPDATE sqlite_sequence SET seq='-12345678901234567890'
WHERE name='t1';
INSERT INTO t1 VALUES(NULL,6);
SELECT * FROM t1;

View File

@ -1606,14 +1606,14 @@ do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0
# an INTEGER then the result of the cast is the largest negative
# integer: -9223372036854775808.
#
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer -9223372036854775808
do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807
do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
do_expr_test e_expr-31.2.3 {
CAST(-9223372036854775809.0 AS INT)
} integer -9223372036854775808
do_expr_test e_expr-31.2.4 {
CAST(9223372036854775809.0 AS INT)
} integer -9223372036854775808
} integer 9223372036854775807
# EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC