/ Check-in [43fef1ca]
Login

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

Overview
Comment:Changes to remove sqlite3FitsIn64Bits().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 43fef1cab6315f837782ea601d5a2aeb9843ab3c
User & Date: shaneh 2010-09-30 16:51:26
Context
2010-09-30
17:33
Do correct affinity transformations on floating point values which have a decimal point at the beginning or end of the mantissa. Ticket [3998683a16a7076e08f5]. check-in: ca154f97 user: drh tags: experimental
16:51
Changes to remove sqlite3FitsIn64Bits(). check-in: 43fef1ca user: shaneh tags: experimental
14:48
Fix the handling of default values for ALTER TABLE ADD COLUMN columns so that is able to deal with negative numbers, including large negative numbers. Ticket [8454a207b9fd2243c4] check-in: ce6cc16e user: drh tags: experimental
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
....
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945


1946
1947
1948
1949


1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
    /* Wildcard of the form "?".  Assign the next variable number */
    assert( z[0]=='?' );
    pExpr->iColumn = (ynVar)(++pParse->nVar);
  }else if( z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    i64 i;
    int bOk = sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8);
    pExpr->iColumn = (ynVar)i;
    testcase( i==0 );
    testcase( i==1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
    if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
................................................................................
#endif


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] into register iMem.
**
** The z[] string will probably not be zero-terminated.  But the 
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
  Vdbe *v = pParse->pVdbe;
  if( pExpr->flags & EP_IntValue ){
    int i = pExpr->u.iValue;
    if( negFlag ) i = -i;
    sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
  }else{


    const char *z = pExpr->u.zToken;
    assert( z!=0 );
    if( sqlite3FitsIn64Bits(z, negFlag) ){
      i64 value;


      char *zV;
      sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
      if( negFlag ) value = -value;
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
    }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
      sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
      codeReal(v, z, negFlag, iMem);







|







 







|
<
<








>
>


<
<
>
>

<
|







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
....
1928
1929
1930
1931
1932
1933
1934
1935


1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947


1948
1949
1950

1951
1952
1953
1954
1955
1956
1957
1958
    /* Wildcard of the form "?".  Assign the next variable number */
    assert( z[0]=='?' );
    pExpr->iColumn = (ynVar)(++pParse->nVar);
  }else if( z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    i64 i;
    int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8);
    pExpr->iColumn = (ynVar)i;
    testcase( i==0 );
    testcase( i==1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
    testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
    if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
................................................................................
#endif


/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] into register iMem.
**
** Expr.u.zToken is always UTF8 and zero-terminated.


*/
static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
  Vdbe *v = pParse->pVdbe;
  if( pExpr->flags & EP_IntValue ){
    int i = pExpr->u.iValue;
    if( negFlag ) i = -i;
    sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
  }else{
    int c;
    i64 value;
    const char *z = pExpr->u.zToken;
    assert( z!=0 );


    c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
    if( c==0 || (c==2 && negFlag) ){
      char *zV;

      if( negFlag ){ value = -value; }
      zV = dup8bytes(v, (char*)&value);
      sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
    }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
      sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
      codeReal(v, z, negFlag, iMem);

Changes to src/sqliteInt.h.

2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3AtoF(const char *z, double*, int, u8);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *, int);
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
int sqlite3Utf8Read(const u8*, const u8**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c







<







2824
2825
2826
2827
2828
2829
2830

2831
2832
2833
2834
2835
2836
2837
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3AtoF(const char *z, double*, int, u8);
int sqlite3GetInt32(const char *, int*);

int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
int sqlite3Utf8Read(const u8*, const u8**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c

Changes to src/test1.c.

1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  char *z;
  if( argc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FORMAT INT INT INT\"", 0);
    return TCL_ERROR;
  }
  for(i=2; i<5; i++){
    if( !sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
      Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
      return TCL_ERROR;
    }
  }
  z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
  Tcl_AppendResult(interp, z, 0);
  sqlite3_free(z);







|







1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  char *z;
  if( argc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FORMAT INT INT INT\"", 0);
    return TCL_ERROR;
  }
  for(i=2; i<5; i++){
    if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
      Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
      return TCL_ERROR;
    }
  }
  z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
  Tcl_AppendResult(interp, z, 0);
  sqlite3_free(z);

Changes to src/util.c.

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
...
417
418
419
420
421
422
423
424
425




426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
      result = (double)s;
    }
  }

  /* store the result */
  *pResult = result;

  /* return number of bytes used */
  return z>=zEnd && sqlite3Isdigit(z[-incr]);
#else
  return sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}

