]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Combine the Parse.ckBase and Parse.iSelfTab fields into just Parse.iSelfTab.
authordrh <drh@noemail.net>
Thu, 20 Jul 2017 13:17:08 +0000 (13:17 +0000)
committerdrh <drh@noemail.net>
Thu, 20 Jul 2017 13:17:08 +0000 (13:17 +0000)
This fixes a problem with date/time functions in check-constraints.  Add
some test cases for date/time functions in index expressions and check
constraints.

FossilOrigin-Name: 22eda0985ecd1f456c073e6ad735a8417f3ff1fb6aaad1640e1cec01e50c51d8

12 files changed:
manifest
manifest.uuid
src/date.c
src/expr.c
src/insert.c
src/pragma.c
src/shell.c
src/sqliteInt.h
src/vdbe.h
src/vdbeaux.c
test/date2.test [new file with mode: 0644]
test/indexexpr1.test

index b22ec0fccc643eb45213dcc682e7c77277b47f91..8076acadd49bcedcc12f951d68ba6eea3704aee3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Allow\sindexes\sto\sbe\screated\son\sdate/time\sfunctions\sas\slong\sas\sthe\s'now'\ndate\sand\sthe\s'localtime'\sand\s'utc'\smodifiers\sare\snot\sused.
-D 2017-07-19T19:48:40.351
+C Combine\sthe\sParse.ckBase\sand\sParse.iSelfTab\sfields\sinto\sjust\sParse.iSelfTab.\nThis\sfixes\sa\sproblem\swith\sdate/time\sfunctions\sin\scheck-constraints.\s\sAdd\nsome\stest\scases\sfor\sdate/time\sfunctions\sin\sindex\sexpressions\sand\scheck\nconstraints.
+D 2017-07-20T13:17:08.298
 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -402,10 +402,10 @@ F src/build.c 74108007d286232fb4290464ee5452fa860c26215f8caa0e6c7cbf69a6fafe8f
 F src/callback.c 8e14b60d1ed1c87c02cb5f121ecda99224f2aea6524a77ee6f72c9b5c7110f84
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 928954802b1397d9fb1378c7eb702c94b4735bbab1d5793e21b6a77734f56a1b
-F src/date.c 921fb5957cacfb4e512d25efa13fbdf5f3ebade2077a0809fbe24105d2f33cff
+F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
 F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
 F src/delete.c 939bd15e6b54b82b951e1c0ffc2ff2b4ab579196780a1f6d394e47bd6f799b6c
-F src/expr.c 17fb28516a5fbfbabdade6b3401c797b0804de25e36b7b1becff2cf07921dc4c
+F src/expr.c fdb2fc465cabbf372fecad1fc2b291758bec74150b4db0fb945332e09df28a0e
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
 F src/func.c e2854b19386b93ad6b498a3f3b7d6baa98ec14cfe84530fb12fce4414263d871
@@ -414,7 +414,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391
+F src/insert.c 487d2c1cd8d549f8d9492377ecc4d2f507b1bd5185e96c54389f6b607dce854c
 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2
 F src/main.c 3a9da9e3974d8a32ef6ca15b75503d540af22d284beb75bc7f0d93254ca3f8f7
@@ -445,7 +445,7 @@ F src/parse.y e384cb73f99e1b074085c974b37f4d830e885359e4b60837e30f7d67c16ba65b
 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
-F src/pragma.c 95672b7dc59930b4978d08baa8c357085767cc30e5d3ddac9b12592489d3ede2
+F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2
 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
 F src/prepare.c dd250f904739b1dc449c131ac527c35e3424d94082dd111321bd83f80c6bb0fe
 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
