1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Always disallow the use of non-deterministic functions in CHECK constraints,

even date/time functions that use the 'now' or similar keywords.  Provide
improved error messages when this requirement is not met.
Ticket [830277d9db6c3ba1]

FossilOrigin-Name: 2978b65ebe25eeabe543b67cb266308cceb20082a4ae71565d6d083d7c08bc9f
This commit is contained in:
drh
2019-10-30 18:50:08 +00:00
parent 920cf596e6
commit 20cee7d0bb
10 changed files with 104 additions and 55 deletions

View File

@ -502,11 +502,13 @@ int sqlite3_totype_init(
int rc = SQLITE_OK; int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi); SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */ (void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "tointeger", 1, SQLITE_UTF8, 0, rc = sqlite3_create_function(db, "tointeger", 1,
tointegerFunc, 0, 0); SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
tointegerFunc, 0, 0);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "toreal", 1, SQLITE_UTF8, 0, rc = sqlite3_create_function(db, "toreal", 1,
torealFunc, 0, 0); SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
torealFunc, 0, 0);
} }
return rc; return rc;
} }

View File

@ -1,5 +1,5 @@
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. 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-30T16:29:02.506 D 2019-10-30T18:50:08.069
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -316,7 +316,7 @@ F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74 F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 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/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
F ext/misc/uuid.c db4db81e8c6a92ad6176ebd9f81dcb6870e331e1a286d0452f4319e3ba3df812 F ext/misc/uuid.c db4db81e8c6a92ad6176ebd9f81dcb6870e331e1a286d0452f4319e3ba3df812
F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35 F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35
@ -478,7 +478,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
F src/expr.c 23d5f9e491921a57fe6d59b75c461d45777470d8b1653180ebb3e83ea658f889 F src/expr.c 90c774b399e5df80e963fe23d18b36e0affe2949291a3ddf5555e14ef08e251e
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c ac56f02ffe7a3dff311654f86e3c2fd1ff2eb38862b0c07fd908d8cc0fb4a9a2 F src/fkey.c ac56f02ffe7a3dff311654f86e3c2fd1ff2eb38862b0c07fd908d8cc0fb4a9a2
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12 F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
@ -524,14 +524,14 @@ F src/pragma.h b45328f0946307b2e08f320abbb68e5352d94e45ce0a5c6d61ceb2f25a55b353
F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 9d6a3bdca1ebc759c4616fee0d7dd4cf62741f53db3a6b0117600f27c5b1406a F src/resolve.c cf2391c93d425455388389e7a47674b9da107d2ed69ebf49979044d70dbeb045
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 3395765ea3749341deb4c25e8339c3d626a8ac641a52c216e9632e48e620ba68 F src/select.c 3395765ea3749341deb4c25e8339c3d626a8ac641a52c216e9632e48e620ba68
F src/shell.c.in a17d143f186966ef24927b6b083f985ffdb95a01aa1bebaba7dcc706289bf7d2 F src/shell.c.in a17d143f186966ef24927b6b083f985ffdb95a01aa1bebaba7dcc706289bf7d2
F src/sqlite.h.in 5ba20664cede7f4e6861541fad1f17bac50f7bf576b40a8784c54f9126a9edd4 F src/sqlite.h.in 5ba20664cede7f4e6861541fad1f17bac50f7bf576b40a8784c54f9126a9edd4
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
F src/sqliteInt.h 5b2d25ba23135ece06886d82f60d9a16869506592e5950f3c09257b3b5d28d5c F src/sqliteInt.h 3ab4cce57fcda91b6b5377ba7d56dfb011d55b6a4a7d643c31dbefa06e00828a
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@ -602,7 +602,7 @@ F src/vdbe.c b67d6af853e03c3dd6d1116351567f62d8a2c10d3bd6db5f7f366e75d11c6653
F src/vdbe.h fdbc0a11e5768a702b46ce63286f60e22e71351a29bd98b3666405e1fccc7802 F src/vdbe.h fdbc0a11e5768a702b46ce63286f60e22e71351a29bd98b3666405e1fccc7802
F src/vdbeInt.h bd589b8b7273286858950717e0e1ec5c88b18af45079a3366dc1371865cea704 F src/vdbeInt.h bd589b8b7273286858950717e0e1ec5c88b18af45079a3366dc1371865cea704
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
F src/vdbeaux.c aeba258bb045c583bd85ae1e0b218c3542897baf522da1f1ab7da4259a7394ce F src/vdbeaux.c ab10ec13e61cffacf26024aa10053e66285d175b3d88d87966674b6b9b8820c4
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530 F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530
F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be F src/vdbesort.c a3be032cc3fee0e3af31773af4a7a6f931b7230a34f53282ccf1d9a2a72343be
@ -727,7 +727,7 @@ F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bc
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895 F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38 F test/check.test 25c6035302c846c7ff8e681cf8284473f6f01be94d327de60a688ad84ab01f8b
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
@ -794,7 +794,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 F test/date2.test 5ef8265c71460cda6b1698bf18f4bb0ffb40ac08c5092f6afe84d398c2feb5be
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292 F test/dbfuzz001.test 42aad1dcef6219fbee86a9b7d08832c9bbb2e41508f6f128ae91745927276292
@ -1057,7 +1057,7 @@ F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
F test/indexexpr1.test c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9 F test/indexexpr1.test 284e119999d132cc8bf37735a928c9859b28e8e295d02b7a6a4f93977c7f9ba5
F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1 F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@ -1848,7 +1848,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 13fe6978b7de208d2e27460d824f7fc778cf6ea0aabfe566b32bb410b8816f63 P 84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
R 2b5ad42e3fc6b49f0350688afce0bf63 R a5809c36248fb2412cd83c239c6f50ff
U drh U drh
Z 8fbcb7ba95c29435c7309e57f3022596 Z 0ef46baeb11e85e5dfc62c1770da0b94

