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
This commit is contained in:
+25
-4
@@ -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 ){
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user