int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0,
- tointegerFunc, 0, 0);
+ rc = sqlite3_create_function(db, "tointeger", 1,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+ tointegerFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0,
- torealFunc, 0, 0);
+ rc = sqlite3_create_function(db, "toreal", 1,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+ torealFunc, 0, 0);
}
return rc;
}
-C Simplify\sthe\sbytecode\sgeneration\sfor\sSQL\sfunction\scalls\ssuch\sthat\sthe\nOP_Function\sor\sOP_PureFunc\sopcodes\sare\scoded\sdirectly,\srather\sthan\susing\nthe\sintermediate\sOP_Function0\sor\sOP_PureFunc0\s-\sopcodes\sthat\sare\snow\sremoved.
-D 2019-10-30T16:29:02.506
+C Always\sdisallow\sthe\suse\sof\snon-deterministic\sfunctions\sin\sCHECK\sconstraints,\neven\sdate/time\sfunctions\sthat\suse\sthe\s'now'\sor\ssimilar\skeywords.\s\sProvide\nimproved\serror\smessages\swhen\sthis\srequirement\sis\snot\smet.\nTicket\s[830277d9db6c3ba1]
+D 2019-10-30T18:50:08.069
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
-F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
+F ext/misc/totype.c 5b6b1eafaa993e29f8df843319b3292b029f1b5cbbbf11c8a88e05d3f714159f
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
F ext/misc/uuid.c db4db81e8c6a92ad6176ebd9f81dcb6870e331e1a286d0452f4319e3ba3df812
F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
-F src/expr.c 23d5f9e491921a57fe6d59b75c461d45777470d8b1653180ebb3e83ea658f889
+F src/expr.c 90c774b399e5df80e963fe23d18b36e0affe2949291a3ddf5555e14ef08e251e
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c ac56f02ffe7a3dff311654f86e3c2fd1ff2eb38862b0c07fd908d8cc0fb4a9a2
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 9d6a3bdca1ebc759c4616fee0d7dd4cf62741f53db3a6b0117600f27c5b1406a
+F src/resolve.c cf2391c93d425455388389e7a47674b9da107d2ed69ebf49979044d70dbeb045
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 3395765ea3749341deb4c25e8339c3d626a8ac641a52c216e9632e48e620ba68
F src/shell.c.in a17d143f186966ef24927b6b083f985ffdb95a01aa1bebaba7dcc706289bf7d2
F src/sqlite.h.in 5ba20664cede7f4e6861541fad1f17bac50f7bf576b40a8784c54f9126a9edd4
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
-F src/sqliteInt.h 5b2d25ba23135ece06886d82f60d9a16869506592e5950f3c09257b3b5d28d5c
+F src/sqliteInt.h 3ab4cce57fcda91b6b5377ba7d56dfb011d55b6a4a7d643c31dbefa06e00828a
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/vdbe.h fdbc0a11e5768a702b46ce63286f60e22e71351a29bd98b3666405e1fccc7802
F src/vdbeInt.h bd589b8b7273286858950717e0e1ec5c88b18af45079a3366dc1371865cea704
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
-F src/vdbeaux.c aeba258bb045c583bd85ae1e0b218c3542897baf522da1f1ab7da4259a7394ce
+F src/vdbeaux.c ab10ec13e61cffacf26024aa10053e66285d175b3d88d87966674b6b9b8820c4
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530
F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
-F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38
+F test/check.test 25c6035302c846c7ff8e681cf8284473f6f01be94d327de60a688ad84ab01f8b
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
-F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
+F test/date2.test 5ef8265c71460cda6b1698bf18f4bb0ffb40ac08c5092f6afe84d398c2feb5be
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
-F test/indexexpr1.test c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9
+F test/indexexpr1.test 284e119999d132cc8bf37735a928c9859b28e8e295d02b7a6a4f93977c7f9ba5
F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 13fe6978b7de208d2e27460d824f7fc778cf6ea0aabfe566b32bb410b8816f63
-R 2b5ad42e3fc6b49f0350688afce0bf63
+P 84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
+R a5809c36248fb2412cd83c239c6f50ff
U drh
-Z 8fbcb7ba95c29435c7309e57f3022596
+Z 0ef46baeb11e85e5dfc62c1770da0b94
-84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
\ No newline at end of file
+2978b65ebe25eeabe543b67cb266308cceb20082a4ae71565d6d083d7c08bc9f
\ No newline at end of file
#endif
{
sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
- pDef, pParse->iSelfTab);
+ pDef, pExpr->op2);
}
if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
&& (combinedFlags & EP_Reduced)==0
){
if( pA->iColumn!=pB->iColumn ) return 2;
- if( pA->op2!=pB->op2 ) return 2;
+ if( pA->op2!=pB->op2 && (pA->op!=TK_FUNCTION || iTab<0) ) return 2;
if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
return 2;
}
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
/* For the purposes of the EP_ConstFunc flag, date and time
** functions and other functions that change slowly are considered
- ** constant because they are constant for the duration of one query */
+ ** constant because they are constant for the duration of one query.
+ ** This allows them to be factored out of inner loops. */
ExprSetProperty(pExpr,EP_ConstFunc);
}
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
/* Date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used
** in an index. */
- notValid(pParse, pNC, "non-deterministic functions",
- NC_IdxExpr|NC_PartIdx|NC_GenCol);
+ notValid(pParse, pNC, "non-deterministic functions", NC_SelfRef);
+ }else{
+ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
+ pExpr->op2 = pNC->ncFlags & NC_SelfRef;
}
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
** Resolve names in expressions that can only reference a single table
** or which cannot reference any tables at all. Examples:
**
-** (1) CHECK constraints
-** (2) WHERE clauses on partial indices
-** (3) Expressions in indexes on expressions
-** (4) Expression arguments to VACUUM INTO.
-** (5) GENERATED ALWAYS as expressions
+** "type" flag
+** ------------
+** (1) CHECK constraints NC_IsCheck
+** (2) WHERE clauses on partial indices NC_PartIdx
+** (3) Expressions in indexes on expressions NC_IdxExpr
+** (4) Expression arguments to VACUUM INTO. 0
+** (5) GENERATED ALWAYS as expressions NC_GenCol
**
** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
** nodes of the expression is set to -1 and the Expr.iColumn value is
struct Expr {
u8 op; /* Operation performed by this node */
char affExpr; /* affinity, or RAISE type */
+ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
+ ** TK_COLUMN: the value of p5 for OP_Column
+ ** TK_AGG_FUNCTION: nesting depth
+ ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
- ** TK_COLUMN: the value of p5 for OP_Column
- ** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
union {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */
#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */
#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */
-#define NC_InAggFunc 0x00008 /* True if analyzing arguments to an agg func */
+#define NC_GenCol 0x00008 /* True for a GENERATED ALWAYS AS clause */
#define NC_HasAgg 0x00010 /* One or more aggregate functions seen */
#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */
+#define NC_SelfRef 0x0002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
#define NC_VarSelect 0x00040 /* A correlated subquery has been seen */
#define NC_UEList 0x00080 /* True if uNC.pEList is used */
#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */
#define NC_AllowWin 0x04000 /* Window functions are allowed here */
#define NC_HasWin 0x08000 /* One or more window functions seen */
#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
-#define NC_GenCol 0x20000 /* True for a GENERATED ALWAYS AS clause */
+#define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */
/*
** An instance of the following object describes a single ON CONFLICT
}
pCtx->pOut = 0;
pCtx->pFunc = (FuncDef*)pFunc;
- pCtx->pVdbe = v;
+ pCtx->pVdbe = 0;
pCtx->isError = 0;
pCtx->argc = nArg;
addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
+ sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
pCtx->iOp = addr;
return addr;
}
** features such as 'now'.
*/
int sqlite3NotPureFunc(sqlite3_context *pCtx){
+ const VdbeOp *pOp;
#ifdef SQLITE_ENABLE_STAT4
if( pCtx->pVdbe==0 ) return 1;
#endif
- if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
-#if 0
- char *zMsg = sqlite3_mprintf(
- "non-deterministic use of %s() in an index, CHECK constraint, "
- "or generated column", pCtx->pFunc->zName);
+ pOp = pCtx->pVdbe->aOp + pCtx->iOp;
+ if( pOp->opcode==OP_PureFunc ){
+ const char *zContext;
+ char *zMsg;
+ if( pOp->p5 & NC_IsCheck ){
+ zContext = "a CHECK constraint";
+ }else if( pOp->p5 & NC_GenCol ){
+ zContext = "a generated column";
+ }else{
+ zContext = "an index";
+ }
+ zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s",
+ pCtx->pFunc->zName, zContext);
sqlite3_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg);
-#else
- sqlite3_result_error(pCtx,
- "non-deterministic function in index expression or CHECK constraint",
- -1);
-#endif
return 0;
}
return 1;
#
reset_db
proc myfunc {x} {expr $x < 10}
-db func myfunc myfunc
+db func myfunc -deterministic myfunc
do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }
} {}
do_catchsql_test date2-110 {
INSERT INTO t1(x,y) VALUES('now','two');
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of date() in a CHECK constraint}}
do_execsql_test date2-120 {
SELECT * FROM t1;
} {2017-07-20 one}
}
do_catchsql_test date2-210 {
INSERT INTO t2(x,y) VALUES(3, 'now');
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of date() in an index}}
do_execsql_test date2-220 {
SELECT x, y FROM t2 ORDER BY x;
} {1 2017-07-20 2 xyzzy}
}
do_catchsql_test date2-310 {
CREATE INDEX t3b1 ON t3(datetime(b));
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of datetime() in an index}}
do_catchsql_test date2-320 {
CREATE INDEX t3b1 ON t3(datetime(b)) WHERE typeof(b)='real';
} {0 {}}
do_catchsql_test date2-410 {
CREATE INDEX t4b1 ON t4(b)
WHERE date(b) BETWEEN '2017-06-01' AND '2017-08-31';
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of date() in an index}}
do_execsql_test date2-420 {
DELETE FROM t4 WHERE a=500;
CREATE INDEX t4b1 ON t4(b)
}
do_catchsql_test date2-430 {
INSERT INTO t4(a,b) VALUES(9999,'now');
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of date() in an index}}
do_execsql_test date2-500 {
CREATE TABLE mods(x);
}
do_catchsql_test date2-510 {
INSERT INTO t5(y,m) VALUES('2017-07-20','localtime');
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of datetime() in an index}}
do_catchsql_test date2-520 {
INSERT INTO t5(y,m) VALUES('2017-07-20','utc');
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of datetime() in an index}}
+# 2019-10-30 Ticket 830277d9db6c3ba1
+#
+do_catchsql_test date2-600 {
+ CREATE TABLE t600(a REAL CHECK( a<julianday('now') ));
+ INSERT INTO t600(a) VALUES(1.0);
+} {1 {non-deterministic use of julianday() in a CHECK constraint}}
+do_catchsql_test date2-601 {
+ CREATE TABLE t601(a REAL, b TEXT, CHECK( a<julianday(b) ));
+ INSERT INTO t601(a,b) VALUES(1.0, '1970-01-01');
+} {0 {}}
+do_catchsql_test date2-602 {
+ INSERT INTO t601(a,b) VALUES(1e100, '1970-01-01');
+} {1 {CHECK constraint failed: t601}}
+do_catchsql_test date2-603 {
+ INSERT INTO t601(a,b) VALUES(10, 'now');
+} {1 {non-deterministic use of julianday() in a CHECK constraint}}
+do_catchsql_test date2-604 {
+ INSERT INTO t600(a) VALUES(julianday('now')+10);
+} {1 {non-deterministic use of julianday() in a CHECK constraint}}
-
+do_catchsql_test date2-610 {
+ CREATE TABLE t610(a,b);
+ CREATE INDEX t610x1 ON t610(julianday('now')+b);
+ INSERT INTO t610(a,b) VALUES(123,456);
+} {1 {non-deterministic use of julianday() in an index}}
+do_catchsql_test date2-611 {
+ CREATE TABLE t611(a,b);
+ CREATE INDEX t611x1 ON t611(julianday(a)+b);
+ INSERT INTO t611(a,b) VALUES('1970-01-01',10.0);
+} {0 {}}
+do_catchsql_test date2-612 {
+ INSERT INTO t611(a,b) VALUES('now',10.0);
+} {1 {non-deterministic use of julianday() in an index}}
+do_catchsql_test date3-620 {
+ CREATE TABLE t620(a, b AS (a+julianday('now')));
+ INSERT INTO t620 VALUES(10);
+} {1 {non-deterministic use of julianday() in a generated column}}
finish_test
} {1 {non-deterministic functions prohibited in index expressions}}
do_catchsql_test indexexpr1-301 {
CREATE INDEX t2x1 ON t2(julianday('now',a));
-} {1 {non-deterministic function in index expression or CHECK constraint}}
+} {1 {non-deterministic use of julianday() in an index}}
do_catchsql_test indexexpr1-310 {
CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
} {1 {subqueries prohibited in index expressions}}