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

Overview
Comment:Remove uses of type 'double' from the vdbe.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | sqlite4-num
Files: files | file ages | folders
SHA1: e0188231625fd452f0985d3f7e98476d4b1b34da
User & Date: dan 2013-05-31 19:19:01.946
Context
2013-05-31
19:34
Remove OP_Int64 and OP_Real. OP_Num is now used instead. Leaf check-in: 860695f9be user: dan tags: sqlite4-num
19:19
Remove uses of type 'double' from the vdbe. check-in: e018823162 user: dan tags: sqlite4-num
17:13
Use decimal arithmetic in affinity routines. check-in: ae34cd8492 user: dan tags: sqlite4-num
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/math.c.
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529






530

531
532
533
534

535

536
537
538

539
540

541
542
543
544
545
546
547
548
549
  return x;
}

/*
** TODO: This is a placeholder implementation only.
*/
int sqlite4_num_to_int32(sqlite4_num num, int *piOut){
  i64 i;
  sqlite4_num_to_int64(num, &i);
  *piOut = i;
  return SQLITE4_OK;
}

int sqlite4_num_to_double(sqlite4_num num, double *pr){
  double rRet;
  int i;
  rRet = num.m;
  if( num.sign ) rRet = rRet*-1;
  for(i=0; i<num.e; i++){
    rRet = rRet * 10.0;
  }
  for(i=num.e; i<0; i++){
    rRet = rRet / 10.0;
  }
  *pr = rRet;
  return SQLITE4_OK;
}







int sqlite4_num_to_int64(sqlite4_num num, sqlite4_int64 *piOut){

  i64 iRet;
  int i;
  iRet = num.m;
  if( num.sign ) iRet = iRet*-1;

  for(i=0; i<num.e; i++){

    iRet = iRet * 10;
  }
  for(i=num.e; i<0; i++){

    iRet = iRet / 10;
  }

  *piOut = iRet;
  return SQLITE4_OK;
}


/*
** Convert an integer into text in the buffer supplied. The
** text is zero-terminated and right-justified in the buffer.
** A pointer to the first character of text is returned.







<
|
<


















>
>
>
>
>
>
|
>



|
>

>



>


>
|
|







502
503
504
505
506
507
508

509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  return x;
}

/*
** TODO: This is a placeholder implementation only.
*/
int sqlite4_num_to_int32(sqlite4_num num, int *piOut){

  *piOut = sqlite4_num_to_int64(num, 0);

  return SQLITE4_OK;
}

int sqlite4_num_to_double(sqlite4_num num, double *pr){
  double rRet;
  int i;
  rRet = num.m;
  if( num.sign ) rRet = rRet*-1;
  for(i=0; i<num.e; i++){
    rRet = rRet * 10.0;
  }
  for(i=num.e; i<0; i++){
    rRet = rRet / 10.0;
  }
  *pr = rRet;
  return SQLITE4_OK;
}

/*
** Convert the number passed as the first argument to a signed 64-bit
** integer and return the value. If the second argument is not NULL,
** then set the value that it points to 1 if data was lost as part
** of the conversion, or 0 otherwise.
*/
sqlite4_int64 sqlite4_num_to_int64(sqlite4_num num, int *pbLossy){
  static const i64 L10 = (LARGEST_INT64 / 10);
  i64 iRet;
  int i;
  iRet = num.m;

  if( pbLossy ) *pbLossy = 0;
  for(i=0; i<num.e; i++){
    if( pbLossy && iRet>L10 ) *pbLossy = 1;
    iRet = iRet * 10;
  }
  for(i=num.e; i<0; i++){
    if( pbLossy && (iRet % 10) ) *pbLossy = 1;
    iRet = iRet / 10;
  }

  if( num.sign ) iRet = iRet*-1;
  return iRet;
}


/*
** Convert an integer into text in the buffer supplied. The
** text is zero-terminated and right-justified in the buffer.
** A pointer to the first character of text is returned.
Changes to src/sqlite.h.in.
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
int sqlite4_num_isnan(sqlite4_num);
sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
int sqlite4_num_compare(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*);
sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
sqlite4_num sqlite4_num_from_double(double);
int sqlite4_num_to_int32(sqlite4_num, int*);
int sqlite4_num_to_int64(sqlite4_num, sqlite4_int64*);
int sqlite4_num_to_double(sqlite4_num, double *);
int sqlite4_num_to_text(sqlite4_num, char*, int);

/*
** CAPI4REF: Flags For Text-To-Numeric Conversion
*/
#define SQLITE4_PREFIX_ONLY         0x10