/*
** Compare the 19-character string zNum against the text representation
** value 2^63:  9223372036854775808.  Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.

**
** Unlike memcmp() this routine is guaranteed to return the difference
** in the values of the last digit if the only difference is in the
** last digit.  So, for example,
**
**      compare2pow63("9223372036854775800", 1)
**
................................................................................
    testcase( c==(+1) );
  }
  return c;
}


/*
** Return TRUE if zNum is a 64-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer




** or is an integer that is too large to be expressed with 64 bits,
** then return false.
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated.  The encoding is
** given by enc.
*/
int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
  int incr = (enc==SQLITE_UTF8?1:2);
  i64 v = 0;
  int neg = 0;
  int i;
  int c = 0;
  const char *zStart;
  const char *zEnd = zNum + length;
  if( enc==SQLITE_UTF16BE ) zNum++;
  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
  if( zNum>=zEnd ) goto do_atoi_calc;
  if( *zNum=='-' ){
    neg = 1;
    zNum+=incr;
  }else if( *zNum=='+' ){
    neg = 0;
    zNum+=incr;
  }else{
    neg = 0;
  }
do_atoi_calc:
  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){
    v = v*10 + c - '0';
  }
  *pNum = neg ? -v : v;
  testcase( i==18 );
  testcase( i==19 );
  testcase( i==20 );
  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
    /* zNum is empty or contains non-numeric text or is longer
    ** than 19 digits (thus guaranting that it is too large) */
    return 0;
  }else if( i<19*incr ){
    /* Less than 19 digits, so we know that it fits in 64 bits */
    return 1;
  }else{
    /* 19-digit numbers must be no larger than 9223372036854775807 if positive
    ** or 9223372036854775808 if negative.  Note that 9223372036854665808
    ** is 2^63. */
    return compare2pow63(zNum, incr)<neg;
  }
}

/*
** The string zNum represents an unsigned integer.  The zNum string
** consists of one or more digit characters and is terminated by
** a zero character.  Any stray characters in zNum result in undefined
** behavior.
**
** If the unsigned integer that zNum represents will fit in a
** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** If the negFlag parameter is true, that means that zNum really represents
** a negative number.  (The leading "-" is omitted from zNum.)  This
** parameter is needed to determine a boundary case.  A string
** of "9223373036854775808" returns false if negFlag is false or true
** if negFlag is true.
**
** Leading zeros are ignored.
*/
int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
  int i;
  int neg = 0;

  assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */

  if( negFlag ) neg = 1-neg;
  while( *zNum=='0' ){
    zNum++;   /* Skip leading zeros.  Ticket #2454 */
  }
  for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
  testcase( i==18 );
  testcase( i==19 );
  testcase( i==20 );
  if( i<19 ){
    /* Guaranteed to fit if less than 19 digits */

    return 1;
  }else if( i>19 ){
    /* Guaranteed to be too big if greater than 19 digits */
    return 0;
  }else{
    /* Compare against 2^63. */
    return compare2pow63(zNum, 1)<neg;
  }
}

/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
**







|


|







>







 







|
|
>
>
>
>
|
|








|











<

<
<













|
|


|



|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453


454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476




































477
478






479
480
481
482
483
484
485
      result = (double)s;
    }
  }

  /* store the result */
  *pResult = result;

  /* return true if number and no extra chracters after */
  return z>=zEnd && sqlite3Isdigit(z[-incr]);
#else
  return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}

/*
** Compare the 19-character string zNum against the text representation
** value 2^63:  9223372036854775808.  Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.
** Note that zNum must contain exactly 19 characters.
**
** Unlike memcmp() this routine is guaranteed to return the difference
** in the values of the last digit if the only difference is in the
** last digit.  So, for example,
**
**      compare2pow63("9223372036854775800", 1)
**
................................................................................
    testcase( c==(+1) );
  }
  return c;
}


/*
** Convert zNum to a 64-bit signed integer and write
** the value of the integer into *pNum.
** If zNum is exactly 9223372036854665808, return 2.
** This is a special case as the context will determine
** if it is too big (used as a negative).
** If zNum is not an integer or is an integer that 
** is too large to be expressed with 64 bits,
** then return 1.  Otherwise return 0.
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated.  The encoding is
** given by enc.
*/
int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
  int incr = (enc==SQLITE_UTF8?1:2);
  i64 v = 0;
  int neg = 0; /* assume positive */
  int i;
  int c = 0;
  const char *zStart;
  const char *zEnd = zNum + length;
  if( enc==SQLITE_UTF16BE ) zNum++;
  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
  if( zNum>=zEnd ) goto do_atoi_calc;
  if( *zNum=='-' ){
    neg = 1;
    zNum+=incr;
  }else if( *zNum=='+' ){

    zNum+=incr;


  }
