/ Check-in [4c8c89d7]
Login

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

Overview
Comment:Merge the Mem.r value into the MemValue union as Mem.u.r. Hence, a Mem can now store an integer or a real but not both at the same time. Strings are still stored in a separate element Mem.z, for now.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4c8c89d7e62aecfe2eb735f7bb114aed6b452847
User & Date: drh 2014-09-18 17:52:15
Context
2014-09-18
18:55
Correct typos in comments. No changes to code. check-in: 55879932 user: mistachkin tags: trunk
17:52
Merge the Mem.r value into the MemValue union as Mem.u.r. Hence, a Mem can now store an integer or a real but not both at the same time. Strings are still stored in a separate element Mem.z, for now. check-in: 4c8c89d7 user: drh tags: trunk
16:28
Performance improvement for affinity transformations on comparison operators. check-in: d7afdcba user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   239    239   ** if there is an exact integer representation of the quantity.
   240    240   */
   241    241   static void applyNumericAffinity(Mem *pRec, int bTryForInt){
   242    242     double rValue;
   243    243     i64 iValue;
   244    244     u8 enc = pRec->enc;
   245    245     if( (pRec->flags&MEM_Str)==0 ) return;
          246  +  if( (pRec->flags&(MEM_Int|MEM_Real))!=0 ) return;
   246    247     if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
   247    248     if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
   248    249       pRec->u.i = iValue;
   249    250       pRec->flags |= MEM_Int;
   250    251     }else{
   251         -    pRec->r = rValue;
          252  +    pRec->u.r = rValue;
   252    253       pRec->flags |= MEM_Real;
   253    254       if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
   254    255     }
   255    256   }
   256    257   
   257    258   /*
   258    259   ** Processing is determine by the affinity parameter:
................................................................................
   325    326   ){
   326    327     applyAffinity((Mem *)pVal, affinity, enc);
   327    328   }
   328    329   
   329    330   /*
   330    331   ** pMem currently only holds a string type (or maybe a BLOB that we can
   331    332   ** interpret as a string if we want to).  Compute its corresponding
   332         -** numeric type, if has one.  Set the pMem->r and pMem->u.i fields
          333  +** numeric type, if has one.  Set the pMem->u.r and pMem->u.i fields
   333    334   ** accordingly.
   334    335   */
   335    336   static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
   336    337     assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
   337    338     assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
   338         -  if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){
          339  +  if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
   339    340       return 0;
   340    341     }
   341    342     if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
   342    343       return MEM_Int;
   343    344     }
   344    345     return MEM_Real;
   345    346   }
   346    347   
   347    348   /*
   348    349   ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
   349    350   ** none.  
   350    351   **
   351    352   ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
   352         -** But it does set pMem->r and pMem->u.i appropriately.
          353  +** But it does set pMem->u.r and pMem->u.i appropriately.
   353    354   */
   354    355   static u16 numericType(Mem *pMem){
   355    356     if( pMem->flags & (MEM_Int|MEM_Real) ){
   356    357       return pMem->flags & (MEM_Int|MEM_Real);
   357    358     }
   358    359     if( pMem->flags & (MEM_Str|MEM_Blob) ){
   359    360       return computeNumericType(pMem);
................................................................................
   455    456       printf(" NULL");
   456    457     }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
   457    458       printf(" si:%lld", p->u.i);
   458    459     }else if( p->flags & MEM_Int ){
   459    460       printf(" i:%lld", p->u.i);
   460    461   #ifndef SQLITE_OMIT_FLOATING_POINT
   461    462     }else if( p->flags & MEM_Real ){
   462         -    printf(" r:%g", p->r);
          463  +    printf(" r:%g", p->u.r);
   463    464   #endif
   464    465     }else if( p->flags & MEM_RowSet ){
   465    466       printf(" (rowset)");
   466    467     }else{
   467    468       char zBuf[200];
   468    469       sqlite3VdbeMemPrettyPrint(p, zBuf);
   469    470       printf(" %s", zBuf);
................................................................................
   998    999   **
   999   1000   ** P4 is a pointer to a 64-bit floating point value.
  1000   1001   ** Write that value into register P2.
  1001   1002   */
  1002   1003   case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
  1003   1004     pOut->flags = MEM_Real;
  1004   1005     assert( !sqlite3IsNaN(*pOp->p4.pReal) );
  1005         -  pOut->r = *pOp->p4.pReal;
         1006  +  pOut->u.r = *pOp->p4.pReal;
  1006   1007     break;
  1007   1008   }
  1008   1009   #endif
  1009   1010   
  1010   1011   /* Opcode: String8 * P2 * P4 *
  1011   1012   ** Synopsis: r[P2]='P4'
  1012   1013   **
................................................................................
  1475   1476   #ifdef SQLITE_OMIT_FLOATING_POINT
  1476   1477       pOut->u.i = rB;
  1477   1478       MemSetTypeFlag(pOut, MEM_Int);
  1478   1479   #else
  1479   1480       if( sqlite3IsNaN(rB) ){
  1480   1481         goto arithmetic_result_is_null;
  1481   1482       }
  1482         -    pOut->r = rB;
         1483  +    pOut->u.r = rB;
  1483   1484       MemSetTypeFlag(pOut, MEM_Real);
  1484   1485       if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
  1485   1486         sqlite3VdbeIntegerAffinity(pOut);
  1486   1487       }
  1487   1488   #endif
  1488   1489     }
  1489   1490     break;
................................................................................
  3568   3569         /* If the approximation iKey is larger than the actual real search
  3569   3570         ** term, substitute >= for > and < for <=. e.g. if the search term
  3570   3571         ** is 4.9 and the integer approximation 5:
  3571   3572         **
  3572   3573         **        (x >  4.9)    ->     (x >= 5)
  3573   3574         **        (x <= 4.9)    ->     (x <  5)
  3574   3575         */
  3575         -      if( pIn3->r<(double)iKey ){
         3576  +      if( pIn3->u.r<(double)iKey ){
  3576   3577           assert( OP_SeekGE==(OP_SeekGT-1) );
  3577   3578           assert( OP_SeekLT==(OP_SeekLE-1) );
  3578   3579           assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
  3579   3580           if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--;
  3580   3581         }
  3581   3582   
  3582   3583         /* If the approximation iKey is smaller than the actual real search
  3583   3584         ** term, substitute <= for < and > for >=.  */
  3584         -      else if( pIn3->r>(double)iKey ){
         3585  +      else if( pIn3->u.r>(double)iKey ){
  3585   3586           assert( OP_SeekLE==(OP_SeekLT+1) );
  3586   3587           assert( OP_SeekGT==(OP_SeekGE+1) );
  3587   3588           assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
  3588   3589           if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
  3589   3590         }
  3590   3591       } 
  3591   3592       rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);

