diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/date.c | 29 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 | ||||
-rw-r--r-- | src/vdbeapi.c | 23 | ||||
-rw-r--r-- | src/vdbeaux.c | 1 |
4 files changed, 51 insertions, 4 deletions
diff --git a/src/date.c b/src/date.c index a3e58bc4e..21077df93 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; @@ -346,6 +348,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 ** range of a julian day number, install it as such and set validJD. @@ -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 3da5f13d5..638260c5d 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 476b6a2ad..432c1fa22 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -988,6 +988,29 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ } /* +** 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 d04d8f1e1..82dc60715 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 ); |