/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/util.c.

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  }
  zStart = zNum;
  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
    u = u*10 + c - '0';
  }
  if( u>LARGEST_INT64 ){
    *pNum = SMALLEST_INT64;
  }else if( neg ){
    *pNum = -(i64)u;
  }else{
    *pNum = (i64)u;
  }
  testcase( i==18 );
  testcase( i==19 );
................................................................................
    }else if( c>0 ){
      /* zNum is greater than 9223372036854775808 so it overflows */
      return 1;
    }else{
      /* 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;
    }
  }
}

/*
** If zNum represents an integer that will fit in 32-bits, then set







|







 







<







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
...
539
540
541
542
543
544
545

546
547
548
549
550
551
552
  }
  zStart = zNum;
  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
    u = u*10 + c - '0';
  }
  if( u>LARGEST_INT64 ){
    *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
  }else if( neg ){
    *pNum = -(i64)u;
  }else{
    *pNum = (i64)u;
  }
  testcase( i==18 );
  testcase( i==19 );
................................................................................
    }else if( c>0 ){
      /* zNum is greater than 9223372036854775808 so it overflows */
      return 1;
    }else{
      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
      ** special case 2 overflow if positive */
      assert( u-1==LARGEST_INT64 );

      return neg ? 0 : 2;
    }
  }
}

/*
** If zNum represents an integer that will fit in 32-bits, then set

Changes to src/vdbe.c.

3510
3511
3512
3513
3514
3515
3516
3517


3518
3519
3520
3521
3522
3523
3524
        pc = pOp->p2 - 1;
        break;
      }
      /* If we reach this point, then the P3 value must be a floating
      ** point number. */
      assert( (pIn3->flags & MEM_Real)!=0 );

      if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){


        /* The P3 value is too large in magnitude to be expressed as an
        ** integer. */
        res = 1;
        if( pIn3->r<0 ){
          if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt );
            rc = sqlite3BtreeFirst(pC->pCursor, &res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;







|
>
>







3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
        pc = pOp->p2 - 1;
        break;
      }
      /* If we reach this point, then the P3 value must be a floating
      ** point number. */
      assert( (pIn3->flags & MEM_Real)!=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;
        if( pIn3->r<0 ){
          if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt );
            rc = sqlite3BtreeFirst(pC->pCursor, &res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;

Changes to src/vdbemem.c.

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
  p->z = 0;
  p->zMalloc = 0;
  p->xDel = 0;
}

/*
** 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.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
  /* When floating-point is omitted, double and int64 are the same thing */
  return r;
#else
  /*
................................................................................
  ** inconsistently.  And many do not understand the "LL" notation.
  ** So we define our own static constants here using nothing
  ** larger than a 32-bit integer constant.
  */
  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. */
    return minInt;
  }else{
    return (i64)r;
  }
#endif
}

/*
................................................................................
  **
  **    (1) the round-trip conversion real->int->real is a no-op, and
  **    (2) The integer is neither the largest nor the smallest
  **        possible integer (ticket #3922)
  **
  ** 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.
  */
  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;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.







|
|
<
<
<
<
<
<
<







 







|

|
<
<
<
<
|







 







|
<
<



<
<
<

<







299
300
301
302
303
304
305
306
307







308
309
310
311
312
313
314
...
317
318
319
320
321
322
323
324
325
326




327
328
329
330
331
332
333
334
...
402
403
404
405
406
407
408
409


410
411
412



413

414
415
416
417
418
419
420
  p->z = 0;
  p->zMalloc = 0;
  p->xDel = 0;
}

/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** 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
  /* When floating-point is omitted, double and int64 are the same thing */
  return r;
#else
  /*
................................................................................
  ** inconsistently.  And many do not understand the "LL" notation.
  ** So we define our own static constants here using nothing
  ** larger than a 32-bit integer constant.
  */
  static const i64 maxInt = LARGEST_INT64;
  static const i64 minInt = SMALLEST_INT64;

  if( r<=(double)minInt ){
    return minInt;
  }else if( r>=(double)maxInt ){




    return maxInt;
  }else{
    return (i64)r;
  }
#endif
}

/*
................................................................................
  **
  **    (1) the round-trip conversion real->int->real is a no-op, and
  **    (2) The integer is neither the largest nor the smallest
  **        possible integer (ticket #3922)
  **
  ** The second and third terms in the following conditional enforces
  ** the second condition under the assumption that addition overflow causes
  ** values to wrap around.


  */
  if( pMem->r==(double)pMem->u.i
   && pMem->u.i>SMALLEST_INT64



   && pMem->u.i<LARGEST_INT64

  ){
    pMem->flags |= MEM_Int;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.

Changes to test/autoinc.test.

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







|







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

Changes to test/e_expr.test.

1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0

# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
# 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.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


# 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.
#







|






|







1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1
do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0

# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as
# 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 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 9223372036854775807


# 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.
#