@@ -453,12 +453,12 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c c6bf96a7f9d7d68f929de84738c599a30d0a725ab0b54420e70545743cd5ee7b
-F src/shell.c dd4494287b22ac5ab0654fdd5acb1f2172d2fe621f673a39229ddc31bd8d598f
+F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
 F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
 F src/sqlite.h.in dad804d4e1979a2ddec33cc8da6aa50c04e6ba0dcb4058e7b3609588d010e041
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 967154985ed2ae62f90d9029bb5b5071793d847f1696a2ebe9e8cc0b042ae60b
-F src/sqliteInt.h 9b57e05822422268d5a20fa797afd23bf2b039c8401e87dff26700c0c39faf34
+F src/sqliteInt.h 96197a18f041b9ab99e6cee0db39dbf771ac7762d9f0f63d9e719285f0478664
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -521,10 +521,10 @@ F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
 F src/vdbe.c 1e541ec7ff409bbabcc6b4f154957296fff5827c16c2ab0056348acae75685bf
-F src/vdbe.h c1fc5b3d31756eb12b7bf43595260388b01f2c85e65fdb6ac0c3f618bfcaf717
+F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
 F src/vdbeInt.h 19bd04a4211fe56c712ab35b48be77fd5a0579b851e9dea2cb8deade359b72b9
 F src/vdbeapi.c 52844a5a71712197be45f1c63d730c48a745c7457c959465cfb2b969af40a266
-F src/vdbeaux.c 23a02ba4195b5cc4d48a494d52a8cd5a194ce5f80e8a295c302bcbabccf39979
+F src/vdbeaux.c 42e215cc6f69e91eebdd2b886ec1ff2b0d5e44331bd8b88a0a44e78bbeed7133
 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
 F src/vdbemem.c fe8fce1cdc258320b465934039fe4b1230d63f81d6b81b1eac775b6eec00af0d
 F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
@@ -697,6 +697,7 @@ F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807
 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
+F test/date2.test f8d82bb0bdcab156e2f480337bd874b89fe175a52cd0de0db583eee226d32bbe
 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
@@ -935,7 +936,7 @@ F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
-F test/indexexpr1.test 1857373a97e4795ce4119caf05cbb148bdabe1c8738fc0b7e5e240abb6adbe4e
+F test/indexexpr1.test f06298de30f343f6a022c3b13ae82817bb52a169f2b23a13600688aa591be5d9
 F test/indexexpr2.test 3ddd7f23bc381b9f2b7a15f2d083b1a4078e7733dce8295602ecfa3c74a34cf9
 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@@ -1636,10 +1637,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 d14fc621e918915bbf8e04597eb238ea78dff3d9c5eb4402cb88692d00dbdfee
-R 71a176dbaf167be1fc010ab41b45c196
-T *branch * index-on-date-func
-T *sym-index-on-date-func *
-T -sym-trunk *
+P 0a5e1c04d9d07bb7fd6546a9ddac1bf42b19ea19c2b79570aea6cd4226887a27
+R a25d10c9c943ee05f3ba67aef01e9e07
 U drh
-Z 6174c3091e77280f162146b58b68a8ad
+Z d1c30883ae74083a00de3da1ad7b0ca1
index 49b5fd7ed6a67ff7e9df8f1119c2db0ed25bb6c7..2fa3ac8c9d9c1da61cafc98e18c7b332d64b2121 100644 (file)
@@ -1 +1 @@
-0a5e1c04d9d07bb7fd6546a9ddac1bf42b19ea19c2b79570aea6cd4226887a27
\ No newline at end of file
+22eda0985ecd1f456c073e6ad735a8417f3ff1fb6aaad1640e1cec01e50c51d8
\ No newline at end of file
index a7f849abdb225fd40d681e538ada010b44279a7c..c0ca4c99049b377ac1012e22639175d7e9af9f33 100644 (file)
@@ -386,8 +386,7 @@ static int parseDateOrTime(
     return 0;
   }else if( parseHhMmSs(zDate, p)==0 ){
     return 0;
-  }else if( sqlite3StrICmp(zDate,"now")==0 ){
-    sqlite3VdbePureFuncOnly(context);
+  }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
     return setDateTimeToCurrent(context, p);
   }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
     setRawDateNumber(p, r);
