]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Always disallow the use of non-deterministic functions in CHECK constraints,
authordrh <drh@noemail.net>
Wed, 30 Oct 2019 18:50:08 +0000 (18:50 +0000)
committerdrh <drh@noemail.net>
Wed, 30 Oct 2019 18:50:08 +0000 (18:50 +0000)
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

ext/misc/totype.c
manifest
manifest.uuid
src/expr.c
src/resolve.c
src/sqliteInt.h
src/vdbeaux.c
test/check.test
test/date2.test
test/indexexpr1.test

index 5dc99f3d7dc5f36ba4adf311e18b55a24bc29e7e..c9655c3dbf437077693bf9a1fe122e5af948ad79 100644 (file)
@@ -502,11 +502,13 @@ int sqlite3_totype_init(
   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;
 }
index 5f1f7568dd11d64fbe195eb81f8d26790787423f..8a8bf3650bf265aabda61286c21806f5ab9439e1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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.
-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
@@ -316,7 +316,7 @@ F ext/misc/spellfix.c f88ecb2c0294453ce8b7704b211f5350c41b085b38c8e056852e3a08b0
 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
@@ -478,7 +478,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 23d5f9e491921a57fe6d59b75c461d45777470d8b1653180ebb3e83ea658f889
+F src/expr.c 90c774b399e5df80e963fe23d18b36e0affe2949291a3ddf5555e14ef08e251e
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c ac56f02ffe7a3dff311654f86e3c2fd1ff2eb38862b0c07fd908d8cc0fb4a9a2
 F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
@@ -524,14 +524,14 @@ F src/pragma.h b45328f0946307b2e08f320abbb68e5352d94e45ce0a5c6d61ceb2f25a55b353
 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
@@ -602,7 +602,7 @@ F src/vdbe.c b67d6af853e03c3dd6d1116351567f62d8a2c10d3bd6db5f7f366e75d11c6653
 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
@@ -727,7 +727,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 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38
+F test/check.test 25c6035302c846c7ff8e681cf8284473f6f01be94d327de60a688ad84ab01f8b
 F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
 F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
@@ -794,7 +794,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
 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
@@ -1057,7 +1057,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 c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9
+F test/indexexpr1.test 284e119999d132cc8bf37735a928c9859b28e8e295d02b7a6a4f93977c7f9ba5
 F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1
 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@@ -1848,7 +1848,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 13fe6978b7de208d2e27460d824f7fc778cf6ea0aabfe566b32bb410b8816f63
-R 2b5ad42e3fc6b49f0350688afce0bf63
+P 84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
+R a5809c36248fb2412cd83c239c6f50ff
 U drh
-Z 8fbcb7ba95c29435c7309e57f3022596
+Z 0ef46baeb11e85e5dfc62c1770da0b94
index 924a8fc5ec84eca31cdd668f73a1162f08f9bff2..7163f2adf6c49da44048f9015521a119ac81ee89 100644 (file)
@@ -1 +1 @@
-84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
\ No newline at end of file
+2978b65ebe25eeabe543b67cb266308cceb20082a4ae71565d6d083d7c08bc9f
\ No newline at end of file
index 36ab7c795a6a181109ac297aba8863fd0e933c94..b0c61f00f842ec81c44ee5009c6faef0218264ac 100644 (file)
@@ -4033,7 +4033,7 @@ expr_code_doover:
 #endif
       {
         sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
-                                   pDef, pParse->iSelfTab);
+                                   pDef, pExpr->op2);
       }
       if( nFarg && constMask==0 ){
         sqlite3ReleaseTempRange(pParse, r1, nFarg);
@@ -5028,7 +5028,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
      && (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;
       }
index a9c20b1016284e853bbcccc16e2cedb32422aee7..9be62c0902aebeca490d113bef284768deed8c79 100644 (file)
@@ -815,15 +815,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
         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
@@ -1789,11 +1792,13 @@ void sqlite3ResolveSelectNames(
 ** 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
index d8668a278fb32d2974edde234ab57b5dc2e3239c..cf7abfe66c027dca3bc224eda33b5ad16ede4943 100644 (file)
@@ -2487,6 +2487,10 @@ typedef int ynVar;
 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 */
@@ -2525,9 +2529,6 @@ struct Expr {
                          ** 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
@@ -2840,9 +2841,10 @@ struct NameContext {
 #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 */
@@ -2852,7 +2854,7 @@ struct NameContext {
 #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
index de6575cd51dcf0aa9391885955dd340513ecd380..9596e163b0fde576f81118813359eb199349d36a 100644 (file)
@@ -365,11 +365,12 @@ int sqlite3VdbeAddFunctionCall(
   }
   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;
 }
@@ -4999,21 +5000,25 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
 ** 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;
index e23043eb045002f22d4933483f78e8fd0f75c437..ac0a9ac6ba2ed0d0d3f2bdab9ecf33b96d425a00 100644 (file)
@@ -442,7 +442,7 @@ do_test check-6.15 {
 #
 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)  }
index 2815df5ec772350cfaa5dd56a41bdb92a7a63fc8..820420ccf50027eac216493b9132ae28b2eb3732 100644 (file)
@@ -30,7 +30,7 @@ do_execsql_test date2-100 {
 } {}
 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}
@@ -45,7 +45,7 @@ do_execsql_test date2-200 {
 }
 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}
@@ -58,7 +58,7 @@ do_execsql_test date2-300 {
 }
 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 {}}
@@ -84,7 +84,7 @@ do_execsql_test date2-400 {
 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)
@@ -92,7 +92,7 @@ do_execsql_test date2-420 {
 }
 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);
@@ -121,14 +121,49 @@ do_execsql_test date2-500 {
 }
 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
index 6b134dbd3f4720bd49cc914b403f603bf2ac7200..19c2573509eebfc6c636e5d2ae7ea9e8029e5e67 100644 (file)
@@ -186,7 +186,7 @@ do_catchsql_test indexexpr1-300 {
 } {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}}