Changes to src/vdbeInt.h.

   157    157   
   158    158   /*
   159    159   ** Internally, the vdbe manipulates nearly all SQL values as Mem
   160    160   ** structures. Each Mem struct may cache multiple representations (string,
   161    161   ** integer etc.) of the same value.
   162    162   */
   163    163   struct Mem {
   164         -  union {
          164  +  union MemValue {
          165  +    double r;           /* Real value used when MEM_Realis set in flags */
   165    166       i64 i;              /* Integer value used when MEM_Int is set in flags */
   166    167       int nZero;          /* Used when bit MEM_Zero is set in flags */
   167    168       FuncDef *pDef;      /* Used only when flags==MEM_Agg */
   168    169       RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   169    170       VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   170    171     } u;
   171    172     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   172    173     u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
   173    174     int n;              /* Number of characters in string value, excluding '\0' */
   174         -  double r;           /* Real value */
   175    175     char *z;            /* String or BLOB value */
   176         -  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
   177    176     /* ShallowCopy only needs to copy the information above */
          177  +  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
   178    178     sqlite3 *db;        /* The associated database connection */
   179    179     void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
   180    180   #ifdef SQLITE_DEBUG
   181    181     Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   182    182     void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
   183    183   #endif
   184    184   };

Changes to src/vdbeapi.c.

   803    803       __attribute__((aligned(8))) 
   804    804   #endif
   805    805       = {
   806    806           /* .u          = */ {0},
   807    807           /* .flags      = */ MEM_Null,
   808    808           /* .enc        = */ 0,
   809    809           /* .n          = */ 0,
   810         -        /* .r          = */ (double)0,
   811    810           /* .z          = */ 0,
   812    811           /* .zMalloc    = */ 0,
   813    812           /* .db         = */ 0,
   814    813           /* .xDel       = */ 0,
   815    814   #ifdef SQLITE_DEBUG
   816    815           /* .pScopyFrom = */ 0,
   817    816           /* .pFiller    = */ 0,
................................................................................
  1268   1267     int rc;
  1269   1268     switch( sqlite3_value_type((sqlite3_value*)pValue) ){
  1270   1269       case SQLITE_INTEGER: {
  1271   1270         rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
  1272   1271         break;
  1273   1272       }
  1274   1273       case SQLITE_FLOAT: {
  1275         -      rc = sqlite3_bind_double(pStmt, i, pValue->r);
         1274  +      rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
  1276   1275         break;
  1277   1276       }
  1278   1277       case SQLITE_BLOB: {
  1279   1278         if( pValue->flags & MEM_Zero ){
  1280   1279           rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
  1281   1280         }else{
  1282   1281           rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT);

Changes to src/vdbeaux.c.

  1072   1072       case P4_MEM: {
  1073   1073         Mem *pMem = pOp->p4.pMem;
  1074   1074         if( pMem->flags & MEM_Str ){
  1075   1075           zP4 = pMem->z;
  1076   1076         }else if( pMem->flags & MEM_Int ){
  1077   1077           sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
  1078   1078         }else if( pMem->flags & MEM_Real ){
  1079         -        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
         1079  +        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
  1080   1080         }else if( pMem->flags & MEM_Null ){
  1081   1081           sqlite3_snprintf(nTemp, zTemp, "NULL");
  1082   1082         }else{
  1083   1083           assert( pMem->flags & MEM_Blob );
  1084   1084           zP4 = "(blob)";
  1085   1085         }
  1086   1086         break;
................................................................................
  2945   2945     u32 len;
  2946   2946   
  2947   2947     /* Integer and Real */
  2948   2948     if( serial_type<=7 && serial_type>0 ){
  2949   2949       u64 v;
  2950   2950       u32 i;
  2951   2951       if( serial_type==7 ){
  2952         -      assert( sizeof(v)==sizeof(pMem->r) );
  2953         -      memcpy(&v, &pMem->r, sizeof(v));
         2952  +      assert( sizeof(v)==sizeof(pMem->u.r) );
         2953  +      memcpy(&v, &pMem->u.r, sizeof(v));
  2954   2954         swapMixedEndianFloat(v);
  2955   2955       }else{
  2956   2956         v = pMem->u.i;
  2957   2957       }
  2958   2958       len = i = sqlite3VdbeSerialTypeLen(serial_type);
  2959   2959       assert( i>0 );
  2960   2960       do{
................................................................................
  3016   3016       */
  3017   3017       static const u64 t1 = ((u64)0x3ff00000)<<32;
  3018   3018       static const double r1 = 1.0;
  3019   3019       u64 t2 = t1;
  3020   3020       swapMixedEndianFloat(t2);
  3021   3021       assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
  3022   3022   #endif
  3023         -    assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
         3023  +    assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
  3024   3024       swapMixedEndianFloat(x);
  3025         -    memcpy(&pMem->r, &x, sizeof(x));
  3026         -    pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
         3025  +    memcpy(&pMem->u.r, &x, sizeof(x));
         3026  +    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
  3027   3027     }
  3028   3028     return 8;
  3029   3029   }
  3030   3030   u32 sqlite3VdbeSerialGet(
  3031   3031     const unsigned char *buf,     /* Buffer to deserialize from */
  3032   3032     u32 serial_type,              /* Serial type to deserialize */
  3033   3033     Mem *pMem                     /* Memory cell to write value into */
................................................................................
  3364   3364       double r1, r2;
  3365   3365       if( (f1 & f2 & MEM_Int)!=0 ){
  3366   3366         if( pMem1->u.i < pMem2->u.i ) return -1;
  3367   3367         if( pMem1->u.i > pMem2->u.i ) return 1;
  3368   3368         return 0;
  3369   3369       }
  3370   3370       if( (f1&MEM_Real)!=0 ){
  3371         -      r1 = pMem1->r;
         3371  +      r1 = pMem1->u.r;
  3372   3372       }else if( (f1&MEM_Int)!=0 ){
  3373   3373         r1 = (double)pMem1->u.i;
  3374   3374       }else{
  3375   3375         return 1;
  3376   3376       }
  3377   3377       if( (f2&MEM_Real)!=0 ){
  3378         -      r2 = pMem2->r;
         3378  +      r2 = pMem2->u.r;
  3379   3379       }else if( (f2&MEM_Int)!=0 ){
  3380   3380         r2 = (double)pMem2->u.i;
  3381   3381       }else{
  3382   3382         return -1;
  3383   3383       }
  3384   3384       if( r1<r2 ) return -1;
  3385   3385       if( r1>r2 ) return 1;
................................................................................
  3532   3532         if( serial_type>=12 ){
  3533   3533           rc = +1;
  3534   3534         }else if( serial_type==0 ){
  3535   3535           rc = -1;
  3536   3536         }else if( serial_type==7 ){
  3537   3537           double rhs = (double)pRhs->u.i;
  3538   3538           sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
  3539         -        if( mem1.r<rhs ){
         3539  +        if( mem1.u.r<rhs ){
  3540   3540             rc = -1;
  3541         -        }else if( mem1.r>rhs ){
         3541  +        }else if( mem1.u.r>rhs ){
  3542   3542             rc = +1;
  3543   3543           }
  3544   3544         }else{
  3545   3545           i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
  3546   3546           i64 rhs = pRhs->u.i;
  3547   3547           if( lhs<rhs ){
  3548   3548             rc = -1;
................................................................................
  3556   3556       else if( pRhs->flags & MEM_Real ){
  3557   3557         serial_type = aKey1[idx1];
  3558   3558         if( serial_type>=12 ){
  3559   3559           rc = +1;
  3560   3560         }else if( serial_type==0 ){
  3561   3561           rc = -1;
  3562   3562         }else{
  3563         -        double rhs = pRhs->r;
         3563  +        double rhs = pRhs->u.r;
  3564   3564           double lhs;
  3565   3565           sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
  3566   3566           if( serial_type==7 ){
  3567         -          lhs = mem1.r;
         3567  +          lhs = mem1.u.r;
  3568   3568           }else{
  3569   3569             lhs = (double)mem1.u.i;
  3570   3570           }
  3571   3571           if( lhs<rhs ){
  3572   3572             rc = -1;
  3573   3573           }else if( lhs>rhs ){
  3574   3574             rc = +1;

Changes to src/vdbemem.c.

    27     27   */
    28     28   int sqlite3VdbeCheckMemInvariants(Mem *p){
    29     29     /* If MEM_Dyn is set then Mem.xDel!=0.  
    30     30     ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
    31     31     */
    32     32     assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
    33     33   
           34  +  /* Cannot be both MEM_Int and MEM_Real at the same time */
           35  +  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
           36  +
    34     37     /* If p holds a string or blob, the Mem.z must point to exactly
    35     38     ** one of the following:
    36     39     **
    37     40     **   (1) Memory in Mem.zMalloc and managed by the Mem object
    38     41     **   (2) Memory to be freed using Mem.xDel
    39     42     **   (3) An ephemeral string or blob
    40     43     **   (4) A static string or blob
................................................................................
   260    263     ** 
   261    264     ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
   262    265     */
   263    266     if( fg & MEM_Int ){
   264    267       sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
   265    268     }else{
   266    269       assert( fg & MEM_Real );
   267         -    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
          270  +    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
   268    271     }
   269    272     pMem->n = sqlite3Strlen30(pMem->z);
   270    273     pMem->enc = SQLITE_UTF8;
   271    274     pMem->flags |= MEM_Str|MEM_Term;
   272    275     if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
   273    276     sqlite3VdbeChangeEncoding(pMem, enc);
   274    277     return SQLITE_OK;
................................................................................
   417    420     int flags;
   418    421     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   419    422     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   420    423     flags = pMem->flags;
   421    424     if( flags & MEM_Int ){
   422    425       return pMem->u.i;
   423    426     }else if( flags & MEM_Real ){
   424         -    return doubleToInt64(pMem->r);
          427  +    return doubleToInt64(pMem->u.r);
   425    428     }else if( flags & (MEM_Str|MEM_Blob) ){
   426    429       i64 value = 0;
   427    430       assert( pMem->z || pMem->n==0 );
   428    431       sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
   429    432       return value;
   430    433     }else{
   431    434       return 0;
................................................................................
   438    441   ** value.  If it is a string or blob, try to convert it to a double.
   439    442   ** If it is a NULL, return 0.0.
   440    443   */
   441    444   double sqlite3VdbeRealValue(Mem *pMem){
   442    445     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   443    446     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   444    447     if( pMem->flags & MEM_Real ){
   445         -    return pMem->r;
          448  +    return pMem->u.r;
   446    449     }else if( pMem->flags & MEM_Int ){
   447    450       return (double)pMem->u.i;
   448    451     }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
   449    452       /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
   450    453       double val = (double)0;
   451    454       sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
   452    455       return val;
................................................................................
   457    460   }
   458    461   
   459    462   /*
   460    463   ** The MEM structure is already a MEM_Real.  Try to also make it a
   461    464   ** MEM_Int if we can.
   462    465   */
   463    466   void sqlite3VdbeIntegerAffinity(Mem *pMem){
          467  +  i64 ix;
   464    468     assert( pMem->flags & MEM_Real );
   465    469     assert( (pMem->flags & MEM_RowSet)==0 );
   466    470     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   467    471     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   468    472   
   469         -  pMem->u.i = doubleToInt64(pMem->r);
          473  +  ix = doubleToInt64(pMem->u.r);
   470    474   
   471    475     /* Only mark the value as an integer if
   472    476     **
   473    477     **    (1) the round-trip conversion real->int->real is a no-op, and
   474    478     **    (2) The integer is neither the largest nor the smallest
   475    479     **        possible integer (ticket #3922)
   476    480     **
   477    481     ** The second and third terms in the following conditional enforces
   478    482     ** the second condition under the assumption that addition overflow causes
   479    483     ** values to wrap around.
   480    484     */
   481         -  if( pMem->r==(double)pMem->u.i
   482         -   && pMem->u.i>SMALLEST_INT64
   483         -   && pMem->u.i<LARGEST_INT64
   484         -  ){
   485         -    pMem->flags |= MEM_Int;
          485  +  if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
          486  +    pMem->u.i = ix;
          487  +    MemSetTypeFlag(pMem, MEM_Int);
   486    488     }
   487    489   }
   488    490   
   489    491   /*
   490    492   ** Convert pMem to type integer.  Invalidate any prior representations.
   491    493   */
   492    494   int sqlite3VdbeMemIntegerify(Mem *pMem){
................................................................................
   503    505   ** Convert pMem so that it is of type MEM_Real.
   504    506   ** Invalidate any prior representations.
   505    507   */
   506    508   int sqlite3VdbeMemRealify(Mem *pMem){
   507    509     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   508    510     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   509    511   
   510         -  pMem->r = sqlite3VdbeRealValue(pMem);
          512  +  pMem->u.r = sqlite3VdbeRealValue(pMem);
   511    513     MemSetTypeFlag(pMem, MEM_Real);
   512    514     return SQLITE_OK;
   513    515   }
   514    516   
   515    517   /*
   516    518   ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
   517    519   ** Invalidate any prior representations.
................................................................................
   523    525   int sqlite3VdbeMemNumerify(Mem *pMem){
   524    526     if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
   525    527       assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
   526    528       assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   527    529       if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
   528    530         MemSetTypeFlag(pMem, MEM_Int);
   529    531       }else{
   530         -      pMem->r = sqlite3VdbeRealValue(pMem);
          532  +      pMem->u.r = sqlite3VdbeRealValue(pMem);
   531    533         MemSetTypeFlag(pMem, MEM_Real);
   532    534         sqlite3VdbeIntegerAffinity(pMem);
   533    535       }
   534    536     }
   535    537     assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
   536    538     pMem->flags &= ~(MEM_Str|MEM_Blob);
   537    539     return SQLITE_OK;
................................................................................
   659    661   /*
   660    662   ** Delete any previous value and set the value stored in *pMem to val,
   661    663   ** manifest type REAL.
   662    664   */
   663    665   void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
   664    666     sqlite3VdbeMemSetNull(pMem);
   665    667     if( !sqlite3IsNaN(val) ){
   666         -    pMem->r = val;
          668  +    pMem->u.r = val;
   667    669       pMem->flags = MEM_Real;
   668    670     }
   669    671   }
   670    672   #endif
   671    673   
   672    674   /*
   673    675   ** Delete any previous value and set the value of pMem to be an
................................................................................
  1164   1166       }
  1165   1167     }else if( op==TK_UMINUS ) {
  1166   1168       /* This branch happens for multiple negative signs.  Ex: -(-5) */
  1167   1169       if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) 
  1168   1170        && pVal!=0
  1169   1171       ){
  1170   1172         sqlite3VdbeMemNumerify(pVal);
  1171         -      if( pVal->u.i==SMALLEST_INT64 ){
  1172         -        pVal->flags &= ~MEM_Int;
  1173         -        pVal->flags |= MEM_Real;
  1174         -        pVal->r = (double)SMALLEST_INT64;
         1173  +      if( pVal->flags & MEM_Real ){
         1174  +        pVal->u.r = -pVal->u.r;
         1175  +      }else if( pVal->u.i==SMALLEST_INT64 ){
         1176  +        pVal->u.r = -(double)SMALLEST_INT64;
         1177  +        MemSetTypeFlag(pVal, MEM_Real);
  1175   1178         }else{
  1176   1179           pVal->u.i = -pVal->u.i;
  1177   1180         }
  1178         -      pVal->r = -pVal->r;
  1179   1181         sqlite3ValueApplyAffinity(pVal, affinity, enc);
  1180   1182       }
  1181   1183     }else if( op==TK_NULL ){
  1182   1184       pVal = valueNew(db, pCtx);
  1183   1185       if( pVal==0 ) goto no_mem;
  1184   1186     }
  1185   1187   #ifndef SQLITE_OMIT_BLOB_LITERAL

Changes to src/vdbetrace.c.

   123    123         assert( idx>0 && idx<=p->nVar );
   124    124         pVar = &p->aVar[idx-1];
   125    125         if( pVar->flags & MEM_Null ){
   126    126           sqlite3StrAccumAppend(&out, "NULL", 4);
   127    127         }else if( pVar->flags & MEM_Int ){
   128    128           sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
   129    129         }else if( pVar->flags & MEM_Real ){
   130         -        sqlite3XPrintf(&out, 0, "%!.15g", pVar->r);
          130  +        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
   131    131         }else if( pVar->flags & MEM_Str ){
   132    132           int nOut;  /* Number of bytes of the string text to include in output */
   133    133   #ifndef SQLITE_OMIT_UTF16
   134    134           u8 enc = ENC(db);
   135    135           Mem utf8;
   136    136           if( enc!=SQLITE_UTF8 ){
   137    137             memset(&utf8, 0, sizeof(utf8));