!1974 提升事务中now()重复计算的性能
Merge pull request !1974 from junhangis/junhangis/performance/time_cache
This commit is contained in:
@ -348,15 +348,52 @@ void GetCurrentDateTime(struct pg_tm* tm)
|
||||
*
|
||||
* Get the transaction start time ("now()") broken down as a struct pg_tm,
|
||||
* including fractional seconds and timezone offset.
|
||||
*
|
||||
* Internally, we cache the result, since this could be called many times
|
||||
* in a transaction, within which now() doesn't change.
|
||||
*/
|
||||
void GetCurrentTimeUsec(struct pg_tm* tm, fsec_t* fsec, int* tzp)
|
||||
{
|
||||
int tz;
|
||||
TimestampTz cur_ts = GetCurrentTransactionStartTimestamp();
|
||||
|
||||
timestamp2tm(GetCurrentTransactionStartTimestamp(), &tz, tm, fsec, NULL, NULL);
|
||||
/* Note: don't pass NULL tzp to timestamp2tm; affects behavior */
|
||||
if (tzp != NULL)
|
||||
*tzp = tz;
|
||||
/*
|
||||
* The cache key must include both current time and current timezone.
|
||||
* By representing the timezone by just a pointer, we're assuming that
|
||||
* distinct timezone settings could never have the same pointer value.
|
||||
* This is true by virtue of the hashtable used inside pg_tzset();
|
||||
* however, it might need another look if we ever allow entries in that
|
||||
* hash to be recycled.
|
||||
*/
|
||||
if (cur_ts != u_sess->cache_ts || session_timezone != u_sess->cache_timezone) {
|
||||
/*
|
||||
* Make sure cache is marked invalid in case of error after partial
|
||||
* update within timestamp2tm.
|
||||
*/
|
||||
u_sess->cache_timezone = NULL;
|
||||
|
||||
/*
|
||||
* Perform the computation, storing results into cache. We do not
|
||||
* really expect any error here, since current time surely ought to be
|
||||
* within range, but check just for sanity's sake.
|
||||
*/
|
||||
if (timestamp2tm(cur_ts,
|
||||
&u_sess->cache_tz, &u_sess->cache_tm, &u_sess->cache_fsec,
|
||||
NULL, session_timezone) != 0) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
}
|
||||
|
||||
/* OK, so mark the cache valid. */
|
||||
u_sess->cache_ts = cur_ts;
|
||||
u_sess->cache_timezone = session_timezone;
|
||||
}
|
||||
|
||||
*tm = u_sess->cache_tm;
|
||||
*fsec = u_sess->cache_fsec;
|
||||
if (tzp != NULL) {
|
||||
*tzp = u_sess->cache_tz;
|
||||
}
|
||||
}
|
||||
|
||||
/* TrimTrailingZeros()
|
||||
|
||||
@ -2772,6 +2772,13 @@ typedef struct knl_session_context {
|
||||
struct knl_u_clientConnTime_context clientConnTime_cxt;
|
||||
|
||||
knl_u_hook_context hook_cxt;
|
||||
|
||||
/* The datetime cache in current transaction. */
|
||||
TimestampTz cache_ts = 0;
|
||||
pg_tz* cache_timezone = NULL;
|
||||
struct pg_tm cache_tm;
|
||||
fsec_t cache_fsec;
|
||||
int cache_tz;
|
||||
} knl_session_context;
|
||||
|
||||
enum stp_xact_err_type {
|
||||
|
||||
Reference in New Issue
Block a user