|







4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
int sqlite4_num_isnan(sqlite4_num);
sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
int sqlite4_num_compare(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*);
sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
sqlite4_num sqlite4_num_from_double(double);
int sqlite4_num_to_int32(sqlite4_num, int*);
sqlite4_int64 sqlite4_num_to_int64(sqlite4_num, int *);
int sqlite4_num_to_double(sqlite4_num, double *);
int sqlite4_num_to_text(sqlite4_num, char*, int);

/*
** CAPI4REF: Flags For Text-To-Numeric Conversion
*/
#define SQLITE4_PREFIX_ONLY         0x10
Changes to src/vdbe.c.
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
  pIn2 = &aMem[pOp->p2];
  applyNumericAffinity(pIn2);
  pOut = &aMem[pOp->p3];
  flags = pIn1->flags | pIn2->flags;
  if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;

  if( (pIn1->flags&MEM_Int) && (pIn2->flags&MEM_Int) ){
    sqlite4_num_to_int64(pIn1->u.num, &iA);
    sqlite4_num_to_int64(pIn2->u.num, &iB);

    switch( pOp->opcode ){
      case OP_Add:       if( sqlite4AddInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite4SubInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite4MulInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Divide: {
        if( iA==0 ) goto arithmetic_result_is_null;







|
|







1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
  pIn2 = &aMem[pOp->p2];
  applyNumericAffinity(pIn2);
  pOut = &aMem[pOp->p3];
  flags = pIn1->flags | pIn2->flags;
  if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;

  if( (pIn1->flags&MEM_Int) && (pIn2->flags&MEM_Int) ){
    iA = sqlite4_num_to_int64(pIn1->u.num, 0);
    iB = sqlite4_num_to_int64(pIn2->u.num, 0);

    switch( pOp->opcode ){
      case OP_Add:       if( sqlite4AddInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite4SubInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite4MulInt64(&iB,iA) ) goto fp_math;  break;
      case OP_Divide: {
        if( iA==0 ) goto arithmetic_result_is_null;
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
      case OP_Subtract: 
        pOut->u.num = sqlite4_num_sub(num2, num1); break;
      case OP_Multiply: 
        pOut->u.num = sqlite4_num_mul(num1, num2); break;
      case OP_Divide: 
        pOut->u.num = sqlite4_num_div(num2, num1); break;
      default: {
        sqlite4_num_to_int64(num1, &iA);
        sqlite4_num_to_int64(num2, &iB);
        if( iA==0 ) goto arithmetic_result_is_null;
        pOut->u.num = sqlite4_num_from_int64(iB % iA);
        break;
      }
    }

    if( sqlite4_num_isnan(pOut->u.num) ){







|
|







1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
      case OP_Subtract: 
        pOut->u.num = sqlite4_num_sub(num2, num1); break;
      case OP_Multiply: 
        pOut->u.num = sqlite4_num_mul(num1, num2); break;
      case OP_Divide: 
        pOut->u.num = sqlite4_num_div(num2, num1); break;
      default: {
        iA = sqlite4_num_to_int64(num1, 0);
        iB = sqlite4_num_to_int64(num2, 0);
        if( iA==0 ) goto arithmetic_result_is_null;
        pOut->u.num = sqlite4_num_from_int64(iB % iA);
        break;
      }
    }

    if( sqlite4_num_isnan(pOut->u.num) ){
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
  Db *pDb;
  i64 v;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  pIn3 = &aMem[pOp->p3];
  sqlite4VdbeMemIntegerify(pIn3);
  sqlite4_num_to_int64(pIn3->u.num, &v);
  rc = sqlite4KVStorePutSchema(pDb->pKV, (u32)v);
  pDb->pSchema->schema_cookie = (int)v;
  db->flags |= SQLITE4_InternChanges;
  if( pOp->p1==1 ){
    /* Invalidate all prepared statements whenever the TEMP database
    ** schema is changed.  Ticket #1644 */
    sqlite4ExpirePreparedStatements(db);







|







2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
  Db *pDb;
  i64 v;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  pIn3 = &aMem[pOp->p3];
  sqlite4VdbeMemIntegerify(pIn3);
  v = sqlite4_num_to_int64(pIn3->u.num, 0);
  rc = sqlite4KVStorePutSchema(pDb->pKV, (u32)v);
  pDb->pSchema->schema_cookie = (int)v;
  db->flags |= SQLITE4_InternChanges;
  if( pOp->p1==1 ){
    /* Invalidate all prepared statements whenever the TEMP database
    ** schema is changed.  Ticket #1644 */
    sqlite4ExpirePreparedStatements(db);
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( pOp->p3 && rc==SQLITE4_OK ){
    pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3);
    assert( memIsValid(pIn3) );
    REGISTER_TRACE(pOp->p3, pIn3);
    sqlite4VdbeMemIntegerify(pIn3);
    assert( (pIn3->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
    sqlite4_num_to_int64(pIn3->u.num, &i3);
    if( i3==MAX_ROWID ){
      rc = SQLITE4_FULL;
    }
    if( v<i3 ) v = i3;
  }
#endif
  pOut->flags = MEM_Int;







|







3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( pOp->p3 && rc==SQLITE4_OK ){
    pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3);
    assert( memIsValid(pIn3) );
    REGISTER_TRACE(pOp->p3, pIn3);
    sqlite4VdbeMemIntegerify(pIn3);
    assert( (pIn3->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
    i3 = sqlite4_num_to_int64(pIn3->u.num, 0);
    if( i3==MAX_ROWID ){
      rc = SQLITE4_FULL;
    }
    if( v<i3 ) v = i3;
  }
#endif
  pOut->flags = MEM_Int;
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
      }
    }else if( rc==SQLITE4_NOTFOUND ){
      rc = SQLITE4_OK;
    }
    sqlite4KVCursorClose(pCsr);
  }

  sqlite4_num_to_int64(pIn1->u.num, &i1);
  if( i1>=(i64)iMax ){
    i1++;
  }else{
    i1 = iMax+1;
  }
  pIn1->u.num = sqlite4_num_from_int64(i1);








|







3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
      }
    }else if( rc==SQLITE4_NOTFOUND ){
      rc = SQLITE4_OK;
    }
    sqlite4KVCursorClose(pCsr);
  }

  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  if( i1>=(i64)iMax ){
    i1++;
  }else{
    i1 = iMax+1;
  }
  pIn1->u.num = sqlite4_num_from_int64(i1);

3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
    assert( memIsValid(pKey) );
    REGISTER_TRACE(pOp->p3, pKey);
    sqlite4_num_to_int64(pKey->u.num, &iKey);
  }else{
    /* assert( pOp->opcode==OP_InsertInt ); */
    iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pData->flags & MEM_Null ){







|







3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
    assert( memIsValid(pKey) );
    REGISTER_TRACE(pOp->p3, pKey);
    iKey = sqlite4_num_to_int64(pKey->u.num, 0);
  }else{
    /* assert( pOp->opcode==OP_InsertInt ); */
    iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pData->flags & MEM_Null ){
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
  Mem *pIn1;
  pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1);
  assert( memIsValid(pIn1) );
  sqlite4VdbeMemIntegerify(pIn1);
  pIn2 = &aMem[pOp->p2];
  REGISTER_TRACE(pOp->p1, pIn1);
  sqlite4VdbeMemIntegerify(pIn2);
  sqlite4_num_to_int64(pIn1->u.num, &i1);
  sqlite4_num_to_int64(pIn2->u.num, &i2);
  if( i1<i2 ){
    pIn1->u.num = sqlite4_num_from_int64(i2);
  }
  REGISTER_TRACE(pOp->p1, pIn1);
  break;
}
#endif /* SQLITE4_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 * * *
**
** If the value of register P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfPos: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  sqlite4_num_to_int64(pIn1->u.num, &i1);
  if( i1>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfNeg P1 P2 * * *
**
** If the value of register P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfNeg: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  sqlite4_num_to_int64(pIn1->u.num, &i1);
  if( i1<0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfZero P1 P2 P3 * *
**
** The register P1 must contain an integer.  Add literal P3 to the
** value in register P1.  If the result is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfZero: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  sqlite4_num_to_int64(pIn1->u.num, &i1);
  i1 += pOp->p3;
  pIn1->u.num = sqlite4_num_from_int64(i1);
  if( i1==0 ){
     pc = pOp->p2 - 1;
  }
  break;
}







|
|



















|

















|


















|







4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
  Mem *pIn1;
  pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1);
  assert( memIsValid(pIn1) );
  sqlite4VdbeMemIntegerify(pIn1);
  pIn2 = &aMem[pOp->p2];
  REGISTER_TRACE(pOp->p1, pIn1);
  sqlite4VdbeMemIntegerify(pIn2);
  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  i2 = sqlite4_num_to_int64(pIn2->u.num, 0);
  if( i1<i2 ){
    pIn1->u.num = sqlite4_num_from_int64(i2);
  }
  REGISTER_TRACE(pOp->p1, pIn1);
  break;
}
#endif /* SQLITE4_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 * * *
**
** If the value of register P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfPos: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  if( i1>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfNeg P1 P2 * * *
**
** If the value of register P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfNeg: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  if( i1<0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfZero P1 P2 P3 * *
**
** The register P1 must contain an integer.  Add literal P3 to the
** value in register P1.  If the result is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a register that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfZero: {        /* jump, in1 */
  i64 i1;
  pIn1 = &aMem[pOp->p1];
  assert( pIn1->flags&MEM_Int );
  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  i1 += pOp->p3;
  pIn1->u.num = sqlite4_num_from_int64(i1);
  if( i1==0 ){
     pc = pOp->p2 - 1;
  }
  break;
}
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
  cksum = 0;

  if( pOp->p5 ){
    sqlite4Fts5EntryCksum(db, pInfo, pKey, aArg, &cksum);
  }else{
    sqlite4Fts5RowCksum(db, pInfo, pKey, aArg, &cksum);
  }
  sqlite4_num_to_int64(pOut->u.num, &i1);
  pOut->u.num = sqlite4_num_from_int64(i1 ^ cksum);

  break;
}

/* Opcode: FtsOpen P1 P2 P3 P4 P5
**







|







4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
  cksum = 0;

  if( pOp->p5 ){
    sqlite4Fts5EntryCksum(db, pInfo, pKey, aArg, &cksum);
  }else{
    sqlite4Fts5RowCksum(db, pInfo, pKey, aArg, &cksum);
  }
  i1 = sqlite4_num_to_int64(pOut->u.num, 0);
  pOut->u.num = sqlite4_num_from_int64(i1 ^ cksum);

  break;
}

/* Opcode: FtsOpen P1 P2 P3 P4 P5
**
Changes to src/vdbeapi.c.
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099

1100



1101
1102
1103
1104
1105
1106
1107
1108
1109
){
  return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE);
}
#endif /* SQLITE4_OMIT_UTF16 */
int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){
  int rc;
  switch( pValue->type ){
    case SQLITE4_INTEGER: {
      i64 i1;
      sqlite4_num_to_int64(pValue->u.num, &i1);
      rc = sqlite4_bind_int64(pStmt, i, i1);
      break;
    }
    case SQLITE4_FLOAT: {

      double r;



      sqlite4_num_to_double(pValue->u.num, &r);
      rc = sqlite4_bind_double(pStmt, i, r);
      break;
    }
    case SQLITE4_BLOB: {
      rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
                             SQLITE4_TRANSIENT, 0);
      break;
    }







|
<
<
<
<
<

>
|
>
>
>
|
|







1086
1087
1088
1089
1090
1091
1092
1093





1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
){
  return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE);
}
#endif /* SQLITE4_OMIT_UTF16 */
int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){
  int rc;
  switch( pValue->type ){
    case SQLITE4_INTEGER:





    case SQLITE4_FLOAT: {
      Mem *p = (Mem *)pValue;
      Vdbe *v = (Vdbe *)pStmt;
      vdbeUnbind(v, i);
      v->aVar[i-1].u.num = p->u.num;
      MemSetTypeFlag(&v->aVar[i-1], 
          (pValue->type==SQLITE4_FLOAT ? MEM_Real : MEM_Int)
      );
      break;
    }
    case SQLITE4_BLOB: {
      rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
                             SQLITE4_TRANSIENT, 0);
      break;
    }
Changes to src/vdbecodec.c.
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  nOut = 9;
  for(i=0; i<nIn; i++){
    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      aOut[nOut++] = 0;
    }else if( flags & MEM_Int ){
      i64 i1;
      sqlite4_num_to_int64(aIn[i].u.num, &i1);
      n = significantBytes(i1);
      aOut[nOut++] = n+2;
      nPayload += n;
      aAux[i].n = n;
    }else if( flags & MEM_Real ){
      sqlite4_num *p = &aIn[i].u.num;
      int e;







|







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  nOut = 9;
  for(i=0; i<nIn; i++){
    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      aOut[nOut++] = 0;
    }else if( flags & MEM_Int ){
      i64 i1;
      i1 = sqlite4_num_to_int64(aIn[i].u.num, 0);
      n = significantBytes(i1);
      aOut[nOut++] = n+2;
      nPayload += n;
      aAux[i].n = n;
    }else if( flags & MEM_Real ){
      sqlite4_num *p = &aIn[i].u.num;
      int e;
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; }
  for(i=0; i<nIn; i++){
    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      /* No content */
    }else if( flags & MEM_Int ){
      sqlite4_int64 v;
      sqlite4_num_to_int64(aIn[i].u.num, &v);
      n = aAux[i].n;
      aOut[nOut+(--n)] = v & 0xff;
      while( n ){
        v >>= 8;
        aOut[nOut+(--n)] = v & 0xff;
      }
      nOut += aAux[i].n;







|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  if( aOut==0 ){ rc = SQLITE4_NOMEM; goto vdbeEncodeData_error; }
  for(i=0; i<nIn; i++){
    int flags = aIn[i].flags;
    if( flags & MEM_Null ){
      /* No content */
    }else if( flags & MEM_Int ){
      sqlite4_int64 v;
      v = sqlite4_num_to_int64(aIn[i].u.num, 0);
      n = aAux[i].n;
      aOut[nOut+(--n)] = v & 0xff;
      while( n ){
        v >>= 8;
        aOut[nOut+(--n)] = v & 0xff;
      }
      nOut += aAux[i].n;
Changes to src/vdbemem.c.
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
** If pMem is a string or blob, then we make an attempt to convert
** it into a integer and return that.  If pMem represents an
** an SQL-NULL value, return 0.
**
** If pMem represents a string value, its encoding might be changed.
*/
i64 sqlite4VdbeIntValue(Mem *pMem){
  int flags;
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );
  flags = pMem->flags;
  if( flags & (MEM_Int|MEM_Real) ){
    i64 i1;
    sqlite4_num_to_int64(pMem->u.num, &i1);
    return i1;
  }else if( flags & (MEM_Str|MEM_Blob) ){
    i64 value = 0;
    assert( pMem->z || pMem->n==0 );
    testcase( pMem->z==0 );
    sqlite4Atoi64(pMem->z, &value, pMem->n, pMem->enc);
    return value;
  }else{
    return 0;
  }
}

/*
** Return the best representation of pMem that we can get into a
** double.  If pMem is already a double or an integer, return its
** value.  If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.







<


<
<
<
|
<
<
<
<
<
<
<
<
<
<







308
309
310
311
312
313
314

315
316



317










318
319
320
321
322
323
324
** If pMem is a string or blob, then we make an attempt to convert
** it into a integer and return that.  If pMem represents an
** an SQL-NULL value, return 0.
**
** If pMem represents a string value, its encoding might be changed.
*/
i64 sqlite4VdbeIntValue(Mem *pMem){

  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );



  return sqlite4_num_to_int64(sqlite4VdbeNumValue(pMem), 0);










}

/*
** Return the best representation of pMem that we can get into a
** double.  If pMem is already a double or an integer, return its
** value.  If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
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
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
** Extract and return a numeric value from memory cell pMem. This call
** does not modify the contents or flags of *pMem in any way.
*/
sqlite4_num sqlite4VdbeNumValue(Mem *pMem){
  if( pMem->flags & (MEM_Real|MEM_Int) ){
    return pMem->u.num;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    int flags = SQLITE4_PREFIX_ONLY | pMem->enc;
    return sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
  }else{
    sqlite4_num zero = {0,0,0,0};
    return zero;
  }
}

/*
** The MEM structure is already a MEM_Real.  Try to also make it a
** MEM_Int if we can.
*/
void sqlite4VdbeIntegerAffinity(Mem *pMem){
  i64 i;
  double r;

  assert( pMem->flags & MEM_Real );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  sqlite4_num_to_int64(pMem->u.num, &i);
  sqlite4_num_to_double(pMem->u.num, &r);

  /* Only mark the value as an integer if
  **
  **    (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( r==(double)i && i>SMALLEST_INT64 && ALWAYS(i<LARGEST_INT64) ){
    pMem->u.num = sqlite4_num_from_int64(i);
    MemSetTypeFlag(pMem, MEM_Int);
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
int sqlite4VdbeMemIntegerify(Mem *pMem){
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  if( (pMem->flags & MEM_Int)==0 ){
    sqlite4VdbeMemNumerify(pMem);
  }
  if( (pMem->flags & MEM_Int)==0 ){
    if( pMem->flags & MEM_Real ){
      i64 iVal;
      sqlite4_num_to_int64(pMem->u.num, &iVal);
      pMem->u.num = sqlite4_num_from_int64(iVal);
    }else{
      pMem->u.num = sqlite4_num_from_int64(0);
    }
  }

  MemSetTypeFlag(pMem, MEM_Int);
  return SQLITE4_OK;
}

/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**







|













|






|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<

<












<
<
<
<
<
<
|
<
|
|
<
<
<







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365













366

367
368
369
370
371
372
373
374
375
376
377
378






379

380
381



382
383
384
385
386
387
388
** Extract and return a numeric value from memory cell pMem. This call
** does not modify the contents or flags of *pMem in any way.
*/
sqlite4_num sqlite4VdbeNumValue(Mem *pMem){
  if( pMem->flags & (MEM_Real|MEM_Int) ){
    return pMem->u.num;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    int flags = SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE | pMem->enc;
    return sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
  }else{
    sqlite4_num zero = {0,0,0,0};
    return zero;
  }
}

/*
** The MEM structure is already a MEM_Real.  Try to also make it a
** MEM_Int if we can.
*/
void sqlite4VdbeIntegerAffinity(Mem *pMem){
  i64 i;
  int bLossy;

  assert( pMem->flags & MEM_Real );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  i = sqlite4_num_to_int64(pMem->u.num, &bLossy);
  if( bLossy==0 ){
    MemSetTypeFlag(pMem, MEM_Int);













    pMem->u.num = sqlite4_num_from_int64(i);

  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
int sqlite4VdbeMemIntegerify(Mem *pMem){
  assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
  assert( (pMem->flags & MEM_RowSet)==0 );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

  if( (pMem->flags & MEM_Int)==0 ){






    pMem->u.num = sqlite4_num_from_int64(sqlite4VdbeIntValue(pMem));

    MemSetTypeFlag(pMem, MEM_Int);
  }



  return SQLITE4_OK;
}

/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
**
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){
    if( !(f1&(MEM_Int|MEM_Real)) ){
      return 1;
    }
    if( !(f2&(MEM_Int|MEM_Real)) ){
      return -1;
    }
    if( (f1 & f2 & MEM_Int)==0 ){
      double r1, r2;
      sqlite4_num_to_double(pMem1->u.num, &r1);
      sqlite4_num_to_double(pMem2->u.num, &r2);
      if( r1<r2 ) return -1;
      if( r1>r2 ) return 1;
      return 0;
    }else{
      i64 i1, i2;
      sqlite4_num_to_int64(pMem1->u.num, &i1);
      sqlite4_num_to_int64(pMem2->u.num, &i2);
      assert( f1&MEM_Int );
      assert( f2&MEM_Int );
      if( i1<i2 ) return -1;
      if( i1>i2 ) return 1;
      return 0;
    }
  }

  /* If one value is a string and the other is a blob, the string is less.
  ** If both are strings, compare using the collating functions.
  */
  if( combined_flags&MEM_Str ){
    if( (f1 & MEM_Str)==0 ){







|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







690
691
692
693
694
695
696
697


698
699


















700
701
702
703
704
705
706
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){
    if( !(f1&(MEM_Int|MEM_Real)) ) return 1;


    if( !(f2&(MEM_Int|MEM_Real)) ) return -1;
    return (sqlite4_num_compare(pMem1->u.num, pMem2->u.num) - 2);


















  }

  /* If one value is a string and the other is a blob, the string is less.
  ** If both are strings, compare using the collating functions.
  */
  if( combined_flags&MEM_Str ){
    if( (f1 & MEM_Str)==0 ){