SQLite4
Check-in [e018823162]
Not logged in

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

Overview
Comment:Remove uses of type 'double' from the vdbe.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sqlite4-num
Files: files | file ages | folders
SHA1: e0188231625fd452f0985d3f7e98476d4b1b34da
User & Date: dan 2013-05-31 19:19:01
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
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/math.c.

   502    502     return x;
   503    503   }
   504    504   
   505    505   /*
   506    506   ** TODO: This is a placeholder implementation only.
   507    507   */
   508    508   int sqlite4_num_to_int32(sqlite4_num num, int *piOut){
   509         -  i64 i;
   510         -  sqlite4_num_to_int64(num, &i);
   511         -  *piOut = i;
          509  +  *piOut = sqlite4_num_to_int64(num, 0);
   512    510     return SQLITE4_OK;
   513    511   }
   514    512   
   515    513   int sqlite4_num_to_double(sqlite4_num num, double *pr){
   516    514     double rRet;
   517    515     int i;
   518    516     rRet = num.m;
................................................................................
   523    521     for(i=num.e; i<0; i++){
   524    522       rRet = rRet / 10.0;
   525    523     }
   526    524     *pr = rRet;
   527    525     return SQLITE4_OK;
   528    526   }
   529    527   
   530         -int sqlite4_num_to_int64(sqlite4_num num, sqlite4_int64 *piOut){
          528  +/*
          529  +** Convert the number passed as the first argument to a signed 64-bit
          530  +** integer and return the value. If the second argument is not NULL,
          531  +** then set the value that it points to 1 if data was lost as part
          532  +** of the conversion, or 0 otherwise.
          533  +*/
          534  +sqlite4_int64 sqlite4_num_to_int64(sqlite4_num num, int *pbLossy){
          535  +  static const i64 L10 = (LARGEST_INT64 / 10);
   531    536     i64 iRet;
   532    537     int i;
   533    538     iRet = num.m;
   534         -  if( num.sign ) iRet = iRet*-1;
          539  +
          540  +  if( pbLossy ) *pbLossy = 0;
   535    541     for(i=0; i<num.e; i++){
          542  +    if( pbLossy && iRet>L10 ) *pbLossy = 1;
   536    543       iRet = iRet * 10;
   537    544     }
   538    545     for(i=num.e; i<0; i++){
          546  +    if( pbLossy && (iRet % 10) ) *pbLossy = 1;
   539    547       iRet = iRet / 10;
   540    548     }
   541         -  *piOut = iRet;
   542         -  return SQLITE4_OK;
          549  +
          550  +  if( num.sign ) iRet = iRet*-1;
          551  +  return iRet;
   543    552   }
   544    553   
   545    554   
   546    555   /*
   547    556   ** Convert an integer into text in the buffer supplied. The
   548    557   ** text is zero-terminated and right-justified in the buffer.
   549    558   ** A pointer to the first character of text is returned.

Changes to src/sqlite.h.in.

  4112   4112   int sqlite4_num_isnan(sqlite4_num);
  4113   4113   sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
  4114   4114   int sqlite4_num_compare(sqlite4_num, sqlite4_num);
  4115   4115   sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*);
  4116   4116   sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
  4117   4117   sqlite4_num sqlite4_num_from_double(double);
  4118   4118   int sqlite4_num_to_int32(sqlite4_num, int*);
  4119         -int sqlite4_num_to_int64(sqlite4_num, sqlite4_int64*);
         4119  +sqlite4_int64 sqlite4_num_to_int64(sqlite4_num, int *);
  4120   4120   int sqlite4_num_to_double(sqlite4_num, double *);
  4121   4121   int sqlite4_num_to_text(sqlite4_num, char*, int);
  4122   4122   
  4123   4123   /*
  4124   4124   ** CAPI4REF: Flags For Text-To-Numeric Conversion
  4125   4125   */
  4126   4126   #define SQLITE4_PREFIX_ONLY         0x10

Changes to src/vdbe.c.

  1233   1233     pIn2 = &aMem[pOp->p2];
  1234   1234     applyNumericAffinity(pIn2);
  1235   1235     pOut = &aMem[pOp->p3];
  1236   1236     flags = pIn1->flags | pIn2->flags;
  1237   1237     if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  1238   1238   
  1239   1239     if( (pIn1->flags&MEM_Int) && (pIn2->flags&MEM_Int) ){
  1240         -    sqlite4_num_to_int64(pIn1->u.num, &iA);
  1241         -    sqlite4_num_to_int64(pIn2->u.num, &iB);
         1240  +    iA = sqlite4_num_to_int64(pIn1->u.num, 0);
         1241  +    iB = sqlite4_num_to_int64(pIn2->u.num, 0);
  1242   1242   
  1243   1243       switch( pOp->opcode ){
  1244   1244         case OP_Add:       if( sqlite4AddInt64(&iB,iA) ) goto fp_math;  break;
  1245   1245         case OP_Subtract:  if( sqlite4SubInt64(&iB,iA) ) goto fp_math;  break;
  1246   1246         case OP_Multiply:  if( sqlite4MulInt64(&iB,iA) ) goto fp_math;  break;
  1247   1247         case OP_Divide: {
  1248   1248           if( iA==0 ) goto arithmetic_result_is_null;
................................................................................
  1272   1272         case OP_Subtract: 
  1273   1273           pOut->u.num = sqlite4_num_sub(num2, num1); break;
  1274   1274         case OP_Multiply: 
  1275   1275           pOut->u.num = sqlite4_num_mul(num1, num2); break;
  1276   1276         case OP_Divide: 
  1277   1277           pOut->u.num = sqlite4_num_div(num2, num1); break;
  1278   1278         default: {
  1279         -        sqlite4_num_to_int64(num1, &iA);
  1280         -        sqlite4_num_to_int64(num2, &iB);
         1279  +        iA = sqlite4_num_to_int64(num1, 0);
         1280  +        iB = sqlite4_num_to_int64(num2, 0);
  1281   1281           if( iA==0 ) goto arithmetic_result_is_null;
  1282   1282           pOut->u.num = sqlite4_num_from_int64(iB % iA);
  1283   1283           break;
  1284   1284         }
  1285   1285       }
  1286   1286   
  1287   1287       if( sqlite4_num_isnan(pOut->u.num) ){
................................................................................
  2573   2573     Db *pDb;
  2574   2574     i64 v;
  2575   2575   
  2576   2576     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2577   2577     pDb = &db->aDb[pOp->p1];
  2578   2578     pIn3 = &aMem[pOp->p3];
  2579   2579     sqlite4VdbeMemIntegerify(pIn3);
  2580         -  sqlite4_num_to_int64(pIn3->u.num, &v);
         2580  +  v = sqlite4_num_to_int64(pIn3->u.num, 0);
  2581   2581     rc = sqlite4KVStorePutSchema(pDb->pKV, (u32)v);
  2582   2582     pDb->pSchema->schema_cookie = (int)v;
  2583   2583     db->flags |= SQLITE4_InternChanges;
  2584   2584     if( pOp->p1==1 ){
  2585   2585       /* Invalidate all prepared statements whenever the TEMP database
  2586   2586       ** schema is changed.  Ticket #1644 */
  2587   2587       sqlite4ExpirePreparedStatements(db);
................................................................................
  3327   3327   #ifndef SQLITE_OMIT_AUTOINCREMENT
  3328   3328     if( pOp->p3 && rc==SQLITE4_OK ){
  3329   3329       pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3);
  3330   3330       assert( memIsValid(pIn3) );
  3331   3331       REGISTER_TRACE(pOp->p3, pIn3);
  3332   3332       sqlite4VdbeMemIntegerify(pIn3);
  3333   3333       assert( (pIn3->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
  3334         -    sqlite4_num_to_int64(pIn3->u.num, &i3);
         3334  +    i3 = sqlite4_num_to_int64(pIn3->u.num, 0);
  3335   3335       if( i3==MAX_ROWID ){
  3336   3336         rc = SQLITE4_FULL;
  3337   3337       }
  3338   3338       if( v<i3 ) v = i3;
  3339   3339     }
  3340   3340   #endif
  3341   3341     pOut->flags = MEM_Int;
................................................................................
  3377   3377         }
  3378   3378       }else if( rc==SQLITE4_NOTFOUND ){
  3379   3379         rc = SQLITE4_OK;
  3380   3380       }
  3381   3381       sqlite4KVCursorClose(pCsr);
  3382   3382     }
  3383   3383   
  3384         -  sqlite4_num_to_int64(pIn1->u.num, &i1);
         3384  +  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  3385   3385     if( i1>=(i64)iMax ){
  3386   3386       i1++;
  3387   3387     }else{
  3388   3388       i1 = iMax+1;
  3389   3389     }
  3390   3390     pIn1->u.num = sqlite4_num_from_int64(i1);
  3391   3391   
................................................................................
  3445   3445     REGISTER_TRACE(pOp->p2, pData);
  3446   3446   
  3447   3447     if( pOp->opcode==OP_Insert ){
  3448   3448       pKey = &aMem[pOp->p3];
  3449   3449       assert( pKey->flags & MEM_Int );
  3450   3450       assert( memIsValid(pKey) );
  3451   3451       REGISTER_TRACE(pOp->p3, pKey);
  3452         -    sqlite4_num_to_int64(pKey->u.num, &iKey);
         3452  +    iKey = sqlite4_num_to_int64(pKey->u.num, 0);
  3453   3453     }else{
  3454   3454       /* assert( pOp->opcode==OP_InsertInt ); */
  3455   3455       iKey = pOp->p3;
  3456   3456     }
  3457   3457   
  3458   3458     if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  3459   3459     if( pData->flags & MEM_Null ){
................................................................................
  4308   4308     Mem *pIn1;
  4309   4309     pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1);
  4310   4310     assert( memIsValid(pIn1) );
  4311   4311     sqlite4VdbeMemIntegerify(pIn1);
  4312   4312     pIn2 = &aMem[pOp->p2];
  4313   4313     REGISTER_TRACE(pOp->p1, pIn1);
  4314   4314     sqlite4VdbeMemIntegerify(pIn2);
  4315         -  sqlite4_num_to_int64(pIn1->u.num, &i1);
  4316         -  sqlite4_num_to_int64(pIn2->u.num, &i2);
         4315  +  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
         4316  +  i2 = sqlite4_num_to_int64(pIn2->u.num, 0);
  4317   4317     if( i1<i2 ){
  4318   4318       pIn1->u.num = sqlite4_num_from_int64(i2);
  4319   4319     }
  4320   4320     REGISTER_TRACE(pOp->p1, pIn1);
  4321   4321     break;
  4322   4322   }
  4323   4323   #endif /* SQLITE4_OMIT_AUTOINCREMENT */
................................................................................
  4329   4329   ** It is illegal to use this instruction on a register that does
  4330   4330   ** not contain an integer.  An assertion fault will result if you try.
  4331   4331   */
  4332   4332   case OP_IfPos: {        /* jump, in1 */
  4333   4333     i64 i1;
  4334   4334     pIn1 = &aMem[pOp->p1];
  4335   4335     assert( pIn1->flags&MEM_Int );
  4336         -  sqlite4_num_to_int64(pIn1->u.num, &i1);
         4336  +  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  4337   4337     if( i1>0 ){
  4338   4338        pc = pOp->p2 - 1;
  4339   4339     }
  4340   4340     break;
  4341   4341   }
  4342   4342   
  4343   4343   /* Opcode: IfNeg P1 P2 * * *
................................................................................
  4347   4347   ** It is illegal to use this instruction on a register that does
  4348   4348   ** not contain an integer.  An assertion fault will result if you try.
  4349   4349   */
  4350   4350   case OP_IfNeg: {        /* jump, in1 */
  4351   4351     i64 i1;
  4352   4352     pIn1 = &aMem[pOp->p1];
  4353   4353     assert( pIn1->flags&MEM_Int );
  4354         -  sqlite4_num_to_int64(pIn1->u.num, &i1);
         4354  +  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  4355   4355     if( i1<0 ){
  4356   4356        pc = pOp->p2 - 1;
  4357   4357     }
  4358   4358     break;
  4359   4359   }
  4360   4360   
  4361   4361   /* Opcode: IfZero P1 P2 P3 * *
................................................................................
  4366   4366   ** It is illegal to use this instruction on a register that does
  4367   4367   ** not contain an integer.  An assertion fault will result if you try.
  4368   4368   */
  4369   4369   case OP_IfZero: {        /* jump, in1 */
  4370   4370     i64 i1;
  4371   4371     pIn1 = &aMem[pOp->p1];
  4372   4372     assert( pIn1->flags&MEM_Int );
  4373         -  sqlite4_num_to_int64(pIn1->u.num, &i1);
         4373  +  i1 = sqlite4_num_to_int64(pIn1->u.num, 0);
  4374   4374     i1 += pOp->p3;
  4375   4375     pIn1->u.num = sqlite4_num_from_int64(i1);
  4376   4376     if( i1==0 ){
  4377   4377        pc = pOp->p2 - 1;
  4378   4378     }
  4379   4379     break;
  4380   4380   }
................................................................................
  4954   4954     cksum = 0;
  4955   4955   
  4956   4956     if( pOp->p5 ){
  4957   4957       sqlite4Fts5EntryCksum(db, pInfo, pKey, aArg, &cksum);
  4958   4958     }else{
  4959   4959       sqlite4Fts5RowCksum(db, pInfo, pKey, aArg, &cksum);
  4960   4960     }
  4961         -  sqlite4_num_to_int64(pOut->u.num, &i1);
         4961  +  i1 = sqlite4_num_to_int64(pOut->u.num, 0);
  4962   4962     pOut->u.num = sqlite4_num_from_int64(i1 ^ cksum);
  4963   4963   
  4964   4964     break;
  4965   4965   }
  4966   4966   
  4967   4967   /* Opcode: FtsOpen P1 P2 P3 P4 P5
  4968   4968   **

Changes to src/vdbeapi.c.

  1086   1086   ){
  1087   1087     return bindText(pStmt, i, zData, nData, xDel, pDelArg, SQLITE4_UTF16NATIVE);
  1088   1088   }
  1089   1089   #endif /* SQLITE4_OMIT_UTF16 */
  1090   1090   int sqlite4_bind_value(sqlite4_stmt *pStmt, int i, const sqlite4_value *pValue){
  1091   1091     int rc;
  1092   1092     switch( pValue->type ){
  1093         -    case SQLITE4_INTEGER: {
  1094         -      i64 i1;
  1095         -      sqlite4_num_to_int64(pValue->u.num, &i1);
  1096         -      rc = sqlite4_bind_int64(pStmt, i, i1);
  1097         -      break;
  1098         -    }
         1093  +    case SQLITE4_INTEGER:
  1099   1094       case SQLITE4_FLOAT: {
  1100         -      double r;
  1101         -      sqlite4_num_to_double(pValue->u.num, &r);
  1102         -      rc = sqlite4_bind_double(pStmt, i, r);
         1095  +      Mem *p = (Mem *)pValue;
         1096  +      Vdbe *v = (Vdbe *)pStmt;
         1097  +      vdbeUnbind(v, i);
         1098  +      v->aVar[i-1].u.num = p->u.num;
         1099  +      MemSetTypeFlag(&v->aVar[i-1], 
         1100  +          (pValue->type==SQLITE4_FLOAT ? MEM_Real : MEM_Int)
         1101  +      );
  1103   1102         break;
  1104   1103       }
  1105   1104       case SQLITE4_BLOB: {
  1106   1105         rc = sqlite4_bind_blob(pStmt, i, pValue->z, pValue->n,
  1107   1106                                SQLITE4_TRANSIENT, 0);
  1108   1107         break;
  1109   1108       }

Changes to src/vdbecodec.c.

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

Changes to src/vdbemem.c.

   308    308   ** If pMem is a string or blob, then we make an attempt to convert
   309    309   ** it into a integer and return that.  If pMem represents an
   310    310   ** an SQL-NULL value, return 0.
   311    311   **
   312    312   ** If pMem represents a string value, its encoding might be changed.
   313    313   */
   314    314   i64 sqlite4VdbeIntValue(Mem *pMem){
   315         -  int flags;
   316    315     assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
   317    316     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   318         -  flags = pMem->flags;
   319         -  if( flags & (MEM_Int|MEM_Real) ){
   320         -    i64 i1;
   321         -    sqlite4_num_to_int64(pMem->u.num, &i1);
   322         -    return i1;
   323         -  }else if( flags & (MEM_Str|MEM_Blob) ){
   324         -    i64 value = 0;
   325         -    assert( pMem->z || pMem->n==0 );
   326         -    testcase( pMem->z==0 );
   327         -    sqlite4Atoi64(pMem->z, &value, pMem->n, pMem->enc);
   328         -    return value;
   329         -  }else{
   330         -    return 0;
   331         -  }
          317  +  return sqlite4_num_to_int64(sqlite4VdbeNumValue(pMem), 0);
   332    318   }
   333    319   
   334    320   /*
   335    321   ** Return the best representation of pMem that we can get into a
   336    322   ** double.  If pMem is already a double or an integer, return its
   337    323   ** value.  If it is a string or blob, try to convert it to a double.
   338    324   ** If it is a NULL, return 0.0.
................................................................................
   349    335   ** Extract and return a numeric value from memory cell pMem. This call
   350    336   ** does not modify the contents or flags of *pMem in any way.
   351    337   */
   352    338   sqlite4_num sqlite4VdbeNumValue(Mem *pMem){
   353    339     if( pMem->flags & (MEM_Real|MEM_Int) ){
   354    340       return pMem->u.num;
   355    341     }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
   356         -    int flags = SQLITE4_PREFIX_ONLY | pMem->enc;
          342  +    int flags = SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE | pMem->enc;
   357    343       return sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
   358    344     }else{
   359    345       sqlite4_num zero = {0,0,0,0};
   360    346       return zero;
   361    347     }
   362    348   }
   363    349   
   364    350   /*
   365    351   ** The MEM structure is already a MEM_Real.  Try to also make it a
   366    352   ** MEM_Int if we can.
   367    353   */
   368    354   void sqlite4VdbeIntegerAffinity(Mem *pMem){
   369    355     i64 i;
   370         -  double r;
          356  +  int bLossy;
   371    357   
   372    358     assert( pMem->flags & MEM_Real );
   373    359     assert( (pMem->flags & MEM_RowSet)==0 );
   374    360     assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
   375    361     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   376    362   
   377         -  sqlite4_num_to_int64(pMem->u.num, &i);
   378         -  sqlite4_num_to_double(pMem->u.num, &r);
   379         -
   380         -  /* Only mark the value as an integer if
   381         -  **
   382         -  **    (1) the round-trip conversion real->int->real is a no-op, and
   383         -  **    (2) The integer is neither the largest nor the smallest
   384         -  **        possible integer (ticket #3922)
   385         -  **
   386         -  ** The second and third terms in the following conditional enforces
   387         -  ** the second condition under the assumption that addition overflow causes
   388         -  ** values to wrap around.  On x86 hardware, the third term is always
   389         -  ** true and could be omitted.  But we leave it in because other
   390         -  ** architectures might behave differently.
   391         -  */
   392         -  if( r==(double)i && i>SMALLEST_INT64 && ALWAYS(i<LARGEST_INT64) ){
   393         -    pMem->u.num = sqlite4_num_from_int64(i);
          363  +  i = sqlite4_num_to_int64(pMem->u.num, &bLossy);
          364  +  if( bLossy==0 ){
   394    365       MemSetTypeFlag(pMem, MEM_Int);
          366  +    pMem->u.num = sqlite4_num_from_int64(i);
   395    367     }
   396    368   }
   397    369   
   398    370   /*
   399    371   ** Convert pMem to type integer.  Invalidate any prior representations.
   400    372   */
   401    373   int sqlite4VdbeMemIntegerify(Mem *pMem){
   402    374     assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
   403    375     assert( (pMem->flags & MEM_RowSet)==0 );
   404    376     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   405    377   
   406    378     if( (pMem->flags & MEM_Int)==0 ){
   407         -    sqlite4VdbeMemNumerify(pMem);
          379  +    pMem->u.num = sqlite4_num_from_int64(sqlite4VdbeIntValue(pMem));
          380  +    MemSetTypeFlag(pMem, MEM_Int);
   408    381     }
   409         -  if( (pMem->flags & MEM_Int)==0 ){
   410         -    if( pMem->flags & MEM_Real ){
   411         -      i64 iVal;
   412         -      sqlite4_num_to_int64(pMem->u.num, &iVal);
   413         -      pMem->u.num = sqlite4_num_from_int64(iVal);
   414         -    }else{
   415         -      pMem->u.num = sqlite4_num_from_int64(0);
   416         -    }
   417         -  }
   418         -
   419         -  MemSetTypeFlag(pMem, MEM_Int);
   420    382     return SQLITE4_OK;
   421    383   }
   422    384   
   423    385   /*
   424    386   ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
   425    387   ** Invalidate any prior representations.
   426    388   **
................................................................................
   728    690     }
   729    691   
   730    692     /* If one value is a number and the other is not, the number is less.
   731    693     ** If both are numbers, compare as reals if one is a real, or as integers
   732    694     ** if both values are integers.
   733    695     */
   734    696     if( combined_flags&(MEM_Int|MEM_Real) ){
   735         -    if( !(f1&(MEM_Int|MEM_Real)) ){
   736         -      return 1;
   737         -    }
   738         -    if( !(f2&(MEM_Int|MEM_Real)) ){
   739         -      return -1;
   740         -    }
   741         -    if( (f1 & f2 & MEM_Int)==0 ){
   742         -      double r1, r2;
   743         -      sqlite4_num_to_double(pMem1->u.num, &r1);
   744         -      sqlite4_num_to_double(pMem2->u.num, &r2);
   745         -      if( r1<r2 ) return -1;
   746         -      if( r1>r2 ) return 1;
   747         -      return 0;
   748         -    }else{
   749         -      i64 i1, i2;
   750         -      sqlite4_num_to_int64(pMem1->u.num, &i1);
   751         -      sqlite4_num_to_int64(pMem2->u.num, &i2);
   752         -      assert( f1&MEM_Int );
   753         -      assert( f2&MEM_Int );
   754         -      if( i1<i2 ) return -1;
   755         -      if( i1>i2 ) return 1;
   756         -      return 0;
   757         -    }
          697  +    if( !(f1&(MEM_Int|MEM_Real)) ) return 1;
          698  +    if( !(f2&(MEM_Int|MEM_Real)) ) return -1;
          699  +    return (sqlite4_num_compare(pMem1->u.num, pMem2->u.num) - 2);
   758    700     }
   759    701   
   760    702     /* If one value is a string and the other is a blob, the string is less.
   761    703     ** If both are strings, compare using the collating functions.
   762    704     */
   763    705     if( combined_flags&MEM_Str ){
   764    706       if( (f1 & MEM_Str)==0 ){