mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
If a subquery has a result column of the form "CAST(... AS NUMERIC)" then
give that column no affinity rather than NUMERIC affinity. This is because casting to numeric preserves real values that could be integers but numeric affinity does not. By using no affinity on the column, we make the behavior consistent if the subquery is implemented as a co-routine or is materialized. FossilOrigin-Name: ece07d091c2ef3367a914187e0b6512c1f2390b8c34844536ad50e88c7e8c2f2
This commit is contained in:
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Move\sJS-to-C\sbinding\ssignatures\sfrom\ssqlite3-api-prologue.js\sto\ssqlite3-api-glue.js\sto\sallow\sfor\suse\sof\sthe\snew/experimental\ssqlite3.wasm.xWrap()\sfeature\swhich\sautomatically\sbinds\sJS\sfunctions\sto\sWASM/C\sas\sneeded,\swhich\ssimplifies\screation\sof\sbindings\swhich\stake\sC\sfunction\spointers.\sReimplement\ssqlite3_exec(),\ssqlite3_create_collation(),\ssqlite3_progress_handler()\sto\suse\sthis\snew\sfeature.
|
||||
D 2022-12-12T14:31:38.581
|
||||
C If\sa\ssubquery\shas\sa\sresult\scolumn\sof\sthe\sform\s"CAST(...\sAS\sNUMERIC)"\sthen\ngive\sthat\scolumn\sno\saffinity\srather\sthan\sNUMERIC\saffinity.\s\sThis\sis\sbecause\ncasting\sto\snumeric\spreserves\sreal\svalues\sthat\scould\sbe\sintegers\sbut\snumeric\naffinity\sdoes\snot.\s\sBy\susing\sno\saffinity\son\sthe\scolumn,\swe\smake\sthe\sbehavior\nconsistent\sif\sthe\ssubquery\sis\simplemented\sas\sa\sco-routine\sor\sis\smaterialized.
|
||||
D 2022-12-12T18:58:53.208
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -645,7 +645,7 @@ F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 9a687883032642054b8f400aa3bcb6019c2c30f890850480975e95568f290c52
|
||||
F src/select.c 39c4b0e23f3f1334ca3ff9b68014de0ec2c4ae5954186765d669893a8c7fc5a9
|
||||
F src/shell.c.in 8d9dc02dd03f8fc93f3e3cdb17d8d16e8ddb985dddad213985c08186900a3ebb
|
||||
F src/sqlite.h.in 97e8021f5db6bab8646d9c2d4231d3bab1204a2e88e5f187eca11dc7eab33ef8
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
@ -863,7 +863,7 @@ F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e
|
||||
F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/carray01.test d55d57bf66b1af1c7ac55fae66ff4910884a8f5d21a90a18797ce386212a2634
|
||||
F test/cast.test 6064022ba9af31a8a2ff7bb345e5bd0e74172ffad85bdab5898a42d8227c7585
|
||||
F test/cast.test 4f14da6ed96af8b3124cd2cda2ff8cda0946a8a0d0d32ae76905795c6e3ac7bc
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/changes.test 9dd8e597d84072122fc8a4fcdea837f4a54a461e6e536053ea984303e8ca937b
|
||||
F test/changes2.test d222c0cbf5ab0ac4d7c180594e486c1bf20b2098d33e56ce33b8e12eba6823b9
|
||||
@ -2067,8 +2067,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P d557015208f504c6d5d20ebf1e451b3f07b19590d76371b16a9f4b54e9645282
|
||||
R 5a61f05e144f2d7b8121b7e697a724d0
|
||||
U stephan
|
||||
Z 82382106256d8062d011dc4fe2d4d001
|
||||
P 9386d6f634680b4e0fa5487c34c63acb29f0b7a6ae738b8f6164ad084a229b62
|
||||
R b147605f598862d0859edce8eb970ae1
|
||||
T *branch * cast-to-numeric
|
||||
T *sym-cast-to-numeric *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 8d98f09634c2da9d51008460bd14d1a6
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
9386d6f634680b4e0fa5487c34c63acb29f0b7a6ae738b8f6164ad084a229b62
|
||||
ece07d091c2ef3367a914187e0b6512c1f2390b8c34844536ad50e88c7e8c2f2
|
28
src/select.c
28
src/select.c
@ -2289,6 +2289,14 @@ int sqlite3ColumnsFromExprList(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This bit, when added to the "aff" parameter of
|
||||
** sqlite3SelectAddColumnTypeAndCollation() means that result set
|
||||
** expressions of the form "CAST(expr AS NUMERIC)" should result in
|
||||
** NONE affinity rather than NUMERIC affinity.
|
||||
*/
|
||||
#define SQLITE_AFF_FLAG1 0x10
|
||||
|
||||
/*
|
||||
** Add type and collation information to a column list based on
|
||||
** a SELECT statement.
|
||||
@ -2299,12 +2307,17 @@ int sqlite3ColumnsFromExprList(
|
||||
**
|
||||
** This routine requires that all identifiers in the SELECT
|
||||
** statement be resolved.
|
||||
**
|
||||
** The SQLITE_AFF_FLAG1 bit added to parameter aff means that a
|
||||
** result set column of the form "CAST(expr AS NUMERIC)" should use
|
||||
** NONE affinity rather than NUMERIC affinity. See the
|
||||
** 2022-12-10 "reopen" of ticket https://sqlite.org/src/tktview/57c47526c3.
|
||||
*/
|
||||
void sqlite3SelectAddColumnTypeAndCollation(
|
||||
Parse *pParse, /* Parsing contexts */
|
||||
Table *pTab, /* Add column type information to this table */
|
||||
Select *pSelect, /* SELECT used to determine types and collations */
|
||||
char aff /* Default affinity for columns */
|
||||
char aff /* Default affinity. Maybe with SQLITE_AFF_FLAG1 too */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
NameContext sNC;
|
||||
@ -2330,6 +2343,12 @@ void sqlite3SelectAddColumnTypeAndCollation(
|
||||
zType = columnType(&sNC, p, 0, 0, 0);
|
||||
/* pCol->szEst = ... // Column size est for SELECT tables never used */
|
||||
pCol->affinity = sqlite3ExprAffinity(p);
|
||||
if( pCol->affinity==SQLITE_AFF_NUMERIC
|
||||
&& p->op==TK_CAST
|
||||
&& (aff & SQLITE_AFF_FLAG1)!=0
|
||||
){
|
||||
pCol->affinity = SQLITE_AFF_NONE;
|
||||
}
|
||||
if( zType ){
|
||||
m = sqlite3Strlen30(zType);
|
||||
n = sqlite3Strlen30(pCol->zCnName);
|
||||
@ -2342,7 +2361,10 @@ void sqlite3SelectAddColumnTypeAndCollation(
|
||||
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
|
||||
}
|
||||
}
|
||||
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
|
||||
if( pCol->affinity<=SQLITE_AFF_NONE ){
|
||||
assert( (SQLITE_AFF_FLAG1 & SQLITE_AFF_MASK)==0 );
|
||||
pCol->affinity = aff & SQLITE_AFF_MASK;
|
||||
}
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
if( pColl ){
|
||||
assert( pTab->pIndex==0 );
|
||||
@ -6216,7 +6238,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
|
||||
if( pSel ){
|
||||
while( pSel->pPrior ) pSel = pSel->pPrior;
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
|
||||
SQLITE_AFF_NONE);
|
||||
SQLITE_AFF_NONE|SQLITE_AFF_FLAG1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -483,5 +483,36 @@ do_execsql_test cast-9.0 {
|
||||
SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0;
|
||||
} {0}
|
||||
|
||||
# Set the 2022-12-10 "reopen" of ticket [https://sqlite.org/src/tktview/57c47526c3]
|
||||
#
|
||||
do_execsql_test cast-9.1 {
|
||||
CREATE TABLE dual(dummy TEXT);
|
||||
INSERT INTO dual VALUES('X');
|
||||
SELECT CAST(4 AS NUMERIC);
|
||||
} {4}
|
||||
do_execsql_test cast-9.2 {
|
||||
SELECT CAST(4.0 AS NUMERIC);
|
||||
} {4.0}
|
||||
do_execsql_test cast-9.3 {
|
||||
SELECT CAST(4.5 AS NUMERIC);
|
||||
} {4.5}
|
||||
do_execsql_test cast-9.4 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4 AS NUMERIC) AS x) JOIN dual;
|
||||
} {4 integer}
|
||||
do_execsql_test cast-9.5 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4 AS NUMERIC) AS x) CROSS JOIN dual;
|
||||
} {4 integer}
|
||||
do_execsql_test cast-9.10 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4.0 AS NUMERIC) AS x) JOIN dual;
|
||||
} {4.0 real}
|
||||
do_execsql_test cast-9.11 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4.0 AS NUMERIC) AS x) CROSS JOIN dual;
|
||||
} {4.0 real}
|
||||
do_execsql_test cast-9.12 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4.5 AS NUMERIC) AS x) JOIN dual;
|
||||
} {4.5 real}
|
||||
do_execsql_test cast-9.13 {
|
||||
SELECT x, typeof(x) FROM (SELECT CAST(4.5 AS NUMERIC) AS x) CROSS JOIN dual;
|
||||
} {4.5 real}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user