@@ -670,8 +669,7 @@ static int parseModifier(
       ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
       ** show local time.
       */
-      if( sqlite3_stricmp(z, "localtime")==0 ){
-        sqlite3VdbePureFuncOnly(pCtx);
+      if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
         computeJD(p);
         p->iJD += localtimeOffset(p, pCtx, &rc);
         clearYMD_HMS_TZ(p);
@@ -697,8 +695,7 @@ static int parseModifier(
         }
       }
 #ifndef SQLITE_OMIT_LOCALTIME
-      else if( sqlite3_stricmp(z, "utc")==0 ){
-        sqlite3VdbePureFuncOnly(pCtx);
+      else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
         if( p->tzSet==0 ){
           sqlite3_int64 c1;
           computeJD(p);
index d6896edaf54f220527c26c8331ed291f20888897..6a3ccd833e96c92d5741cd1c8b5f2a5db8bf2890 100644 (file)
@@ -3484,9 +3484,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
     case TK_COLUMN: {
       int iTab = pExpr->iTable;
       if( iTab<0 ){
-        if( pParse->ckBase>0 ){
+        if( pParse->iSelfTab<0 ){
           /* Generating CHECK constraints or inserting into partial index */
-          return pExpr->iColumn + pParse->ckBase;
+          return pExpr->iColumn - pParse->iSelfTab;
         }else{
           /* Coding an expression that is part of an index where column names
           ** in the index refer to the table to which the index belongs */
index f296740a3ed0738c23fff4c86c1ea8ca3192bca5..20e3736d76f409ca3344d9afc5cec4ae9b038035 100644 (file)
@@ -1333,7 +1333,7 @@ void sqlite3GenerateConstraintChecks(
 #ifndef SQLITE_OMIT_CHECK
   if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
     ExprList *pCheck = pTab->pCheck;
-    pParse->ckBase = regNewData+1;
+    pParse->iSelfTab = -(regNewData+1);
     onError = overrideError!=OE_Default ? overrideError : OE_Abort;
     for(i=0; i<pCheck->nExpr; i++){
       int allOk;
@@ -1353,6 +1353,7 @@ void sqlite3GenerateConstraintChecks(
       }
       sqlite3VdbeResolveLabel(v, allOk);
     }
+    pParse->iSelfTab = 0;
   }
 #endif /* !defined(SQLITE_OMIT_CHECK) */
 
@@ -1497,10 +1498,10 @@ void sqlite3GenerateConstraintChecks(
     /* Skip partial indices for which the WHERE clause is not true */
     if( pIdx->pPartIdxWhere ){
       sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
-      pParse->ckBase = regNewData+1;
+      pParse->iSelfTab = -(regNewData+1);
       sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
                             SQLITE_JUMPIFNULL);
-      pParse->ckBase = 0;
+      pParse->iSelfTab = 0;
     }
 
     /* Create a record for this index entry as it should appear after
@@ -1511,9 +1512,9 @@ void sqlite3GenerateConstraintChecks(
       int iField = pIdx->aiColumn[i];
       int x;
       if( iField==XN_EXPR ){
-        pParse->ckBase = regNewData+1;
+        pParse->iSelfTab = -(regNewData+1);
         sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
-        pParse->ckBase = 0;
+        pParse->iSelfTab = 0;
         VdbeComment((v, "%s column %d", pIdx->zName, i));
       }else{
         if( iField==XN_ROWID || iField==pTab->iPKey ){
index 6f469c7d92da940683a32b99d44682865e10e090..e640c7ebe510c29b91c111dcb61712a1f0926da2 100644 (file)
@@ -1594,7 +1594,7 @@ void sqlite3Pragma(
             int addrCkOk = sqlite3VdbeMakeLabel(v);
             char *zErr;
             int k;
-            pParse->iSelfTab = iDataCur+1;
+            pParse->iSelfTab = iDataCur + 1;
             sqlite3ExprCachePush(pParse);
             for(k=pCheck->nExpr-1; k>0; k--){
               sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
index 0be869b8fc465d47955b68f3cae3962b68b9bbc2..eaefe62012752ff2098be992e5fd7f23e0cdb56d 100644 (file)
@@ -8396,4 +8396,3 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
 #endif
   return rc;
 }
-
index 97d43782dd3a188a3f335768f3018e4b0e89d7b5..e44c733b170aa3cec0a948aad76f5cfed2bafa22 100644 (file)
@@ -2963,8 +2963,8 @@ struct Parse {
   int nMem;            /* Number of memory cells used so far */
   int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
   int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
-  int ckBase;          /* Base register of data during check constraints */
-  int iSelfTab;        /* Table of an index whose exprs are being coded */
+  int iSelfTab;        /* Table for associated with an index on expr, or negative
+                       ** of the base register during check-constraint eval */
   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
   int nLabel;          /* Number of labels used */
index d2d1ae738a5d8664d11ed7c794319dc86789b83c..3e77eb9db5f3c9ce76ef0bfa546ebc609feb98d7 100644 (file)
@@ -253,7 +253,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
 void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
 #endif
 
-void sqlite3VdbePureFuncOnly(sqlite3_context*);
+int sqlite3NotPureFunc(sqlite3_context*);
 
 /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
 ** each VDBE opcode.
index 97c954b53609296bfc7c9f389ab0349b90e3df66..ce9e98bb46f2adc1a857c8bbc66045cfcc71de94 100644 (file)
@@ -4592,11 +4592,14 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
 ** This routine is invoked by date/time functions that use non-deterministic
 ** features such as 'now'.
 */
-void sqlite3VdbePureFuncOnly(sqlite3_context *pCtx){
+int sqlite3NotPureFunc(sqlite3_context *pCtx){
   if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
     sqlite3_result_error(pCtx, 
-       "non-deterministic functions prohibited in index expressions", -1);
+       "non-deterministic function in index expression or CHECK constraint",
+       -1);
+    return 0;
   }
+  return 1;
 }
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
diff --git a/test/date2.test b/test/date2.test
new file mode 100644 (file)
index 0000000..f2f04cb
--- /dev/null
@@ -0,0 +1,53 @@
+# 2017-07-20
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this file is testing date and time functions used in
+# check constraints and index expressions.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Skip this whole file if date and time functions are omitted
+# at compile-time
+#
+ifcapable {!datetime} {
+  finish_test
+  return
+}
+
+do_execsql_test date2-100 {
+  CREATE TABLE t1(x, y, CHECK( date(x) BETWEEN '2017-07-01' AND '2017-07-31' ));
+  INSERT INTO t1(x,y) VALUES('2017-07-20','one');
+} {}
+do_catchsql_test date2-110 {
+  INSERT INTO t1(x,y) VALUES('now','two');
+} {1 {non-deterministic function in index expression or CHECK constraint}}
+do_execsql_test date2-120 {
+  SELECT * FROM t1;
+} {2017-07-20 one}
+do_catchsql_test date2-130 {
+  INSERT INTO t1(x,y) VALUES('2017-08-01','two');
+} {1 {CHECK constraint failed: t1}}
+
+do_execsql_test date2-200 {
+  CREATE TABLE t2(x,y);
+  INSERT INTO t2(x,y) VALUES(1, '2017-07-20'), (2, 'xyzzy');
+  CREATE INDEX t2y ON t2(date(y));
+}
+do_catchsql_test date2-210 {
+  INSERT INTO t2(x,y) VALUES(3, 'now');
+} {1 {non-deterministic function in index expression or CHECK constraint}}
+do_execsql_test date2-220 {
+  SELECT x, y FROM t2 ORDER BY x;
+} {1 2017-07-20 2 xyzzy}
+
+finish_test
index 08bccd3a299e89c16f56a5d4206b377424098875..b9409654955ef1c04a711415723a4917bd97e61c 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}}
+} {1 {non-deterministic function in index expression or CHECK constraint}}
 do_catchsql_test indexexpr1-310 {
   CREATE INDEX t2x2 ON t2(a,b+(SELECT 15));
 } {1 {subqueries prohibited in index expressions}}