/ Check-in [6f53fc71]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6f53fc7106658d44edf63068f9a8522fa5a7688b
User & Date: drh 2013-11-26 15:45:02
Context
2013-11-26
16:20
Do not try to run the atof1.test test script on ARM hardware which lacks the "long double" type. check-in: fafca560 user: drh tags: trunk
15:45
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. check-in: 6f53fc71 user: drh tags: trunk
00:28
Better support for UTF-8 paths on Cygwin. check-in: 9954327c user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/util.c.

   508    508     }
   509    509     zStart = zNum;
   510    510     while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
   511    511     for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
   512    512       u = u*10 + c - '0';
   513    513     }
   514    514     if( u>LARGEST_INT64 ){
   515         -    *pNum = SMALLEST_INT64;
          515  +    *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
   516    516     }else if( neg ){
   517    517       *pNum = -(i64)u;
   518    518     }else{
   519    519       *pNum = (i64)u;
   520    520     }
   521    521     testcase( i==18 );
   522    522     testcase( i==19 );
................................................................................
   539    539       }else if( c>0 ){
   540    540         /* zNum is greater than 9223372036854775808 so it overflows */
   541    541         return 1;
   542    542       }else{
   543    543         /* zNum is exactly 9223372036854775808.  Fits if negative.  The
   544    544         ** special case 2 overflow if positive */
   545    545         assert( u-1==LARGEST_INT64 );
   546         -      assert( (*pNum)==SMALLEST_INT64 );
   547    546         return neg ? 0 : 2;
   548    547       }
   549    548     }
   550    549   }
   551    550   
   552    551   /*
   553    552   ** If zNum represents an integer that will fit in 32-bits, then set

Changes to src/vdbe.c.

  3510   3510           pc = pOp->p2 - 1;
  3511   3511           break;
  3512   3512         }
  3513   3513         /* If we reach this point, then the P3 value must be a floating
  3514   3514         ** point number. */
  3515   3515         assert( (pIn3->flags & MEM_Real)!=0 );
  3516   3516   
  3517         -      if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){
         3517  +      if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey)
         3518  +       || (iKey==LARGEST_INT64 && pIn3->r>(double)iKey)
         3519  +      ){
  3518   3520           /* The P3 value is too large in magnitude to be expressed as an
  3519   3521           ** integer. */
  3520   3522           res = 1;
  3521   3523           if( pIn3->r<0 ){
  3522   3524             if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt );
  3523   3525               rc = sqlite3BtreeFirst(pC->pCursor, &res);
  3524   3526               if( rc!=SQLITE_OK ) goto abort_due_to_error;

Changes to src/vdbemem.c.

   299    299     p->z = 0;
   300    300     p->zMalloc = 0;
   301    301     p->xDel = 0;
   302    302   }
   303    303   
   304    304   /*
   305    305   ** Convert a 64-bit IEEE double into a 64-bit signed integer.
   306         -** If the double is too large, return 0x8000000000000000.
   307         -**
   308         -** Most systems appear to do this simply by assigning
   309         -** variables and without the extra range tests.  But
   310         -** there are reports that windows throws an expection
   311         -** if the floating point value is out of range. (See ticket #2880.)
   312         -** Because we do not completely understand the problem, we will
   313         -** take the conservative approach and always do range tests
   314         -** before attempting the conversion.
          306  +** If the double is out of range of a 64-bit signed integer then
          307  +** return the closest available 64-bit signed integer.
   315    308   */
   316    309   static i64 doubleToInt64(double r){
   317    310   #ifdef SQLITE_OMIT_FLOATING_POINT
   318    311     /* When floating-point is omitted, double and int64 are the same thing */
   319    312     return r;
   320    313   #else
   321    314     /*
................................................................................
   324    317     ** inconsistently.  And many do not understand the "LL" notation.
   325    318     ** So we define our own static constants here using nothing
   326    319     ** larger than a 32-bit integer constant.
   327    320     */
   328    321     static const i64 maxInt = LARGEST_INT64;
   329    322     static const i64 minInt = SMALLEST_INT64;
   330    323   
   331         -  if( r<(double)minInt ){
          324  +  if( r<=(double)minInt ){
   332    325       return minInt;
   333         -  }else if( r>(double)maxInt ){
   334         -    /* minInt is correct here - not maxInt.  It turns out that assigning
   335         -    ** a very large positive number to an integer results in a very large
   336         -    ** negative integer.  This makes no sense, but it is what x86 hardware
   337         -    ** does so for compatibility we will do the same in software. */
   338         -    return minInt;
          326  +  }else if( r>=(double)maxInt ){
          327  +    return maxInt;
   339    328     }else{
   340    329       return (i64)r;
   341    330     }
   342    331   #endif
   343    332   }
   344    333   
   345    334   /*
................................................................................
   413    402     **
   414    403     **    (1) the round-trip conversion real->int->real is a no-op, and
   415    404     **    (2) The integer is neither the largest nor the smallest
   416    405     **        possible integer (ticket #3922)
   417    406     **
   418    407     ** The second and third terms in the following conditional enforces
   419    408     ** the second condition under the assumption that addition overflow causes
   420         -  ** values to wrap around.  On x86 hardware, the third term is always
   421         -  ** true and could be omitted.  But we leave it in because other
   422         -  ** architectures might behave differently.
          409  +  ** values to wrap around.
   423    410     */
   424    411     if( pMem->r==(double)pMem->u.i
   425    412      && pMem->u.i>SMALLEST_INT64
   426         -#if defined(__i486__) || defined(__x86_64__)
   427         -   && ALWAYS(pMem->u.i<LARGEST_INT64)
   428         -#else
   429    413      && pMem->u.i<LARGEST_INT64
   430         -#endif
   431    414     ){
   432    415       pMem->flags |= MEM_Int;
   433    416     }
   434    417   }
   435    418   
   436    419   /*
   437    420   ** Convert pMem to type integer.  Invalidate any prior representations.

Changes to test/autoinc.test.

   212    212   do_test autoinc-2.27 {
   213    213     execsql {
   214    214       SELECT * FROM sqlite_sequence;
   215    215     }
   216    216   } {t1 1238}
   217    217   do_test autoinc-2.28 {
   218    218     execsql {
   219         -    UPDATE sqlite_sequence SET seq='12345678901234567890'
          219  +    UPDATE sqlite_sequence SET seq='-12345678901234567890'
   220    220         WHERE name='t1';
   221    221       INSERT INTO t1 VALUES(NULL,6);
   222    222       SELECT * FROM t1;
   223    223     }
   224    224   } {235 1 1235 2 1236 3 1237 4 1238 5 1239 6}
   225    225   do_test autoinc-2.29 {
   226    226     execsql {

Changes to test/e_expr.test.

  1602   1602   do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
  1603   1603   do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0
  1604   1604   
  1605   1605   # EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
  1606   1606   # an INTEGER then the result of the cast is the largest negative
  1607   1607   # integer: -9223372036854775808.
  1608   1608   #
  1609         -do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer -9223372036854775808
         1609  +do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807
  1610   1610   do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808
  1611   1611   do_expr_test e_expr-31.2.3 { 
  1612   1612     CAST(-9223372036854775809.0 AS INT)
  1613   1613   } integer -9223372036854775808
  1614   1614   do_expr_test e_expr-31.2.4 { 
  1615   1615     CAST(9223372036854775809.0 AS INT)
  1616         -} integer -9223372036854775808
         1616  +} integer 9223372036854775807
  1617   1617   
  1618   1618   
  1619   1619   # EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC
  1620   1620   # first does a forced conversion into REAL but then further converts the
  1621   1621   # result into INTEGER if and only if the conversion from REAL to INTEGER
  1622   1622   # is lossless and reversible.
  1623   1623   #