When computing an expression value for an index-on-expression or a CHECK
constraint and the expressions uses a REAL table column, but the value of that column is an integer (in other words, when it is using the store-real-as-integer optimization) be sure to promote the value to real before evaluating the expression. Ticket [57af00b6642ecd68]. FossilOrigin-Name: 0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9
This commit is contained in:
parent
cc80db69e9
commit
bffdd63633
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Remove\san\sobsolete\sparagraph\sfrom\sthe\sOP_Column\sdocumentation.\s\sNo\scode\nchanges.
|
||||
D 2019-09-01T23:36:33.093
|
||||
C When\scomputing\san\sexpression\svalue\sfor\san\sindex-on-expression\sor\sa\sCHECK\nconstraint\sand\sthe\sexpressions\suses\sa\sREAL\stable\scolumn,\sbut\sthe\svalue\sof\nthat\scolumn\sis\san\sinteger\s(in\sother\swords,\swhen\sit\sis\susing\sthe\s\nstore-real-as-integer\soptimization)\sbe\ssure\sto\spromote\sthe\svalue\sto\sreal\nbefore\sevaluating\sthe\sexpression.\s\sTicket\s[57af00b6642ecd68].
|
||||
D 2019-09-02T00:58:44.169
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
|
||||
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
|
||||
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
|
||||
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
|
||||
F src/expr.c 150acd113edf50e807c70eedf1629b1d94b1177b8a56497e23d8ccf1e1e2a74f
|
||||
F src/expr.c dcf6eb84656d3c5b41d6755cdb55a264a3f6f8f12e68bf87fa27bdd33e263ee3
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e
|
||||
F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467
|
||||
@ -724,7 +724,7 @@ F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bc
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test e6527bed2b5557ffdbf5680765c4ae6fe61e9b68b7ee69a7f776787a4527b5da
|
||||
F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38
|
||||
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
|
||||
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
|
||||
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
|
||||
@ -1052,7 +1052,7 @@ F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
|
||||
F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24
|
||||
F test/indexexpr1.test fb56f0b9a9d147b38979d154176f150b5e45fdd5d0162fab639a7f9478134fa3
|
||||
F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5
|
||||
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
@ -1838,7 +1838,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 63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a
|
||||
R c1da51105a0bd41bcf8b282b1f2a62fa
|
||||
P f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839
|
||||
R cad500c6656aba1cd58b9ed6ead8c93d
|
||||
U drh
|
||||
Z 7a37af4640fc76b6e62eb0e6e9abd09a
|
||||
Z 159d6991963aae3d8bb85f2594c26695
|
||||
|
@ -1 +1 @@
|
||||
f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839
|
||||
0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9
|
14
src/expr.c
14
src/expr.c
@ -3532,7 +3532,19 @@ expr_code_doover:
|
||||
if( iTab<0 ){
|
||||
if( pParse->iSelfTab<0 ){
|
||||
/* Generating CHECK constraints or inserting into partial index */
|
||||
return pExpr->iColumn - pParse->iSelfTab;
|
||||
assert( pExpr->y.pTab!=0 );
|
||||
assert( pExpr->iColumn>=XN_ROWID );
|
||||
assert( pExpr->iColumn<pExpr->y.pTab->nCol );
|
||||
if( pExpr->iColumn>=0
|
||||
&& pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
|
||||
){
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab,
|
||||
target);
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
|
||||
return target;
|
||||
}else{
|
||||
return pExpr->iColumn - pParse->iSelfTab;
|
||||
}
|
||||
}else{
|
||||
/* Coding an expression that is part of an index where column names
|
||||
** in the index refer to the table to which the index belongs */
|
||||
|
@ -123,6 +123,11 @@ do_test check-2.1 {
|
||||
y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
|
||||
z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
|
||||
);
|
||||
CREATE TABLE t2n(
|
||||
x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
|
||||
y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
|
||||
z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
|
||||
);
|
||||
PRAGMA writable_schema = 0;
|
||||
}
|
||||
} {}
|
||||
@ -146,9 +151,17 @@ do_test check-2.4 {
|
||||
}
|
||||
} {1 {CHECK constraint failed: one}}
|
||||
do_test check-2.5 {
|
||||
# The 5 gets automatically promoted to 5.0 because the column type is REAL
|
||||
catchsql {
|
||||
INSERT INTO t2 VALUES(NULL, 5, NULL);
|
||||
}
|
||||
} {0 {}}
|
||||
do_test check-2.5b {
|
||||
# This time the column type is NUMERIC, so not automatic promption to REAL
|
||||
# occurs and the constraint fails.
|
||||
catchsql {
|
||||
INSERT INTO t2n VALUES(NULL, 5, NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: two}}
|
||||
do_test check-2.6 {
|
||||
catchsql {
|
||||
@ -195,6 +208,7 @@ do_test check-2.cleanup {
|
||||
execsql {
|
||||
DROP TABLE IF EXISTS t2b;
|
||||
DROP TABLE IF EXISTS t2c;
|
||||
DROP TABLE IF EXISTS t2n;
|
||||
}
|
||||
} {}
|
||||
|
||||
|
@ -457,4 +457,28 @@ do_execsql_test indexexpr-1700 {
|
||||
SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE);
|
||||
} {0}
|
||||
|
||||
# 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848
|
||||
# When the expression of an an index-on-expression references a
|
||||
# table column of type REAL that is actually holding an MEM_IntReal
|
||||
# value, be sure to use the REAL value and not the INT value when
|
||||
# computing the expression.
|
||||
#
|
||||
do_execsql_test indexexpr-1800 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 REAL, c1 TEXT);
|
||||
CREATE INDEX i0 ON t0(+c0, c0);
|
||||
INSERT INTO t0(c0) VALUES(0);
|
||||
SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0;
|
||||
} {0}
|
||||
do_execsql_test indexexpr-1810 {
|
||||
SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0;
|
||||
} {1}
|
||||
do_execsql_test indexexpr-1820 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x REAL);
|
||||
CREATE INDEX t1x ON t1(x, +x);
|
||||
INSERT INTO t1(x) VALUES(2);
|
||||
SELECT +x FROM t1 WHERE x=2;
|
||||
} {2.0}
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user