]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge the Mem.r value into the MemValue union as Mem.u.r. Hence, a Mem can
authordrh <drh@noemail.net>
Thu, 18 Sep 2014 17:52:15 +0000 (17:52 +0000)
committerdrh <drh@noemail.net>
Thu, 18 Sep 2014 17:52:15 +0000 (17:52 +0000)
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.

FossilOrigin-Name: 4c8c89d7e62aecfe2eb735f7bb114aed6b452847

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
src/vdbemem.c
src/vdbetrace.c

index 8cf00918c02d224df3a0f523ec5af5c911a5a844..4bfcb7263017f81fb72214b823a4d3ae84d945a2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Performance\simprovement\sfor\saffinity\stransformations\son\scomparison\soperators.
-D 2014-09-18T16:28:59.796
+C Merge\sthe\sMem.r\svalue\sinto\sthe\sMemValue\sunion\sas\sMem.u.r.\s\sHence,\sa\sMem\scan\nnow\sstore\san\sinteger\sor\sa\sreal\sbut\snot\sboth\sat\sthe\ssame\stime.\s\sStrings\sare\nstill\sstored\sin\sa\sseparate\selement\sMem.z,\sfor\snow.
+D 2014-09-18T17:52:15.374
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -288,15 +288,15 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0
 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c
 F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8
 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
-F src/vdbe.c b00ffadc43a588b02ca2b60b9128338a6f4efcba
+F src/vdbe.c 17f285ff89d73b6af5bd1fc90c0943341f4003d5
 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327
-F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f
-F src/vdbeapi.c c02242df5e9e8d1001e0086f405953833f9c426b
-F src/vdbeaux.c 9ac63bc59d2783df77e591e4c4fa8c1153a07eab
+F src/vdbeInt.h 45a0b4c5e4b38a2ff8af05102d45e7fa2e6c4439
+F src/vdbeapi.c 88929e02676fdbd5f436fcfd63fa0d371756a7ce
+F src/vdbeaux.c ac3188f182f25eac58923b1a3c0840c69949ed28
 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
-F src/vdbemem.c 8b5e1083fed2da94e315858a7edf5604a5b91804
+F src/vdbemem.c 1907e24ab431bd465f5709c30ec28a9119502f9a
 F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde
-F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415
+F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362
 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f
 F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
@@ -1198,7 +1198,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 4ef4c9a7c8510203bce0941dda2f76ded8da1de2
-R b808ae1c5ded91d91c2a612e5497b640
+P d7afdcbac24350b73a30c06c45cf0f2122820e4f
+R 320866568edfdafc16dd0b942dd87d16
 U drh
-Z 8ec5fac053656715ec4b7b6a3b299333
+Z 7641aa17b0b2d51a4b828447b0d0dc99
index 8fa5f719ed687934c49ae194112236d396a69cfb..55f0527798ce878ea939a1659a645600eb93c0d8 100644 (file)
@@ -1 +1 @@
-d7afdcbac24350b73a30c06c45cf0f2122820e4f
\ No newline at end of file
+4c8c89d7e62aecfe2eb735f7bb114aed6b452847
\ No newline at end of file
index 4bfa5f0e7ec92b3a14e263fba82996b080a05989..996cf8b9b8502ad10f1ae491ec1737c967e47153 100644 (file)
@@ -243,12 +243,13 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
   i64 iValue;
   u8 enc = pRec->enc;
   if( (pRec->flags&MEM_Str)==0 ) return;
+  if( (pRec->flags&(MEM_Int|MEM_Real))!=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->u.r = rValue;
     pRec->flags |= MEM_Real;
     if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
   }
@@ -329,13 +330,13 @@ void sqlite3ValueApplyAffinity(
 /*
 ** pMem currently only holds a string type (or maybe a BLOB that we can
 ** interpret as a string if we want to).  Compute its corresponding
-** numeric type, if has one.  Set the pMem->r and pMem->u.i fields
+** numeric type, if has one.  Set the pMem->u.r and pMem->u.i fields
 ** accordingly.
 */
 static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
   assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
   assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
-  if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){
+  if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
     return 0;
   }
   if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
@@ -349,7 +350,7 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
 ** none.  
 **
 ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
