From d4af882a1bebbefa02cb40ba85b78c82d1deebd9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Feb 2023 21:55:14 +0000 Subject: [PATCH 1/5] Add support for the 'txn' argument to date/time functions that works like 'now' but keeps the same time for the entire transaction. FossilOrigin-Name: 5e4f45af96247e29910403a63ac148cb313b005f9c014b37a9a49d98f5fef9a6 --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/date.c | 29 +++++++++++++++++++++++++---- src/sqliteInt.h | 2 ++ src/vdbeapi.c | 23 +++++++++++++++++++++++ src/vdbeaux.c | 1 + 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b1319ebcd5..d91cd340c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sscript\sproblem\scausing\s"make\stest"\sto\sfail\sfor\snon-RBU\sbuilds. -D 2023-02-07T18:41:23.632 +C Add\ssupport\sfor\sthe\s'txn'\sargument\sto\sdate/time\sfunctions\sthat\sworks\slike\n'now'\sbut\skeeps\sthe\ssame\stime\sfor\sthe\sentire\stransaction. +D 2023-02-07T21:55:14.119 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -567,7 +567,7 @@ F src/build.c c55ab6d1b089ceef57160e840f05f692955ac90944c3d04fcf01d97fd7bfd08d F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 94ce83b4cd848a387680a5f920c9018c16655db778c4d36525af0a0f34679ac5 +F src/date.c ff2d10db98269759315c2048d3cc16cc135f7b39f394fa7442e37f9f9161892f F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e @@ -626,7 +626,7 @@ F src/shell.c.in 250817509dbf12e258e334fdcd87901e35a6b63dc285885fec5f577ebb67b49 F src/sqlite.h.in e26116b4dba94903c78db0f3281493435cf70ee049e2e8270b1013fad740fdb1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 43eeee1ea80543a0e40444bf53643ca259a2b1158ccfe859a6a6435b7358ecdd +F src/sqliteInt.h 459e7dc3936c3f3321d588f9e74c1298526c29dced7e3b9c0b63de5a5e5ecdcc F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -694,8 +694,8 @@ F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd F src/vdbe.c 47d3b78e75e239e1909933f0d77612b4111ebe760f01fdd0085e4e30b59b4cc6 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb -F src/vdbeapi.c 40c47b1528d308a322203de21d2e0d711753257ed9771771b6129214b1d65932 -F src/vdbeaux.c 3f9e3b6585e7434aa11300169dd66ddf0fc963a0c6f7940bdc058335dadeb353 +F src/vdbeapi.c 0760fbeea76491a4c5b79ff0ec212915e7fe27c60ba319ef232ec25403ef4493 +F src/vdbeaux.c 9f2a2ec80ff90266ab603065c32dd3c8b0a53023ab7210a03fccf324ad6ddbce F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 87d3811aabb68eb9210c14c9a8b5e8ec3acb7ba787beb80a4323af54fb6013f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -2045,8 +2045,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a95dbfae6133cc7aac950c3e7ba55a29d80b1625c39479a7d1d10b0868ee2be4 -R eadbc6d63430234ac2cb17610c353b99 -U dan -Z b7b3585268bb0984169cdf414e4a24fd +P 2abc3f9de0d2b66342598ab9015e62568ed20c7da4744a0f0a76b1db72c7e941 +R c0a88244db992b40f65ce347d314e978 +T *branch * txn-date +T *sym-txn-date * +T -sym-trunk * +U drh +Z 947981482da05fefcea564acb307123a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 40eb42fb45..3cfde09ef5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2abc3f9de0d2b66342598ab9015e62568ed20c7da4744a0f0a76b1db72c7e941 \ No newline at end of file +5e4f45af96247e29910403a63ac148cb313b005f9c014b37a9a49d98f5fef9a6 \ No newline at end of file diff --git a/src/date.c b/src/date.c index a3e58bc4e3..21077df93f 100644 --- a/src/date.c +++ b/src/date.c @@ -331,11 +331,13 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ } /* -** Set the time to the current time reported by the VFS. +** Set the time to the current time reported for the prepared statement +** that is currently executing. The same time is reported for all +** invocations of this routine from within the same call to sqlite3_step(). ** ** Return the number of errors. */ -static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ +static int setCurrentStmtTime(sqlite3_context *context, DateTime *p){ p->iJD = sqlite3StmtCurrentTime(context); if( p->iJD>0 ){ p->validJD = 1; @@ -345,6 +347,23 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ } } +/* +** Set the time to the current time reported for the current transaction. +** The same time is set for all calls to this routine within the same +** transaction. +** +** Return the number of errors. +*/ +static int setCurrentTxnTime(sqlite3_context *context, DateTime *p){ + p->iJD = sqlite3TxnCurrentTime(context); + if( p->iJD>0 ){ + p->validJD = 1; + return 0; + }else{ + return 1; + } +} + /* ** Input "r" is a numeric quantity which might be a julian day number, ** or the number of seconds since 1970. If the value if r is within @@ -387,7 +406,9 @@ static int parseDateOrTime( }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ - return setDateTimeToCurrent(context, p); + return setCurrentStmtTime(context, p); + }else if( sqlite3StrICmp(zDate,"txn")==0 && sqlite3NotPureFunc(context) ){ + return setCurrentTxnTime(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; @@ -946,7 +967,7 @@ static int isDate( memset(p, 0, sizeof(*p)); if( argc==0 ){ if( !sqlite3NotPureFunc(context) ) return 1; - return setDateTimeToCurrent(context, p); + return setCurrentStmtTime(context, p); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3da5f13d5b..638260c5dc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1621,6 +1621,7 @@ struct sqlite3 { u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ u8 eOpenState; /* Current condition of the connection */ int nextPagesize; /* Pagesize after VACUUM if >0 */ + i64 txnTime; /* Timestamp for current transaction */ i64 nChange; /* Value returned by sqlite3_changes() */ i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ @@ -5341,6 +5342,7 @@ FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); void sqlite3VtabUsesAllSchemas(sqlite3_index_info*); #endif sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); +sqlite3_int64 sqlite3TxnCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); void sqlite3ParseObjectInit(Parse*,sqlite3*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 476b6a2adf..432c1fa225 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -987,6 +987,29 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ return *piTime; } +/* +** Return the current time for a transaction. If the current time +** is requested more than once within the same transaction +** the same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. +*/ +sqlite3_int64 sqlite3TxnCurrentTime(sqlite3_context *p){ + int rc; +#ifndef SQLITE_ENABLE_STAT4 + sqlite3_int64 *piTime = &p->pVdbe->db->txnTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->db->txnTime : &iTime; +#endif + if( *piTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; + } + return *piTime; +} + /* ** Create a new aggregate context for p and return a pointer to ** its pMem->z element. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d04d8f1e17..82dc607154 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3394,6 +3394,7 @@ int sqlite3VdbeHalt(Vdbe *p){ */ if( db->autoCommit ){ sqlite3ConnectionUnlocked(db); + db->txnTime = 0; } assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); From 3393ee7ff613780888ce67934571e274c5ebb302 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Feb 2023 23:55:59 +0000 Subject: [PATCH 2/5] Simplify the code and add test cases. FossilOrigin-Name: d3bed4caff561e71c396cc869c5b4d9bf216ba203485e738c12ec62741f1aba5 --- manifest | 21 +++++++--------- manifest.uuid | 2 +- src/date.c | 27 +++++--------------- src/sqliteInt.h | 3 +-- src/vdbeapi.c | 40 ++++++++++-------------------- test/date.test | 66 ++++++++++++++++++++++++++++++++++++++++--------- 6 files changed, 85 insertions(+), 74 deletions(-) diff --git a/manifest b/manifest index d91cd340c4..1be3d9ae98 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sthe\s'txn'\sargument\sto\sdate/time\sfunctions\sthat\sworks\slike\n'now'\sbut\skeeps\sthe\ssame\stime\sfor\sthe\sentire\stransaction. -D 2023-02-07T21:55:14.119 +C Simplify\sthe\scode\sand\sadd\stest\scases. +D 2023-02-07T23:55:59.881 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -567,7 +567,7 @@ F src/build.c c55ab6d1b089ceef57160e840f05f692955ac90944c3d04fcf01d97fd7bfd08d F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c ff2d10db98269759315c2048d3cc16cc135f7b39f394fa7442e37f9f9161892f +F src/date.c 0c5db79ea1d5951ed917fa43046e9cc146dfbef5ff46106abe76b69e2523a9f5 F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e @@ -626,7 +626,7 @@ F src/shell.c.in 250817509dbf12e258e334fdcd87901e35a6b63dc285885fec5f577ebb67b49 F src/sqlite.h.in e26116b4dba94903c78db0f3281493435cf70ee049e2e8270b1013fad740fdb1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 459e7dc3936c3f3321d588f9e74c1298526c29dced7e3b9c0b63de5a5e5ecdcc +F src/sqliteInt.h 859e193140c393a9a50dd81345b95130b208a312dd064867065c5e637232ed58 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -694,7 +694,7 @@ F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd F src/vdbe.c 47d3b78e75e239e1909933f0d77612b4111ebe760f01fdd0085e4e30b59b4cc6 F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb -F src/vdbeapi.c 0760fbeea76491a4c5b79ff0ec212915e7fe27c60ba319ef232ec25403ef4493 +F src/vdbeapi.c be64df0e21a43056b62f46777749347b7d51f6e5e6c419c4bf42ce9bf98d6064 F src/vdbeaux.c 9f2a2ec80ff90266ab603065c32dd3c8b0a53023ab7210a03fccf324ad6ddbce F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 87d3811aabb68eb9210c14c9a8b5e8ec3acb7ba787beb80a4323af54fb6013f7 @@ -910,7 +910,7 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47 F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614c7fe201 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 -F test/date.test 118e04db8c8b4efeb885542b4918c7b869a34c460a6bebbfe927dfd75706b80d +F test/date.test 0890bbd03f722169ae34f6d6f7822061d5fda8742355438562638ebed07e227c F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 @@ -2045,11 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2abc3f9de0d2b66342598ab9015e62568ed20c7da4744a0f0a76b1db72c7e941 -R c0a88244db992b40f65ce347d314e978 -T *branch * txn-date -T *sym-txn-date * -T -sym-trunk * +P 5e4f45af96247e29910403a63ac148cb313b005f9c014b37a9a49d98f5fef9a6 +R c20bc84a84eb9b7dcb5243c1d98778fa U drh -Z 947981482da05fefcea564acb307123a +Z 4b08eb982cff98771c7da608dde8a084 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3cfde09ef5..b7c2e2f8f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e4f45af96247e29910403a63ac148cb313b005f9c014b37a9a49d98f5fef9a6 \ No newline at end of file +d3bed4caff561e71c396cc869c5b4d9bf216ba203485e738c12ec62741f1aba5 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 21077df93f..6c48d45e33 100644 --- a/src/date.c +++ b/src/date.c @@ -335,27 +335,12 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ ** that is currently executing. The same time is reported for all ** invocations of this routine from within the same call to sqlite3_step(). ** -** Return the number of errors. -*/ -static int setCurrentStmtTime(sqlite3_context *context, DateTime *p){ - p->iJD = sqlite3StmtCurrentTime(context); - if( p->iJD>0 ){ - p->validJD = 1; - return 0; - }else{ - return 1; - } -} - -/* -** Set the time to the current time reported for the current transaction. -** The same time is set for all calls to this routine within the same -** transaction. +** Or if bTxn is true, use the transaction time. ** ** Return the number of errors. */ -static int setCurrentTxnTime(sqlite3_context *context, DateTime *p){ - p->iJD = sqlite3TxnCurrentTime(context); +static int setCurrentStmtTime(sqlite3_context *context, DateTime *p, int bTxn){ + p->iJD = sqlite3StmtCurrentTime(context, bTxn); if( p->iJD>0 ){ p->validJD = 1; return 0; @@ -406,9 +391,9 @@ static int parseDateOrTime( }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ - return setCurrentStmtTime(context, p); + return setCurrentStmtTime(context, p, 0); }else if( sqlite3StrICmp(zDate,"txn")==0 && sqlite3NotPureFunc(context) ){ - return setCurrentTxnTime(context, p); + return setCurrentStmtTime(context, p, 1); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; @@ -967,7 +952,7 @@ static int isDate( memset(p, 0, sizeof(*p)); if( argc==0 ){ if( !sqlite3NotPureFunc(context) ) return 1; - return setCurrentStmtTime(context, p); + return setCurrentStmtTime(context, p, 0); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 638260c5dc..73378dbf61 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5341,8 +5341,7 @@ FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); && !defined(SQLITE_OMIT_VIRTUALTABLE) void sqlite3VtabUsesAllSchemas(sqlite3_index_info*); #endif -sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); -sqlite3_int64 sqlite3TxnCurrentTime(sqlite3_context*); +sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*, int); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); void sqlite3ParseObjectInit(Parse*,sqlite3*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 432c1fa225..722d1215f1 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -970,41 +970,27 @@ int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){ ** statement, the exact same time is returned for each invocation regardless ** of the amount of time that elapses between invocations. In other words, ** the time returned is always the time of the first call. +** +** Or, if bTxn, return the transaction time. The transaction time is the +** same for all calls within the same transaction. +** +** bTxn is 0 for SQL like datetime('now') and is 1 for datetime('txn'). */ -sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ +sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p, int bTxn){ int rc; #ifndef SQLITE_ENABLE_STAT4 - sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + sqlite3_int64 *piTime; + sqlite3 *db = p->pOut->db; assert( p->pVdbe!=0 ); + piTime = bTxn ? &db->txnTime : &p->pVdbe->iCurrentTime; #else sqlite3_int64 iTime = 0; - sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; + sqlite3_int64 *piTime; + sqlite3 *db = p->pOut->db; + piTime = bTxn ? &db->txnTime : p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; #endif if( *piTime==0 ){ - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); - if( rc ) *piTime = 0; - } - return *piTime; -} - -/* -** Return the current time for a transaction. If the current time -** is requested more than once within the same transaction -** the same time is returned for each invocation regardless -** of the amount of time that elapses between invocations. In other words, -** the time returned is always the time of the first call. -*/ -sqlite3_int64 sqlite3TxnCurrentTime(sqlite3_context *p){ - int rc; -#ifndef SQLITE_ENABLE_STAT4 - sqlite3_int64 *piTime = &p->pVdbe->db->txnTime; - assert( p->pVdbe!=0 ); -#else - sqlite3_int64 iTime = 0; - sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->db->txnTime : &iTime; -#endif - if( *piTime==0 ){ - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + rc = sqlite3OsCurrentTimeInt64(db->pVfs, piTime); if( rc ) *piTime = 0; } return *piTime; diff --git a/test/date.test b/test/date.test index 62233ad8f6..8ade3e43c8 100644 --- a/test/date.test +++ b/test/date.test @@ -309,9 +309,9 @@ sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0 # datetest 7.1 {datetime(null)} NULL datetest 7.2 {datetime('now',null)} NULL -datetest 7.3 {datetime('now','localtime',null)} NULL +datetest 7.3 {datetime('txn','localtime',null)} NULL datetest 7.4 {time(null)} NULL -datetest 7.5 {time('now',null)} NULL +datetest 7.5 {time('txn',null)} NULL datetest 7.6 {time('now','localtime',null)} NULL datetest 7.7 {date(null)} NULL datetest 7.8 {date('now',null)} NULL @@ -322,28 +322,28 @@ datetest 7.12 {julianday('now','localtime',null)} NULL datetest 7.13 {strftime(null,'now')} NULL datetest 7.14 {strftime('%s',null)} NULL datetest 7.15 {strftime('%s','now',null)} NULL -datetest 7.16 {strftime('%s','now','localtime',null)} NULL +datetest 7.16 {strftime('%s','txn','localtime',null)} NULL # Test modifiers when the date begins as a julian day number - to # make sure the HH:MM:SS is preserved. Ticket #551. # set sqlite_current_time [db eval {SELECT strftime('%s','2003-10-22 12:34:00')}] datetest 8.1 {datetime('now','weekday 0')} {2003-10-26 12:34:00} -datetest 8.2 {datetime('now','weekday 1')} {2003-10-27 12:34:00} +datetest 8.2 {datetime('txn','weekday 1')} {2003-10-27 12:34:00} datetest 8.3 {datetime('now','weekday 2')} {2003-10-28 12:34:00} -datetest 8.4 {datetime('now','weekday 3')} {2003-10-22 12:34:00} +datetest 8.4 {datetime('txn','weekday 3')} {2003-10-22 12:34:00} datetest 8.5 {datetime('now','start of month')} {2003-10-01 00:00:00} -datetest 8.6 {datetime('now','start of year')} {2003-01-01 00:00:00} +datetest 8.6 {datetime('txn','start of year')} {2003-01-01 00:00:00} datetest 8.7 {datetime('now','start of day')} {2003-10-22 00:00:00} -datetest 8.8 {datetime('now','1 day')} {2003-10-23 12:34:00} +datetest 8.8 {datetime('txn','1 day')} {2003-10-23 12:34:00} datetest 8.9 {datetime('now','+1 day')} {2003-10-23 12:34:00} -datetest 8.10 {datetime('now','+1.25 day')} {2003-10-23 18:34:00} +datetest 8.10 {datetime('txn','+1.25 day')} {2003-10-23 18:34:00} datetest 8.11 {datetime('now','-1.0 day')} {2003-10-21 12:34:00} -datetest 8.12 {datetime('now','1 month')} {2003-11-22 12:34:00} +datetest 8.12 {datetime('txn','1 month')} {2003-11-22 12:34:00} datetest 8.13 {datetime('now','11 month')} {2004-09-22 12:34:00} -datetest 8.14 {datetime('now','-13 month')} {2002-09-22 12:34:00} +datetest 8.14 {datetime('txn','-13 month')} {2002-09-22 12:34:00} datetest 8.15 {datetime('now','1.5 months')} {2003-12-07 12:34:00} -datetest 8.16 {datetime('now','-5 years')} {1998-10-22 12:34:00} +datetest 8.16 {datetime('txn','-5 years')} {1998-10-22 12:34:00} datetest 8.17 {datetime('now','+10.5 minutes')} {2003-10-22 12:44:30} datetest 8.18 {datetime('now','-1.25 hours')} {2003-10-22 11:19:00} datetest 8.19 {datetime('now','11.25 seconds')} {2003-10-22 12:34:11} @@ -486,11 +486,55 @@ do_test date-15.1 { } } {0.0} do_test date-15.2 { + db func sleeper sleeper + db eval { + SELECT c - a FROM (SELECT julianday('txn') AS a, + sleeper(), julianday('txn') AS c); + } +} {0.0} +do_test date-15.3 { db eval { SELECT a==b FROM (SELECT current_timestamp AS a, sleeper(), current_timestamp AS b); } } {1} +do_test date-15.4 { + db eval { + SELECT a==b FROM (SELECT julianday('txn') AS a, + sleeper(), julianday('txn') AS b); + } +} {0} + +do_execsql_test date-15.5 { + CREATE TEMP TABLE t15(a,b); + BEGIN; + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + COMMIT; + SELECT count(a), count(DISTINCT a) FROM t15; +} {3 1} +do_execsql_test date-15.6 { + DELETE FROM t15; + BEGIN; + INSERT INTO t15(a,b) VALUES(julianday('now'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('now'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('now'),sleeper()); + COMMIT; + SELECT count(a), count(DISTINCT a) FROM t15; +} {3 3} +do_execsql_test date-15.7 { + DELETE FROM t15; + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + BEGIN; + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + INSERT INTO t15(a,b) VALUES(julianday('txn'),sleeper()); + COMMIT; + SELECT count(a), count(DISTINCT a) FROM t15; +} {4 3} + + # Tests of extreme values in date/time functions. Run with UBSan or the # equivalent to verify no signed interger overflow warnings. From c1dab9ded2c16c66e6781984bac804e3218aa5c9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 Feb 2023 11:34:05 +0000 Subject: [PATCH 3/5] Change the behavior of date-time functions without any arguments (and thus the CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP variables) so that they work like 'txn' instead of like 'now'. This is an incompatibility with legacy, but brings SQLite into conformance with all other SQL systems. FossilOrigin-Name: 1ac78be54502779236645eac35b962797f2fb98307d059d2aa19658c4fa74cb7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1be3d9ae98..e5694c8f1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\scode\sand\sadd\stest\scases. -D 2023-02-07T23:55:59.881 +C Change\sthe\sbehavior\sof\sdate-time\sfunctions\swithout\sany\sarguments\s(and\sthus\nthe\sCURRENT_TIME,\sCURRENT_DATE,\sand\sCURRENT_TIMESTAMP\svariables)\sso\sthat\sthey\nwork\slike\s'txn'\sinstead\sof\slike\s'now'.\s\sThis\sis\san\sincompatibility\swith\slegacy,\nbut\sbrings\sSQLite\sinto\sconformance\swith\sall\sother\sSQL\ssystems. +D 2023-02-08T11:34:05.173 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -567,7 +567,7 @@ F src/build.c c55ab6d1b089ceef57160e840f05f692955ac90944c3d04fcf01d97fd7bfd08d F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 0c5db79ea1d5951ed917fa43046e9cc146dfbef5ff46106abe76b69e2523a9f5 +F src/date.c 7bbe94be3ceb349faaf922ed6fb2429c1745bf0c4440c77bfc9ce5b93fcc9fde F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5e4f45af96247e29910403a63ac148cb313b005f9c014b37a9a49d98f5fef9a6 -R c20bc84a84eb9b7dcb5243c1d98778fa +P d3bed4caff561e71c396cc869c5b4d9bf216ba203485e738c12ec62741f1aba5 +R 306a6107a9a25e9636c592ddc5563a3a U drh -Z 4b08eb982cff98771c7da608dde8a084 +Z 577c1f61a5429561225ed1087c13c668 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b7c2e2f8f5..e3acf22720 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3bed4caff561e71c396cc869c5b4d9bf216ba203485e738c12ec62741f1aba5 \ No newline at end of file +1ac78be54502779236645eac35b962797f2fb98307d059d2aa19658c4fa74cb7 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 6c48d45e33..43334f15c1 100644 --- a/src/date.c +++ b/src/date.c @@ -952,7 +952,7 @@ static int isDate( memset(p, 0, sizeof(*p)); if( argc==0 ){ if( !sqlite3NotPureFunc(context) ) return 1; - return setCurrentStmtTime(context, p, 0); + return setCurrentStmtTime(context, p, 1); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ @@ -1318,7 +1318,7 @@ static void currentTimeFunc( UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); - iT = sqlite3StmtCurrentTime(context); + iT = sqlite3StmtCurrentTime(context, 1); if( iT<=0 ) return; t = iT/1000 - 10000*(sqlite3_int64)21086676; #if HAVE_GMTIME_R From ed092fc3684dbc2b2d8642cd05241391e279fe8e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 Feb 2023 12:01:48 +0000 Subject: [PATCH 4/5] Revert the behavior of date/time functions with no arguments so that they once again work like 'now', even while CURRENT_TIMESTAMP and similar work like 'txn'. FossilOrigin-Name: 06180caff0f5d8aba83b9f7be682ccdd6cb2ffc228b557ee6c1fd00fe5c23e92 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e5694c8f1a..b98697019e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sbehavior\sof\sdate-time\sfunctions\swithout\sany\sarguments\s(and\sthus\nthe\sCURRENT_TIME,\sCURRENT_DATE,\sand\sCURRENT_TIMESTAMP\svariables)\sso\sthat\sthey\nwork\slike\s'txn'\sinstead\sof\slike\s'now'.\s\sThis\sis\san\sincompatibility\swith\slegacy,\nbut\sbrings\sSQLite\sinto\sconformance\swith\sall\sother\sSQL\ssystems. -D 2023-02-08T11:34:05.173 +C Revert\sthe\sbehavior\sof\sdate/time\sfunctions\swith\sno\sarguments\sso\sthat\sthey\nonce\sagain\swork\slike\s'now',\seven\swhile\sCURRENT_TIMESTAMP\sand\ssimilar\swork\nlike\s'txn'. +D 2023-02-08T12:01:48.294 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -567,7 +567,7 @@ F src/build.c c55ab6d1b089ceef57160e840f05f692955ac90944c3d04fcf01d97fd7bfd08d F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c 7bbe94be3ceb349faaf922ed6fb2429c1745bf0c4440c77bfc9ce5b93fcc9fde +F src/date.c 37ca5e3cb34d666fae892156c9317d8bf756ae8a281504040dd3a02813ce5e9e F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d3bed4caff561e71c396cc869c5b4d9bf216ba203485e738c12ec62741f1aba5 -R 306a6107a9a25e9636c592ddc5563a3a +P 1ac78be54502779236645eac35b962797f2fb98307d059d2aa19658c4fa74cb7 +R 21bc10e166e48f106bd855a3f05d7452 U drh -Z 577c1f61a5429561225ed1087c13c668 +Z 81861e88fff679ab1e007b3943020398 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e3acf22720..0086c81715 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ac78be54502779236645eac35b962797f2fb98307d059d2aa19658c4fa74cb7 \ No newline at end of file +06180caff0f5d8aba83b9f7be682ccdd6cb2ffc228b557ee6c1fd00fe5c23e92 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 43334f15c1..8546b5dc89 100644 --- a/src/date.c +++ b/src/date.c @@ -937,8 +937,11 @@ static int parseModifier( ** the resulting time into the DateTime structure p. Return 0 ** on success and 1 if there are any errors. ** -** If there are zero parameters (if even argv[0] is undefined) -** then assume a default value of "now" for argv[0]. +** If there are zero parameters (if argc<=0) then assume a default +** value of "now" for argv[0] if argc==0 and "txn" if argc<0. SQL +** functions will always have argc>=0, but the special implementations +** of CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP set argc to -1 +** in order to force the use of 'txn' semantics. */ static int isDate( sqlite3_context *context, @@ -950,9 +953,9 @@ static int isDate( const unsigned char *z; int eType; memset(p, 0, sizeof(*p)); - if( argc==0 ){ + if( argc<=0 ){ if( !sqlite3NotPureFunc(context) ) return 1; - return setCurrentStmtTime(context, p, 1); + return setCurrentStmtTime(context, p, argc<0); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ @@ -1259,7 +1262,7 @@ static void ctimeFunc( sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); - timeFunc(context, 0, 0); + timeFunc(context, -1, 0); } /* @@ -1273,7 +1276,7 @@ static void cdateFunc( sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); - dateFunc(context, 0, 0); + dateFunc(context, -1, 0); } /* @@ -1287,7 +1290,7 @@ static void ctimestampFunc( sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); - datetimeFunc(context, 0, 0); + datetimeFunc(context, -1, 0); } #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ From 159cbfe1cbb9a725cb206479181870adfcb8b6fa Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 Feb 2023 12:31:47 +0000 Subject: [PATCH 5/5] Test cases to show that CURRENT_TIMESTAMP and similar hold the same value across a transaction. FossilOrigin-Name: 7b2fa20e31b8a0314b9ccb97bb556898d552505dbc5943f248df3f86c0f4e008 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/date.test | 25 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b98697019e..1e6875435e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revert\sthe\sbehavior\sof\sdate/time\sfunctions\swith\sno\sarguments\sso\sthat\sthey\nonce\sagain\swork\slike\s'now',\seven\swhile\sCURRENT_TIMESTAMP\sand\ssimilar\swork\nlike\s'txn'. -D 2023-02-08T12:01:48.294 +C Test\scases\sto\sshow\sthat\sCURRENT_TIMESTAMP\sand\ssimilar\shold\sthe\ssame\svalue\nacross\sa\stransaction. +D 2023-02-08T12:31:47.043 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -910,7 +910,7 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47 F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614c7fe201 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 -F test/date.test 0890bbd03f722169ae34f6d6f7822061d5fda8742355438562638ebed07e227c +F test/date.test 8e9ae588d832c54fa2512b0f9789bea48442ada0736dabee54b377dc1b8d4a87 F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 @@ -2045,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1ac78be54502779236645eac35b962797f2fb98307d059d2aa19658c4fa74cb7 -R 21bc10e166e48f106bd855a3f05d7452 +P 06180caff0f5d8aba83b9f7be682ccdd6cb2ffc228b557ee6c1fd00fe5c23e92 +R 191c2a25e4d73ba45ecc912c47f9a8ca U drh -Z 81861e88fff679ab1e007b3943020398 +Z bc216ff029b87470207499db9cc62288 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0086c81715..604bf7c5e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06180caff0f5d8aba83b9f7be682ccdd6cb2ffc228b557ee6c1fd00fe5c23e92 \ No newline at end of file +7b2fa20e31b8a0314b9ccb97bb556898d552505dbc5943f248df3f86c0f4e008 \ No newline at end of file diff --git a/test/date.test b/test/date.test index 8ade3e43c8..479635753a 100644 --- a/test/date.test +++ b/test/date.test @@ -501,7 +501,7 @@ do_test date-15.3 { do_test date-15.4 { db eval { SELECT a==b FROM (SELECT julianday('txn') AS a, - sleeper(), julianday('txn') AS b); + sleeper(), julianday('now') AS b); } } {0} @@ -534,7 +534,28 @@ do_execsql_test date-15.7 { SELECT count(a), count(DISTINCT a) FROM t15; } {4 3} - +do_test date-15.10 { + unset -nocomplain x + db eval {BEGIN;} + db eval { + SELECT + current_time AS ct1, + current_date AS cd1, + current_timestamp AS cs1, + time() AS ct2, + datetime() AS cs2; + } x {continue} + after 1000 + db eval { + SELECT + current_time=$x(ct1), + current_date=$x(cd1), + current_timestamp=$x(cs1), + time()=$x(ct2), + datetime()=$x(cs2); + } +} {1 1 1 0 0} +db eval {COMMIT} # Tests of extreme values in date/time functions. Run with UBSan or the # equivalent to verify no signed interger overflow warnings.