View File

@ -1 +1 @@
84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0 2978b65ebe25eeabe543b67cb266308cceb20082a4ae71565d6d083d7c08bc9f

View File

@ -4033,7 +4033,7 @@ expr_code_doover:
#endif #endif
{ {
sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
pDef, pParse->iSelfTab); pDef, pExpr->op2);
} }
if( nFarg && constMask==0 ){ if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg); sqlite3ReleaseTempRange(pParse, r1, nFarg);
@ -5028,7 +5028,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
&& (combinedFlags & EP_Reduced)==0 && (combinedFlags & EP_Reduced)==0
){ ){
if( pA->iColumn!=pB->iColumn ) return 2; 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 ){ if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
return 2; return 2;
} }

View File

@ -815,15 +815,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
/* For the purposes of the EP_ConstFunc flag, date and time /* For the purposes of the EP_ConstFunc flag, date and time
** functions and other functions that change slowly are considered ** 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); ExprSetProperty(pExpr,EP_ConstFunc);
} }
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
/* Date/time functions that use 'now', and other functions like /* Date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used ** sqlite_version() that might change over time cannot be used
** in an index. */ ** in an index. */
notValid(pParse, pNC, "non-deterministic functions", notValid(pParse, pNC, "non-deterministic functions", NC_SelfRef);
NC_IdxExpr|NC_PartIdx|NC_GenCol); }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 if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0 && pParse->nested==0
@ -1789,11 +1792,13 @@ void sqlite3ResolveSelectNames(
** Resolve names in expressions that can only reference a single table ** Resolve names in expressions that can only reference a single table
** or which cannot reference any tables at all. Examples: ** or which cannot reference any tables at all. Examples:
** **
** (1) CHECK constraints ** "type" flag
** (2) WHERE clauses on partial indices ** ------------
** (3) Expressions in indexes on expressions ** (1) CHECK constraints NC_IsCheck
** (4) Expression arguments to VACUUM INTO. ** (2) WHERE clauses on partial indices NC_PartIdx
** (5) GENERATED ALWAYS as expressions ** (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 ** 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 ** nodes of the expression is set to -1 and the Expr.iColumn value is

View File

@ -2487,6 +2487,10 @@ typedef int ynVar;
struct Expr { struct Expr {
u8 op; /* Operation performed by this node */ u8 op; /* Operation performed by this node */
char affExpr; /* affinity, or RAISE type */ 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 */ u32 flags; /* Various flags. EP_* See below */
union { union {
char *zToken; /* Token value. Zero terminated and dequoted */ char *zToken; /* Token value. Zero terminated and dequoted */
@ -2525,9 +2529,6 @@ struct Expr {
** TK_SELECT_COLUMN: column of the result vector */ ** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ 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 */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
union { union {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@ -2840,9 +2841,10 @@ struct NameContext {
#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */ #define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */
#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */ #define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */
#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */ #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_HasAgg 0x00010 /* One or more aggregate functions seen */
#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */ #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_VarSelect 0x00040 /* A correlated subquery has been seen */
#define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UEList 0x00080 /* True if uNC.pEList is used */
#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */
@ -2852,7 +2854,7 @@ struct NameContext {
#define NC_AllowWin 0x04000 /* Window functions are allowed here */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */
#define NC_HasWin 0x08000 /* One or more window functions seen */ #define NC_HasWin 0x08000 /* One or more window functions seen */
#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ #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 ** An instance of the following object describes a single ON CONFLICT

View File

@ -365,11 +365,12 @@ int sqlite3VdbeAddFunctionCall(
} }
pCtx->pOut = 0; pCtx->pOut = 0;
pCtx->pFunc = (FuncDef*)pFunc; pCtx->pFunc = (FuncDef*)pFunc;
pCtx->pVdbe = v; pCtx->pVdbe = 0;
pCtx->isError = 0; pCtx->isError = 0;
pCtx->argc = nArg; pCtx->argc = nArg;
addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
p1, p2, p3, (char*)pCtx, P4_FUNCCTX); p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
pCtx->iOp = addr; pCtx->iOp = addr;
return addr; return addr;
} }
@ -4999,21 +5000,25 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
** features such as 'now'. ** features such as 'now'.
*/ */
int sqlite3NotPureFunc(sqlite3_context *pCtx){ int sqlite3NotPureFunc(sqlite3_context *pCtx){
const VdbeOp *pOp;
#ifdef SQLITE_ENABLE_STAT4 #ifdef SQLITE_ENABLE_STAT4
if( pCtx->pVdbe==0 ) return 1; if( pCtx->pVdbe==0 ) return 1;
#endif #endif
if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){ pOp = pCtx->pVdbe->aOp + pCtx->iOp;
#if 0 if( pOp->opcode==OP_PureFunc ){
char *zMsg = sqlite3_mprintf( const char *zContext;
"non-deterministic use of %s() in an index, CHECK constraint, " char *zMsg;
"or generated column", pCtx->pFunc->zName); 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_result_error(pCtx, zMsg, -1);
sqlite3_free(zMsg); sqlite3_free(zMsg);
#else
sqlite3_result_error(pCtx,
"non-deterministic function in index expression or CHECK constraint",
-1);
#endif
return 0; return 0;
} }
return 1; return 1;

View File

@ -442,7 +442,7 @@ do_test check-6.15 {
# #
reset_db reset_db
proc myfunc {x} {expr $x < 10} 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.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) } do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }

View File

@ -30,7 +30,7 @@ do_execsql_test date2-100 {
} {} } {}
do_catchsql_test date2-110 { do_catchsql_test date2-110 {
INSERT INTO t1(x,y) VALUES('now','two'); 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 { do_execsql_test date2-120 {
SELECT * FROM t1; SELECT * FROM t1;
} {2017-07-20 one} } {2017-07-20 one}
@ -45,7 +45,7 @@ do_execsql_test date2-200 {
} }
do_catchsql_test date2-210 { do_catchsql_test date2-210 {
INSERT INTO t2(x,y) VALUES(3, 'now'); 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 { do_execsql_test date2-220 {
SELECT x, y FROM t2 ORDER BY x; SELECT x, y FROM t2 ORDER BY x;
} {1 2017-07-20 2 xyzzy} } {1 2017-07-20 2 xyzzy}
@ -58,7 +58,7 @@ do_execsql_test date2-300 {
} }
do_catchsql_test date2-310 { do_catchsql_test date2-310 {
CREATE INDEX t3b1 ON t3(datetime(b)); 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 { do_catchsql_test date2-320 {
CREATE INDEX t3b1 ON t3(datetime(b)) WHERE typeof(b)='real'; CREATE INDEX t3b1 ON t3(datetime(b)) WHERE typeof(b)='real';
} {0 {}} } {0 {}}
@ -84,7 +84,7 @@ do_execsql_test date2-400 {
do_catchsql_test date2-410 { do_catchsql_test date2-410 {
CREATE INDEX t4b1 ON t4(b) CREATE INDEX t4b1 ON t4(b)
WHERE date(b) BETWEEN '2017-06-01' AND '2017-08-31'; 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 { do_execsql_test date2-420 {
DELETE FROM t4 WHERE a=500; DELETE FROM t4 WHERE a=500;
CREATE INDEX t4b1 ON t4(b) CREATE INDEX t4b1 ON t4(b)
@ -92,7 +92,7 @@ do_execsql_test date2-420 {
} }
do_catchsql_test date2-430 { do_catchsql_test date2-430 {
INSERT INTO t4(a,b) VALUES(9999,'now'); 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 { do_execsql_test date2-500 {
CREATE TABLE mods(x); CREATE TABLE mods(x);
@ -121,14 +121,49 @@ do_execsql_test date2-500 {
} }
do_catchsql_test date2-510 { do_catchsql_test date2-510 {
INSERT INTO t5(y,m) VALUES('2017-07-20','localtime'); 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 { do_catchsql_test date2-520 {
INSERT INTO t5(y,m) VALUES('2017-07-20','utc'); 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 finish_test

View File

@ -186,7 +186,7 @@ do_catchsql_test indexexpr1-300 {
} {1 {non-deterministic functions prohibited in index expressions}} } {1 {non-deterministic functions prohibited in index expressions}}
do_catchsql_test indexexpr1-301 { do_catchsql_test indexexpr1-301 {
CREATE INDEX t2x1 ON t2(julianday('now',a)); 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 { do_catchsql_test indexexpr1-310 {
CREATE INDEX t2x2 ON t2(a,b+(SELECT 15)); CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
} {1 {subqueries prohibited in index expressions}} } {1 {subqueries prohibited in index expressions}}