-** But it does set pMem->r and pMem->u.i appropriately.
+** But it does set pMem->u.r and pMem->u.i appropriately.
 */
 static u16 numericType(Mem *pMem){
   if( pMem->flags & (MEM_Int|MEM_Real) ){
@@ -459,7 +460,7 @@ static void memTracePrint(Mem *p){
     printf(" i:%lld", p->u.i);
 #ifndef SQLITE_OMIT_FLOATING_POINT
   }else if( p->flags & MEM_Real ){
-    printf(" r:%g", p->r);
+    printf(" r:%g", p->u.r);
 #endif
   }else if( p->flags & MEM_RowSet ){
     printf(" (rowset)");
@@ -1002,7 +1003,7 @@ case OP_Int64: {           /* out2-prerelease */
 case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
   pOut->flags = MEM_Real;
   assert( !sqlite3IsNaN(*pOp->p4.pReal) );
-  pOut->r = *pOp->p4.pReal;
+  pOut->u.r = *pOp->p4.pReal;
   break;
 }
 #endif
@@ -1479,7 +1480,7 @@ fp_math:
     if( sqlite3IsNaN(rB) ){
       goto arithmetic_result_is_null;
     }
-    pOut->r = rB;
+    pOut->u.r = rB;
     MemSetTypeFlag(pOut, MEM_Real);
     if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
       sqlite3VdbeIntegerAffinity(pOut);
@@ -3572,7 +3573,7 @@ case OP_SeekGT: {       /* jump, in3 */
       **        (x >  4.9)    ->     (x >= 5)
       **        (x <= 4.9)    ->     (x <  5)
       */
-      if( pIn3->r<(double)iKey ){
+      if( pIn3->u.r<(double)iKey ){
         assert( OP_SeekGE==(OP_SeekGT-1) );
         assert( OP_SeekLT==(OP_SeekLE-1) );
         assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
@@ -3581,7 +3582,7 @@ case OP_SeekGT: {       /* jump, in3 */
 
       /* If the approximation iKey is smaller than the actual real search
       ** term, substitute <= for < and > for >=.  */
-      else if( pIn3->r>(double)iKey ){
+      else if( pIn3->u.r>(double)iKey ){
         assert( OP_SeekLE==(OP_SeekLT+1) );
         assert( OP_SeekGT==(OP_SeekGE+1) );
         assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
index 9c7378a26cdca84c25f0e32b0c6521a56b1af657..fb05e9aed2ced9fab4bc7ca3a2241c4833035162 100644 (file)
@@ -161,7 +161,8 @@ struct VdbeFrame {
 ** integer etc.) of the same value.
 */
 struct Mem {
-  union {
+  union MemValue {
+    double r;           /* Real value used when MEM_Realis set in flags */
     i64 i;              /* Integer value used when MEM_Int is set in flags */
     int nZero;          /* Used when bit MEM_Zero is set in flags */
     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
@@ -171,10 +172,9 @@ struct Mem {
   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
   int n;              /* Number of characters in string value, excluding '\0' */
-  double r;           /* Real value */
   char *z;            /* String or BLOB value */
-  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
   /* ShallowCopy only needs to copy the information above */
+  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
   sqlite3 *db;        /* The associated database connection */
   void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
 #ifdef SQLITE_DEBUG
index ef1167a52d986a847545e64588480ffb278c9f8b..aad64aa64bc3bd045fcf70eef79e7009bc36a1f5 100644 (file)
@@ -807,7 +807,6 @@ static const Mem *columnNullValue(void){
         /* .flags      = */ MEM_Null,
         /* .enc        = */ 0,
         /* .n          = */ 0,
-        /* .r          = */ (double)0,
         /* .z          = */ 0,
         /* .zMalloc    = */ 0,
         /* .db         = */ 0,
@@ -1272,7 +1271,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
       break;
     }
     case SQLITE_FLOAT: {
-      rc = sqlite3_bind_double(pStmt, i, pValue->r);
+      rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
       break;
     }
     case SQLITE_BLOB: {
index 8466bfb30ad5b372000196aa4de9392a15c36582..ad57f4ccd3f5c984a091298d06c1abbec8954e27 100644 (file)
@@ -1076,7 +1076,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
       }else if( pMem->flags & MEM_Int ){
         sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
       }else if( pMem->flags & MEM_Real ){
-        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
+        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
       }else if( pMem->flags & MEM_Null ){
         sqlite3_snprintf(nTemp, zTemp, "NULL");
       }else{
@@ -2949,8 +2949,8 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
     u64 v;
     u32 i;
     if( serial_type==7 ){
-      assert( sizeof(v)==sizeof(pMem->r) );
-      memcpy(&v, &pMem->r, sizeof(v));
+      assert( sizeof(v)==sizeof(pMem->u.r) );
+      memcpy(&v, &pMem->u.r, sizeof(v));
       swapMixedEndianFloat(v);
     }else{
       v = pMem->u.i;
@@ -3020,10 +3020,10 @@ static u32 SQLITE_NOINLINE serialGet(
     swapMixedEndianFloat(t2);
     assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
 #endif
-    assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
+    assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
     swapMixedEndianFloat(x);
-    memcpy(&pMem->r, &x, sizeof(x));
-    pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
+    memcpy(&pMem->u.r, &x, sizeof(x));
+    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
   }
   return 8;
 }
@@ -3368,14 +3368,14 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
       return 0;
     }
     if( (f1&MEM_Real)!=0 ){
-      r1 = pMem1->r;
+      r1 = pMem1->u.r;
     }else if( (f1&MEM_Int)!=0 ){
       r1 = (double)pMem1->u.i;
     }else{
       return 1;
     }
     if( (f2&MEM_Real)!=0 ){
-      r2 = pMem2->r;
+      r2 = pMem2->u.r;
     }else if( (f2&MEM_Int)!=0 ){
       r2 = (double)pMem2->u.i;
     }else{
@@ -3536,9 +3536,9 @@ static int vdbeRecordCompareWithSkip(
       }else if( serial_type==7 ){
         double rhs = (double)pRhs->u.i;
         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
-        if( mem1.r<rhs ){
+        if( mem1.u.r<rhs ){
           rc = -1;
-        }else if( mem1.r>rhs ){
+        }else if( mem1.u.r>rhs ){
           rc = +1;
         }
       }else{
@@ -3560,11 +3560,11 @@ static int vdbeRecordCompareWithSkip(
       }else if( serial_type==0 ){
         rc = -1;
       }else{
-        double rhs = pRhs->r;
+        double rhs = pRhs->u.r;
         double lhs;
         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
         if( serial_type==7 ){
-          lhs = mem1.r;
+          lhs = mem1.u.r;
         }else{
           lhs = (double)mem1.u.i;
         }
index 359abb891f3e9051e2d54045de8e94d4f12ae0c6..780bc5286b8393eda18baf16285ccfc9a70586eb 100644 (file)
@@ -31,6 +31,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
   */
   assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
 
+  /* Cannot be both MEM_Int and MEM_Real at the same time */
+  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+
   /* If p holds a string or blob, the Mem.z must point to exactly
   ** one of the following:
   **
@@ -264,7 +267,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
     sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
   }else{
     assert( fg & MEM_Real );
-    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
+    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
   }
   pMem->n = sqlite3Strlen30(pMem->z);
   pMem->enc = SQLITE_UTF8;
@@ -421,7 +424,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
   if( flags & MEM_Int ){
     return pMem->u.i;
   }else if( flags & MEM_Real ){
-    return doubleToInt64(pMem->r);
+    return doubleToInt64(pMem->u.r);
   }else if( flags & (MEM_Str|MEM_Blob) ){
     i64 value = 0;
     assert( pMem->z || pMem->n==0 );
@@ -442,7 +445,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   if( pMem->flags & MEM_Real ){
-    return pMem->r;
+    return pMem->u.r;
   }else if( pMem->flags & MEM_Int ){
     return (double)pMem->u.i;
   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
@@ -461,12 +464,13 @@ double sqlite3VdbeRealValue(Mem *pMem){
 ** MEM_Int if we can.
 */
 void sqlite3VdbeIntegerAffinity(Mem *pMem){
+  i64 ix;
   assert( pMem->flags & MEM_Real );
   assert( (pMem->flags & MEM_RowSet)==0 );
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
-  pMem->u.i = doubleToInt64(pMem->r);
+  ix = doubleToInt64(pMem->u.r);
 
   /* Only mark the value as an integer if
   **
@@ -478,11 +482,9 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
   ** 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;
+  if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
+    pMem->u.i = ix;
+    MemSetTypeFlag(pMem, MEM_Int);
   }
 }
 
@@ -507,7 +509,7 @@ int sqlite3VdbeMemRealify(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
-  pMem->r = sqlite3VdbeRealValue(pMem);
+  pMem->u.r = sqlite3VdbeRealValue(pMem);
   MemSetTypeFlag(pMem, MEM_Real);
   return SQLITE_OK;
 }
@@ -527,7 +529,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
     if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
       MemSetTypeFlag(pMem, MEM_Int);
     }else{
-      pMem->r = sqlite3VdbeRealValue(pMem);
+      pMem->u.r = sqlite3VdbeRealValue(pMem);
       MemSetTypeFlag(pMem, MEM_Real);
       sqlite3VdbeIntegerAffinity(pMem);
     }
@@ -663,7 +665,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
 void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
   sqlite3VdbeMemSetNull(pMem);
   if( !sqlite3IsNaN(val) ){
-    pMem->r = val;
+    pMem->u.r = val;
     pMem->flags = MEM_Real;
   }
 }
@@ -1168,14 +1170,14 @@ static int valueFromExpr(
      && pVal!=0
     ){
       sqlite3VdbeMemNumerify(pVal);
-      if( pVal->u.i==SMALLEST_INT64 ){
-        pVal->flags &= ~MEM_Int;
-        pVal->flags |= MEM_Real;
-        pVal->r = (double)SMALLEST_INT64;
+      if( pVal->flags & MEM_Real ){
+        pVal->u.r = -pVal->u.r;
+      }else if( pVal->u.i==SMALLEST_INT64 ){
+        pVal->u.r = -(double)SMALLEST_INT64;
+        MemSetTypeFlag(pVal, MEM_Real);
       }else{
         pVal->u.i = -pVal->u.i;
       }
-      pVal->r = -pVal->r;
       sqlite3ValueApplyAffinity(pVal, affinity, enc);
     }
   }else if( op==TK_NULL ){
index 362530a1d9fa711314cf087ee4893617cf68047b..d27693450e35786c6a40f1f458fbdf1aa91b9e6d 100644 (file)
@@ -127,7 +127,7 @@ char *sqlite3VdbeExpandSql(
       }else if( pVar->flags & MEM_Int ){
         sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
       }else if( pVar->flags & MEM_Real ){
-        sqlite3XPrintf(&out, 0, "%!.15g", pVar->r);
+        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
       }else if( pVar->flags & MEM_Str ){
         int nOut;  /* Number of bytes of the string text to include in output */
 #ifndef SQLITE_OMIT_UTF16