diff --git a/manifest b/manifest index b22ec0fccc..8076acadd4 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 49b5fd7ed6..2fa3ac8c9d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a5e1c04d9d07bb7fd6546a9ddac1bf42b19ea19c2b79570aea6cd4226887a27 \ No newline at end of file +22eda0985ecd1f456c073e6ad735a8417f3ff1fb6aaad1640e1cec01e50c51d8 \ No newline at end of file diff --git a/src/date.c b/src/date.c index a7f849abdb..c0ca4c9904 100644 --- a/src/date.c +++ b/src/date.c @@ -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); diff --git a/src/expr.c b/src/expr.c index d6896edaf5..6a3ccd833e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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 */ diff --git a/src/insert.c b/src/insert.c index f296740a3e..20e3736d76 100644 --- a/src/insert.c +++ b/src/insert.c @@ -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; inExpr; 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 ){ diff --git a/src/pragma.c b/src/pragma.c index 6f469c7d92..e640c7ebe5 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -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); diff --git a/src/shell.c b/src/shell.c index 0be869b8fc..eaefe62012 100644 --- a/src/shell.c +++ b/src/shell.c @@ -8396,4 +8396,3 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif return rc; } - diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 97d43782dd..e44c733b17 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 */ diff --git a/src/vdbe.h b/src/vdbe.h index d2d1ae738a..3e77eb9db5 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -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. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 97c954b536..ce9e98bb46 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -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 index 0000000000..f2f04cb6e9 --- /dev/null +++ b/test/date2.test @@ -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 diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 08bccd3a29..b940965495 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -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}}