diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index eaaffa7..5ebec5a 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -299,20 +299,27 @@ EncodeSpecialDate(DateADT dt, char *str) DateADT GetSQLCurrentDate(void) { - TimestampTz ts; - struct pg_tm tt, - *tm = &tt; - fsec_t fsec; - int tz; + static DateADT cache_date; /* cache date for current TX timestamp */ + static TimestampTz cache_ts; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); - ts = GetCurrentTransactionStartTimestamp(); + if (cache_ts != cur_ts) + { + struct pg_tm tt, + *tm = &tt; + fsec_t fsec; + int tz; - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, + if (timestamp2tm(cur_ts, &tz, tm, &fsec, NULL, NULL) != 0) + ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); - return date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; + cache_date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; + cache_ts = cur_ts; + } + + return cache_date; } /* @@ -321,22 +328,24 @@ GetSQLCurrentDate(void) TimeTzADT * GetSQLCurrentTime(int32 typmod) { - TimeTzADT *result; - TimestampTz ts; - struct pg_tm tt, - *tm = &tt; - fsec_t fsec; - int tz; - - ts = GetCurrentTransactionStartTimestamp(); + static struct pg_tm cache_pg_tm; /* cache pg_tm for current TX timestamp */ + static fsec_t cache_fsec; /* cache fsec for current TX timestamp */ + static int cache_tz; /* cache tz for current TX timestamp */ + static TimestampTz cache_ts; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); + TimeTzADT *result; - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, + if (cache_ts != cur_ts) + { + if (timestamp2tm(cur_ts, &cache_tz, &cache_pg_tm, &cache_fsec, NULL, NULL) != 0) + ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); + cache_ts = cur_ts; + } result = (TimeTzADT *) palloc(sizeof(TimeTzADT)); - tm2timetz(tm, fsec, tz, result); + tm2timetz(&cache_pg_tm, cache_fsec, cache_tz, result); AdjustTimeForTypmod(&(result->time), typmod); return result; } @@ -347,21 +356,24 @@ GetSQLCurrentTime(int32 typmod) TimeADT GetSQLLocalTime(int32 typmod) { - TimeADT result; - TimestampTz ts; - struct pg_tm tt, - *tm = &tt; - fsec_t fsec; - int tz; + static struct pg_tm cache_pg_tm; /* cache pg_tm for current TX timestamp */ + static fsec_t cache_fsec; /* cache fsec for current TX timestamp */ + static TimestampTz cache_ts; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); + TimeADT result; - ts = GetCurrentTransactionStartTimestamp(); + if (cache_ts != cur_ts) + { + int tz; - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, + if (timestamp2tm(cur_ts, &tz, &cache_pg_tm, &cache_fsec, NULL, NULL) != 0) + ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); + cache_ts = cur_ts; + } - tm2time(tm, fsec, &result); + tm2time(&cache_pg_tm, cache_fsec, &result); AdjustTimeForTypmod(&result, typmod); return result; } diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index dec2fad..67d4268 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -344,12 +344,21 @@ j2day(int date) void GetCurrentDateTime(struct pg_tm *tm) { - int tz; - fsec_t fsec; + static struct pg_tm cache_pg_tm; /* Cache pg_tm for current TX timestamp */ + static TimestampTz cache_ts; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); + + if (cache_ts != cur_ts) + { + int tz; + fsec_t fsec; + + timestamp2tm(cur_ts, &tz, &cache_pg_tm, &fsec, NULL, NULL); + /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + cache_ts = cur_ts; + } - timestamp2tm(GetCurrentTransactionStartTimestamp(), &tz, tm, &fsec, - NULL, NULL); - /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + *tm = cache_pg_tm; } /* @@ -361,13 +370,23 @@ GetCurrentDateTime(struct pg_tm *tm) void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp) { - int tz; + static struct pg_tm cache_pg_tm; /* cache pg_tm for current TX timestamp */ + static fsec_t cache_fsec; /* cache fsec for current TX timestamp */ + static int cache_tz; /* cache tz for current TX timestamp */ + static TimestampTz cache_ts; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); + + if (cache_ts != cur_ts) + { + timestamp2tm(cur_ts, &cache_tz, &cache_pg_tm, &cache_fsec, NULL, NULL); + /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + cache_ts = cur_ts; + } - timestamp2tm(GetCurrentTransactionStartTimestamp(), &tz, tm, fsec, - NULL, NULL); - /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + *tm = cache_pg_tm; + *fsec = cache_fsec; if (tzp != NULL) - *tzp = tz; + *tzp = cache_tz; }