/ Check-in [9b091527]
Login

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

Overview
Comment:Disable the optimization where a REAL value with no fractional part is stored as an INTEGER when the integer uses as much space as the real value it proposes to stand in for (8 bytes). This avoids corner cases of comparing integers against real values that are beyond the resolution of an IEEE 754 double. Fix for ticket [6c1d3febc00b22d457c78c2]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a
User & Date: drh 2019-05-09 17:10:30
Context
2019-05-09
17:54
Fix a crash in the sqlite_dbdata module that could occur if a pointer within an overflow chain in a corrupt database pointed past the end of the db. check-in: 3eae4e30 user: dan tags: trunk
17:10
Disable the optimization where a REAL value with no fractional part is stored as an INTEGER when the integer uses as much space as the real value it proposes to stand in for (8 bytes). This avoids corner cases of comparing integers against real values that are beyond the resolution of an IEEE 754 double. Fix for ticket [6c1d3febc00b22d457c78c2] check-in: 9b091527 user: drh tags: trunk
16:57
Avoid long delays that can occur when ".recover"ing data from a database with a corrupt freelist. check-in: 20f06bf2 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

3418
3419
3420
3421
3422
3423
3424


3425
3426
3427
3428
3429
3430
3431
....
3454
3455
3456
3457
3458
3459
3460









3461
3462
3463
3464
3465
3466
3467
**
** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
** of SQLite will not understand those serial types.
*/

/*
** Return the serial-type for the value stored in pMem.


*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
  int flags = pMem->flags;
  u32 n;

  assert( pLen!=0 );
  if( flags&MEM_Null ){
................................................................................
      }
    }
    if( u<=32767 ){ *pLen = 2; return 2; }
    if( u<=8388607 ){ *pLen = 3; return 3; }
    if( u<=2147483647 ){ *pLen = 4; return 4; }
    if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
    *pLen = 8;









    return 6;
  }
  if( flags&MEM_Real ){
    *pLen = 8;
    return 7;
  }
  assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );







>
>







 







>
>
>
>
>
>
>
>
>







3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
....
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
**
** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
** of SQLite will not understand those serial types.
*/

/*
** Return the serial-type for the value stored in pMem.
**
** This routine might convert a large MEM_IntReal value into MEM_Real.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
  int flags = pMem->flags;
  u32 n;

  assert( pLen!=0 );
  if( flags&MEM_Null ){
................................................................................
      }
    }
    if( u<=32767 ){ *pLen = 2; return 2; }
    if( u<=8388607 ){ *pLen = 3; return 3; }
    if( u<=2147483647 ){ *pLen = 4; return 4; }
    if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
    *pLen = 8;
    if( flags&MEM_IntReal ){
      /* If the value is IntReal and is going to take up 8 bytes to store
      ** as an integer, then we might as well make it an 8-byte floating
      ** point value */
      pMem->u.r = (double)pMem->u.i;
      pMem->flags &= ~MEM_IntReal;
      pMem->flags |= MEM_Real;
      return 7;
    }
    return 6;
  }
  if( flags&MEM_Real ){
    *pLen = 8;
    return 7;
  }
  assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );

Changes to test/select3.test.

256
257
258
259
260
261
262
263













































264
  }
} {real}
do_test select3-8.2 {
  execsql {
    SELECT typeof(sum(a3)) FROM a GROUP BY a1;
  }
} {real}














































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  }
} {real}
do_test select3-8.2 {
  execsql {
    SELECT typeof(sum(a3)) FROM a GROUP BY a1;
  }
} {real}

# 2019-05-09 ticket https://www.sqlite.org/src/tktview/6c1d3febc00b22d457c7
#
unset -nocomplain x
foreach {id x} {
  100 127
  101 128
  102 -127
  103 -128
  104 -129
  110 32767
  111 32768
  112 -32767
  113 -32768
  114 -32769
  120 2147483647
  121 2147483648
  122 -2147483647
  123 -2147483648
  124 -2147483649
  130 140737488355327
  131 140737488355328
  132 -140737488355327
  133 -140737488355328
  134 -140737488355329
  140 9223372036854775807
  141 -9223372036854775807
  142 -9223372036854775808
  143 9223372036854775806
  144 9223372036854775805
  145 -9223372036854775806
  146 -9223372036854775805

} {
  set x [expr {$x+0}]
  do_execsql_test select3-8.$id {
     DROP TABLE IF EXISTS t1;
     CREATE TABLE t1 (c0, c1 REAL PRIMARY KEY);
     INSERT INTO t1(c0, c1) VALUES (0, $x), (0, 0);
     UPDATE t1 SET c0 = NULL;
     UPDATE OR REPLACE t1 SET c1 = 1;
     SELECT DISTINCT * FROM t1 WHERE (t1.c0 IS NULL);
     PRAGMA integrity_check;
  } {{} 1.0 ok}
}

finish_test