1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

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]

FossilOrigin-Name: 9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a
This commit is contained in:
drh
2019-05-09 17:10:30 +00:00
parent f6099e9b40
commit 6bab6f2b4d
4 changed files with 65 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
C Avoid\slong\sdelays\sthat\scan\soccur\swhen\s".recover"ing\sdata\sfrom\sa\sdatabase\swith\sa\scorrupt\sfreelist.
D 2019-05-09T16:57:39.190
C Disable\sthe\soptimization\swhere\sa\sREAL\svalue\swith\sno\sfractional\spart\nis\sstored\sas\san\sINTEGER\swhen\sthe\sinteger\suses\sas\smuch\sspace\sas\sthe\sreal\nvalue\sit\sproposes\sto\sstand\sin\sfor\s(8\sbytes).\s\sThis\savoids\scorner\scases\nof\scomparing\sintegers\sagainst\sreal\svalues\sthat\sare\sbeyond\sthe\sresolution\nof\san\sIEEE\s754\sdouble.\s\sFix\sfor\sticket\s[6c1d3febc00b22d457c78c2]
D 2019-05-09T17:10:30.104
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -597,7 +597,7 @@ F src/vdbe.c d4efd6e5ecff8eeef280ce5d622dc2c0cfe085014e5813401b346517574adb18
F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
F src/vdbeaux.c f9fb1f71e216850267744fde8a6a0b2d3822235d6f85568af368be4722e8da13
F src/vdbeaux.c d444f4a3ff9c571965329a186701a57fe445e4c3f4c42f87402aca75386ba358
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c b76b42ac9d6a36fc55a0797929fc94cc33e1334eea2792f5ee1eef868ce13320
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
@@ -1275,7 +1275,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 7d41f354998524070317207d4e2b68e725e4cf14a57835fc746d4bea686a8714
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
@@ -1825,7 +1825,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885
R 6e5edbee3c41d65385191dd600b1b4bf
U dan
Z 90af5c9a4f9287285acd46f3e2e8c7ab
P 20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630
R 1e923a6ef9e14ab60fd1515804aac862
U drh
Z c06fe0d1d976fd970296d42fc604ced0

View File

@@ -1 +1 @@
20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630
9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a

View File

@@ -3422,6 +3422,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
/*
** 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;
@@ -3458,6 +3460,15 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
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 ){

View File

@@ -261,4 +261,49 @@ do_test select3-8.2 {
}
} {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