-C Fix\san\sincompatibility\sbetween\sthe\sTcl\sinterface\sand\sthe\s"memdb"\svfs\sby\sallowing\smemdb\sto\saccept\sfilenames\sthat\sbegin\swith\s'\\'\scharacters.
-D 2022-12-15T18:56:12.441
+C Create\sa\snew\saffinity\scalled\sFLEXNUM\sthat\sworks\slike\sNUMERIC\sexcept\sthat\sit\nnever\stries\sto\sconvert\sinteger\sto\sreal\sor\sreal\sto\sinteger.\s\sThe\saffinity\sis\nonly\sused\sinternally\s-\sit\sis\snot\spossible\sto\screate\sa\stable\scolumn\swith\sthis\naffinity.\s\sThis\saffinity\sis\sused\son\ssubqueries\sand\sviews\sthat\sare\sbuilt\soff\nof\sa\scompound\sSELECT\sand\swhere\sthe\sdatatype\sis\scontrolled\sby\sa\sCAST\sexpression.\ndbsqlfuzz\sc9ee6f9a0a8b8fefb02cf69de2a8b67ca39525c8
+D 2022-12-15T20:03:08.225
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/btree.c 2f794c217e52fdf4322bf37ee7778331b4d93aed2c00b5d67f914c0239a9edcc
F src/btree.h 49da925329574798be3cbb745a49d069a9e67c99900d8a0d04b1e934d60394ea
F src/btreeInt.h 88ad499c92b489afedbfefc3f067c4d15023ec021afe622db240dc9d2277cfa5
-F src/build.c 51b46b657d914877dc64d0f66e2d82021b6ff622f43287cebc105efee0165600
+F src/build.c ea069a5655797f174403ee6f32c532e69ddcf4031bc0e65cca4863cb28cba603
F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
F src/dbpage.c f1a87f4ebcf22284e0aaf0697862f4ccfc120dcd6db3d8dfa3b049b2580c01d8
F src/dbstat.c a56a7ad1163a9888d46cd5820be2e65354fb1aa04ed6909f7c3e5831e0ee2c29
F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e
-F src/expr.c 63e0b77a5444c75908fb1d2db9b15248c3b31b4fd5ea38f1a45a2b4ac2f14cf8
+F src/expr.c 6dc067ab8244627d62d0d81bd9d9cc78173325cf2fe3f494f0a65a418ce2b9f8
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002
F src/func.c 7e86074afc4dc702691a29b7801f6dcc191db092b52e8bbe69dcd2f7be52194d
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c a6c97f07b148ebf2e47c973b3ed292b43950da5bccec4a98f38ab7db6d6a0283
+F src/select.c c4f845e116a425c71b8115b7ffc221237cb59569de3253134cbd570b7e04cf0f
F src/shell.c.in 47d491325ea7e01d9d4b7f6166a83fbfc6729b3d8a546d857d627a58a5d46d73
F src/sqlite.h.in e752f82b9d71f1d42b259b1900e4b1caf0965e844d756cd5cc91cc2cf45ed925
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h c4b9fa7a7e2bcdf850cfeb4b8a91d5ec47b7a00033bc996fd2ee96cbf2741f5f
-F src/sqliteInt.h 58dac6ab1352193715dc7de71cf900cafce6c3064a7331dc8b2029a6165a2b92
+F src/sqliteInt.h 4bcf6f13b8195de4fd020cd58ebb605a27752b3d82d0d5071d4435a446f00487
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050
F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
-F src/vdbe.c 705df5b079978ea98ae18db8ffcefbdf529f7465e9c8fa19b022530556fc68e1
+F src/vdbe.c c1a65b1bb9e2fdb8831cfb4a7ff4ef3088647dd5f096bcedd5231c03181459f4
F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c
F src/vdbeInt.h 8651e4c4e04d1860d0bdcf330cb8294e3778a9d4222be30ce4c490d9220af783
F src/vdbeapi.c df3f73a4d0a487f2068e3c84776cd6e3fba5ae80ff612659dcfda4307686420b
F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/carray01.test d55d57bf66b1af1c7ac55fae66ff4910884a8f5d21a90a18797ce386212a2634
-F test/cast.test 46a5963a216c2b14220557b8636b968d6de9d3292d79616becbf7109ca00e1ad
+F test/cast.test e3a7e452f37efec0df0a89e55aa2f04861ba6613deb16075101414668bf4bb24
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/changes.test 9dd8e597d84072122fc8a4fcdea837f4a54a461e6e536053ea984303e8ca937b
F test/changes2.test d222c0cbf5ab0ac4d7c180594e486c1bf20b2098d33e56ce33b8e12eba6823b9
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P eb27feecea508f3491a09699f2339951facd2345d479cfd3020183dc2af703b2
-R d9029a8d7af89f7bcaaa52e77671d993
-U dan
-Z 711e972efe20ba3f8cde77248740eec0
+P bd537f2057a4800bd30e7dd57405c3e57df649471104c80bd32573a89568029e
+R 37c0f0e978d6f512d45ea1c89699be07
+U drh
+Z f6d3f39ad91532557d8a7968a4b1fd8b
# Remove this line to create a well-formed Fossil manifest.
-bd537f2057a4800bd30e7dd57405c3e57df649471104c80bd32573a89568029e
\ No newline at end of file
+44135d6ea84f7ba6b36549954b38a8bc048d5ffea5a9779e35950afa4eb2dfb2
\ No newline at end of file
/* SQLITE_AFF_TEXT */ " TEXT",
/* SQLITE_AFF_NUMERIC */ " NUM",
/* SQLITE_AFF_INTEGER */ " INT",
- /* SQLITE_AFF_REAL */ " REAL"
+ /* SQLITE_AFF_REAL */ " REAL",
+ /* SQLITE_AFF_FLEXNUM */ " NUM",
};
int len;
const char *zType;
testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
testcase( pCol->affinity==SQLITE_AFF_INTEGER );
testcase( pCol->affinity==SQLITE_AFF_REAL );
+ testcase( pCol->affinity==SQLITE_AFF_FLEXNUM );
zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
len = sqlite3Strlen30(zType);
- assert( pCol->affinity==SQLITE_AFF_BLOB
+ assert( pCol->affinity==SQLITE_AFF_BLOB
+ || pCol->affinity==SQLITE_AFF_FLEXNUM
|| pCol->affinity==sqlite3AffinityType(zType, 0) );
memcpy(&zStmt[k], zType, len);
k += len;
assert( pExpr->y.pTab!=0 );
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( aff>SQLITE_AFF_BLOB ){
- static const char zAff[] = "B\000C\000D\000E";
+ static const char zAff[] = "B\000C\000D\000E\000F";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
return SQLITE_OK;
}
-/*
-** This bit, when added to the "aff" parameter of
-** sqlite3ColumnTypeOfSubquery() 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
-
/*
** pTab is a transient Table object that represents a subquery of some
** kind (maybe a parenthesized subquery in the FROM clause of a larger
** * The datatype name, as it might appear in a CREATE TABLE statement
** * Which collating sequence to use for the column
** * The affinity of the column
-**
-** 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 sqlite3SubqueryColumnTypes(
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. Maybe with SQLITE_AFF_FLAG1 too */
+ char aff /* Default affinity. */
){
sqlite3 *db = pParse->db;
Column *pCol;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
if( db->mallocFailed ) return;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
a = pSelect->pEList->a;
/* pCol->szEst = ... // Column size est for SELECT tables never used */
pCol->affinity = sqlite3ExprAffinity(p);
if( pCol->affinity<=SQLITE_AFF_NONE ){
- assert( (SQLITE_AFF_FLAG1 & SQLITE_AFF_MASK)==0 );
- pCol->affinity = aff & SQLITE_AFF_MASK;
- }
- if( aff & SQLITE_AFF_FLAG1 ){
- if( pCol->affinity==SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
- pCol->affinity = SQLITE_AFF_NONE;
- }
+ pCol->affinity = aff;
+ }else if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
+ pCol->affinity = SQLITE_AFF_FLEXNUM;
}
if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){
int m = 0;
pCol->affinity = SQLITE_AFF_BLOB;
}
}
- if( pCol->affinity==SQLITE_AFF_NUMERIC ){
+ if( pCol->affinity==SQLITE_AFF_NUMERIC
+ || pCol->affinity==SQLITE_AFF_FLEXNUM
+ ){
zType = "NUM";
}else{
zType = 0;
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
if( pSel ){
- sqlite3SubqueryColumnTypes(pParse, pTab, pSel,
- SQLITE_AFF_NONE|SQLITE_AFF_FLAG1);
+ sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
}
}
}
#define SQLITE_AFF_NUMERIC 0x43 /* 'C' */
#define SQLITE_AFF_INTEGER 0x44 /* 'D' */
#define SQLITE_AFF_REAL 0x45 /* 'E' */
+#define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */
#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
** always preferred, even if the affinity is REAL, because
** an integer representation is more space efficient on disk.
**
+** SQLITE_AFF_FLEXNUM:
+** If the value is text, then try to convert it into a number of
+** some kind (integer or real) but do not make any other changes.
+**
** SQLITE_AFF_TEXT:
** Convert pRec to a text representation.
**
){
if( affinity>=SQLITE_AFF_NUMERIC ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
- || affinity==SQLITE_AFF_NUMERIC );
+ || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM );
if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
if( (pRec->flags & MEM_Real)==0 ){
if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
- }else{
+ }else if( affinity<=SQLITE_AFF_REAL ){
sqlite3VdbeIntegerAffinity(pRec);
}
}
SELECT x, typeof(x) FROM dual CROSS JOIN (SELECT CAST(4.5 AS NUMERIC) AS x);
} {4.5 real}
+# 2022-12-15 dbsqlfuzz c9ee6f9a0a8b8fefb02cf69de2a8b67ca39525c8
+#
+# Added a new SQLITE_AFF_FLEXNUM that does not try to convert int to real or
+# real to int.
+#
+do_execsql_test cast-10.1 {
+ VALUES(CAST(44 AS REAL)),(55);
+} {44.0 55}
+do_execsql_test cast-10.2 {
+ SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55;
+} {44.0 55}
+do_execsql_test cast-10.3 {
+ SELECT * FROM (VALUES(CAST(44 AS REAL)),(55));
+} {44.0 55}
+do_execsql_test cast-10.4 {
+ SELECT * FROM (SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55);
+} {44.0 55}
+do_execsql_test cast-10.5 {
+ SELECT * FROM dual CROSS JOIN (VALUES(CAST(44 AS REAL)),(55));
+} {X 44.0 X 55}
+do_execsql_test cast-10.6 {
+ SELECT * FROM dual CROSS JOIN (SELECT CAST(44 AS REAL) AS 'm'
+ UNION ALL SELECT 55);
+} {X 44.0 X 55}
+do_execsql_test cast-10.7 {
+ DROP VIEW v1;
+ CREATE VIEW v1 AS SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55;
+ SELECT name, type FROM pragma_table_info('v1');
+} {m NUM}
+do_execsql_test cast-10.8 {
+ CREATE VIEW v2 AS VALUES(CAST(44 AS REAL)),(55);
+ SELECT type FROM pragma_table_info('v2');
+} {NUM}
+do_execsql_test cast-10.9 {
+ SELECT * FROM v1;
+} {44.0 55}
+do_execsql_test cast-10.10 {
+ SELECT * FROM v2;
+} {44.0 55}
+
finish_test