do_atoi_calc:
  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){
    v = v*10 + c - '0';
  }
  *pNum = neg ? -v : v;
  testcase( i==18 );
  testcase( i==19 );
  testcase( i==20 );
  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
    /* zNum is empty or contains non-numeric text or is longer
    ** than 19 digits (thus guaranteeing that it is too large) */
    return 1;
  }else if( i<19*incr ){
    /* Less than 19 digits, so we know that it fits in 64 bits */
    return 0;
  }else{
    /* 19-digit numbers must be no larger than 9223372036854775807 if positive
    ** or 9223372036854775808 if negative.  Note that 9223372036854665808
    ** is 2^63. Return 1 if to large */
    c=compare2pow63(zNum, incr);




































    if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
    return c<neg ? 0 : 1;






  }
}

/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
**

Changes to src/vdbe.c.

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
static void applyNumericAffinity(Mem *pRec){
  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
    double rValue;
    i64 iValue;
    u8 enc = pRec->enc;
    if( (pRec->flags&MEM_Str)==0 ) return;
    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
    if( sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
      pRec->u.i = iValue;
      pRec->flags |= MEM_Int;
    }else{
      pRec->r = rValue;
      pRec->flags |= MEM_Real;
    }
  }







|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
static void applyNumericAffinity(Mem *pRec){
  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
    double rValue;
    i64 iValue;
    u8 enc = pRec->enc;
    if( (pRec->flags&MEM_Str)==0 ) return;
    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
    if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
      pRec->u.i = iValue;
      pRec->flags |= MEM_Int;
    }else{
      pRec->r = rValue;
      pRec->flags |= MEM_Real;
    }
  }

Changes to src/vdbemem.c.

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
      MemSetTypeFlag(pMem, MEM_Int);
    }else{
      pMem->r = sqlite3VdbeRealValue(pMem);
      MemSetTypeFlag(pMem, MEM_Real);
      sqlite3VdbeIntegerAffinity(pMem);
    }
  }







|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
      MemSetTypeFlag(pMem, MEM_Int);
    }else{
      pMem->r = sqlite3VdbeRealValue(pMem);
      MemSetTypeFlag(pMem, MEM_Real);
      sqlite3VdbeIntegerAffinity(pMem);
    }
  }

Changes to test/expr.test.

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  test_expr expr-4.10 {r1='0.0', r2='abc'} {r1>r2} 0
  test_expr expr-4.11 {r1='abc', r2='Abc'} {r1<r2} 0
  test_expr expr-4.12 {r1='abc', r2='Abc'} {r1>r2} 1
  test_expr expr-4.13 {r1='abc', r2='Bbc'} {r1<r2} 0
  test_expr expr-4.14 {r1='abc', r2='Bbc'} {r1>r2} 1
  test_expr expr-4.15 {r1='0', r2='0.0'} {r1==r2} 1
  test_expr expr-4.16 {r1='0.000', r2='0.0'} {r1==r2} 1
  test_expr expr-4.17 {r1=' 0.000', r2=' 0.0'} {r1==r2} 0
  test_expr expr-4.18 {r1='0.0', r2='abc'} {r1<r2} 1
  test_expr expr-4.19 {r1='0.0', r2='abc'} {r1==r2} 0
  test_expr expr-4.20 {r1='0.0', r2='abc'} {r1>r2} 0
}

# CSL is true if LIKE is case sensitive and false if not.
# NCSL is the opposite.  Use these variables as the result







|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  test_expr expr-4.10 {r1='0.0', r2='abc'} {r1>r2} 0
  test_expr expr-4.11 {r1='abc', r2='Abc'} {r1<r2} 0
  test_expr expr-4.12 {r1='abc', r2='Abc'} {r1>r2} 1
  test_expr expr-4.13 {r1='abc', r2='Bbc'} {r1<r2} 0
  test_expr expr-4.14 {r1='abc', r2='Bbc'} {r1>r2} 1
  test_expr expr-4.15 {r1='0', r2='0.0'} {r1==r2} 1
  test_expr expr-4.16 {r1='0.000', r2='0.0'} {r1==r2} 1
  test_expr expr-4.17 {r1=' 0.000', r2=' 0.0'} {r1==r2} 1
  test_expr expr-4.18 {r1='0.0', r2='abc'} {r1<r2} 1
  test_expr expr-4.19 {r1='0.0', r2='abc'} {r1==r2} 0
  test_expr expr-4.20 {r1='0.0', r2='abc'} {r1>r2} 0
}

# CSL is true if LIKE is case sensitive and false if not.
# NCSL is the opposite.  Use these variables as the result