/ Check-in [1b027319]
Login

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

Overview
Comment:Work around a problem with GCC on 32-bit machines that cause the CAST operator to generate a floating-point result for strings that could be represented as very large integers.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1b02731962c21bb097a88801ece76ff441bf882519a821a246da84f4e2a33455
User & Date: drh 2018-01-23 17:33:42
Context
2018-01-23
19:24
Remove an unreachable branch from sqlite3SkipAccumulatorLoad(). check-in: 8b9c8eab user: drh tags: trunk
17:33
Work around a problem with GCC on 32-bit machines that cause the CAST operator to generate a floating-point result for strings that could be represented as very large integers. check-in: 1b027319 user: drh tags: trunk
16:38
Fix a bug causing spurious "sub-select returns N columns expected 1" errors in join queries with a term like "(a, b) IN (SELECT ...)" in the WHERE clause. Ticket [7310e2fb3d046a5f5]. check-in: 14dfd96f user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbemem.c.

   577    577     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   578    578     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   579    579   
   580    580     pMem->u.r = sqlite3VdbeRealValue(pMem);
   581    581     MemSetTypeFlag(pMem, MEM_Real);
   582    582     return SQLITE_OK;
   583    583   }
          584  +
          585  +/* Compare a floating point value to an integer.  Return true if the two
          586  +** values are the same within the precision of the floating point value.
          587  +**
          588  +** For some versions of GCC on 32-bit machines, if you do the more obvious
          589  +** comparison of "r1==(double)i" you sometimes get an answer of false even
          590  +** though the r1 and (double)i values are bit-for-bit the same.
          591  +*/
          592  +static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
          593  +  double r2 = (double)i;
          594  +  return memcmp(&r1, &r2, sizeof(r1))==0;
          595  +}
   584    596   
   585    597   /*
   586    598   ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
   587    599   ** Invalidate any prior representations.
   588    600   **
   589    601   ** Every effort is made to force the conversion, even if the input
   590    602   ** is a string that does not look completely like a number.  Convert
................................................................................
   597    609       assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   598    610       rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
   599    611       if( rc==0 ){
   600    612         MemSetTypeFlag(pMem, MEM_Int);
   601    613       }else{
   602    614         i64 i = pMem->u.i;
   603    615         sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
   604         -      if( rc==1 && pMem->u.r==(double)i ){
          616  +      if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
   605    617           pMem->u.i = i;
   606    618           MemSetTypeFlag(pMem, MEM_Int);
   607    619         }else{
   608    620           MemSetTypeFlag(pMem, MEM_Real);
   609    621         }
   610    622       }
   611    623     }