From d685417fbb8692d5ddee8ce60fc80e6b228c81bf Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 4 Apr 2003 04:50:44 +0000
Subject: [PATCH] Avoid repeated computation of the constants date2j(1970, 1,
 1) and date2j(2000, 1, 1).  Should make for some marginal speed improvement
 in date/time operations.

---
 src/backend/utils/adt/date.c        | 22 ++++++------
 src/backend/utils/adt/datetime.c    | 34 +++++++++++-------
 src/backend/utils/adt/nabstime.c    | 54 +++++++++++++++++++----------
 src/backend/utils/adt/pgstatfuncs.c | 13 +------
 src/backend/utils/adt/timestamp.c   | 29 +++++++---------
 src/include/utils/datetime.h        |  8 +++--
 src/include/utils/nabstime.h        |  3 +-
 7 files changed, 91 insertions(+), 72 deletions(-)

diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index a31cce92073..5c098a7007a 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.79 2003/02/13 17:04:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.80 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,7 +91,7 @@ date_in(PG_FUNCTION_ARGS)
 			elog(ERROR, "Unrecognized date external representation '%s'", str);
 	}
 
-	date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
+	date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 
 	PG_RETURN_DATEADT(date);
 }
@@ -108,7 +108,7 @@ date_out(PG_FUNCTION_ARGS)
 			   *tm = &tt;
 	char		buf[MAXDATELEN + 1];
 
-	j2date((date + date2j(2000, 1, 1)),
+	j2date(date + POSTGRES_EPOCH_JDATE,
 		   &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
 
 	EncodeDateOnly(tm, DateStyle, buf);
@@ -256,9 +256,10 @@ date_pl_interval(PG_FUNCTION_ARGS)
 
 	if (span->month != 0)
 	{
-		j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
+		j2date(dateVal + POSTGRES_EPOCH_JDATE,
+			   &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
 		tm->tm_mon += span->month;
-		dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+		dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 	}
 	if (span->time != 0)
 		dateVal += (span->time / 86400e0);
@@ -279,9 +280,10 @@ date_mi_interval(PG_FUNCTION_ARGS)
 
 	if (span->month != 0)
 	{
-		j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
+		j2date(dateVal + POSTGRES_EPOCH_JDATE,
+			   &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
 		tm->tm_mon -= span->month;
-		dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+		dateVal = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 	}
 	if (span->time != 0)
 		dateVal -= (span->time / 86400e0);
@@ -346,7 +348,7 @@ date_timestamptz(PG_FUNCTION_ARGS)
 	struct tm	tt,
 			   *tm = &tt;
 
-	j2date((dateVal + date2j(2000, 1, 1)),
+	j2date(dateVal + POSTGRES_EPOCH_JDATE,
 		   &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
 
 	if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
@@ -399,7 +401,7 @@ timestamptz_date(PG_FUNCTION_ARGS)
 	if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
 		elog(ERROR, "Unable to convert timestamp to date");
 
-	result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+	result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 
 	PG_RETURN_DATEADT(result);
 }
@@ -431,7 +433,7 @@ abstime_date(PG_FUNCTION_ARGS)
 
 		default:
 			abstime2tm(abstime, &tz, tm, NULL);
-			result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+			result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 			break;
 	}
 
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 8978cb534f7..e099245e7c9 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.102 2003/02/22 05:57:44 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.103 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -648,6 +648,14 @@ j2date(int jd, int *year, int *month, int *day)
 	return;
 }	/* j2date() */
 
+
+/*
+ * j2day - convert Julian date to day-of-week (0..6 == Sun..Sat)
+ *
+ * Note: various places use the locution j2day(date - 1) to produce a
+ * result according to the convention 0..6 = Mon..Sun.  This is a bit of
+ * a crock, but will work as long as the computation here is just a modulo.
+ */
 int
 j2day(int date)
 {
@@ -1261,7 +1269,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
 								*dtype = DTK_DATE;
 								GetCurrentDateTime(tm);
 								j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - 1),
-								&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+									   &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
 								tm->tm_hour = 0;
 								tm->tm_min = 0;
 								tm->tm_sec = 0;
@@ -1281,7 +1289,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
 								*dtype = DTK_DATE;
 								GetCurrentDateTime(tm);
 								j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1),
-								&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+									   &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
 								tm->tm_hour = 0;
 								tm->tm_min = 0;
 								tm->tm_sec = 0;
@@ -1546,8 +1554,7 @@ DetermineLocalTimeZone(struct tm * tm)
 						delta2;
 			time_t		mytime;
 
-			day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) -
-				   date2j(1970, 1, 1));
+			day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
 			mysec = tm->tm_sec + (tm->tm_min + (day * 24 + tm->tm_hour) * 60) * 60;
 			mytime = (time_t) mysec;
 
@@ -1556,8 +1563,8 @@ DetermineLocalTimeZone(struct tm * tm)
 			 * and reassemble to get a representation of local time.
 			 */
 			tmp = localtime(&mytime);
-			day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
-				   date2j(1970, 1, 1));
+			day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
+				UNIX_EPOCH_JDATE;
 			locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
 
 			/*
@@ -1586,8 +1593,8 @@ DetermineLocalTimeZone(struct tm * tm)
 			mysec += delta1;
 			mytime = (time_t) mysec;
 			tmp = localtime(&mytime);
-			day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
-				   date2j(1970, 1, 1));
+			day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
+				UNIX_EPOCH_JDATE;
 			locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
 			delta2 = mysec - locsec;
 			if (delta2 != delta1)
@@ -1595,8 +1602,8 @@ DetermineLocalTimeZone(struct tm * tm)
 				mysec += (delta2 - delta1);
 				mytime = (time_t) mysec;
 				tmp = localtime(&mytime);
-				day = (date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
-					   date2j(1970, 1, 1));
+				day = date2j(tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday) -
+					UNIX_EPOCH_JDATE;
 				locsec = tmp->tm_sec + (tmp->tm_min + (day * 24 + tmp->tm_hour) * 60) * 60;
 				delta2 = mysec - locsec;
 			}
@@ -2360,7 +2367,7 @@ DecodeNumber(int flen, char *str, int fmask,
 	{
 		*tmask = (DTK_M(DOY) | DTK_M(MONTH) | DTK_M(DAY));
 		tm->tm_yday = val;
-		j2date((date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1),
+		j2date(date2j(tm->tm_year, 1, 1) + tm->tm_yday - 1,
 			   &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
 	}
 
@@ -3702,6 +3709,9 @@ CheckDateTokenTables(void)
 {
 	bool		ok = true;
 
+	Assert(UNIX_EPOCH_JDATE == date2j(1970, 1, 1));
+	Assert(POSTGRES_EPOCH_JDATE == date2j(2000, 1, 1));
+
 	ok &= CheckDateTokenTable("datetktbl", datetktbl, szdatetktbl);
 	ok &= CheckDateTokenTable("deltatktbl", deltatktbl, szdeltatktbl);
 	ok &= CheckDateTokenTable("australian_datetktbl",
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 8a75bdffbee..ac63b2966eb 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.105 2003/03/20 03:34:56 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.106 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,10 +85,7 @@ static int istinterval(char *i_string,
 /* 
  * GetCurrentAbsoluteTime()
  *
- * Get the current system time. Set timezone parameters if not specified
- * elsewhere.  Define HasCTZSet to allow clients to specify the default
- * timezone.
- *
+ * Get the current system time (relative to Unix epoch).
  */
 AbsoluteTime
 GetCurrentAbsoluteTime(void)
@@ -100,11 +97,11 @@ GetCurrentAbsoluteTime(void)
 }
 
 
-/* GetCurrentAbsoluteTimeUsec()
- * Get the current system time.
+/*
+ * GetCurrentAbsoluteTimeUsec()
  *
- * Returns the number of seconds since epoch (January 1 1970 GMT),
- * and returns fractional seconds (as # of microseconds) into *usec.
+ * Get the current system time (relative to Unix epoch), including fractional
+ * seconds expressed as microseconds.
  */
 AbsoluteTime
 GetCurrentAbsoluteTimeUsec(int *usec)
@@ -119,7 +116,31 @@ GetCurrentAbsoluteTimeUsec(int *usec)
 }
 
 
-/* GetCurrentDateTime()
+/*
+ * AbsoluteTimeUsecToTimestampTz()
+ *
+ * Convert system time including microseconds to TimestampTz representation.
+ */
+TimestampTz
+AbsoluteTimeUsecToTimestampTz(AbsoluteTime sec, int usec)
+{
+	TimestampTz result;
+
+#ifdef HAVE_INT64_TIMESTAMP
+	result = ((sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400))
+			  * INT64CONST(1000000)) + usec;
+#else
+	result = sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * 86400)
+		+ (usec / 1000000.0);
+#endif
+
+	return result;
+}
+
+
+/*
+ * GetCurrentDateTime()
+ *
  * Get the transaction start time ("now()") broken down as a struct tm.
  */
 void
@@ -131,13 +152,10 @@ GetCurrentDateTime(struct tm * tm)
 }
 
 /* 
- * GetCurrentAbsoluteTimeUsec()
- *
- * Get the current system time. Set timezone parameters if not specified
- * elsewhere.  Define HasCTZSet to allow clients to specify the default
- * timezone.
+ * GetCurrentTimeUsec()
  *
- * Returns the number of seconds since epoch (January 1 1970 GMT)
+ * Get the transaction start time ("now()") broken down as a struct tm,
+ * including fractional seconds and timezone offset.
  */
 void
 GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
@@ -152,7 +170,7 @@ GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp)
 #ifdef HAVE_INT64_TIMESTAMP
 	*fsec = usec;
 #else
-	*fsec = usec * 1.0e-6;
+	*fsec = usec / 1000000.0;
 #endif
 }
 
@@ -307,7 +325,7 @@ tm2abstime(struct tm * tm, int tz)
 		|| tm->tm_sec < 0 || tm->tm_sec > 59)
 		return INVALID_ABSTIME;
 
-	day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(1970, 1, 1));
+	day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
 
 	/* check for time out of range */
 	if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 787f0226cdc..083bb1374a4 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -328,18 +328,7 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
 	if (sec == 0 && usec == 0)
 		PG_RETURN_NULL();
 
-	/*
-	 * This method of converting "Unix time" (sec/usec since epoch) to a
-	 * PostgreSQL timestamp is an ugly hack -- if you fix it, be sure to
-	 * fix the similar hackery in timestamp.c
-	 */
-#ifdef HAVE_INT64_TIMESTAMP
-	result = (((sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400))
-			   * INT64CONST(1000000)) + usec);
-#else
-	result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) -
-										date2j(1970, 1, 1)) * 86400));
-#endif
+	result = AbsoluteTimeUsecToTimestampTz(sec, usec);
 
 	PG_RETURN_TIMESTAMPTZ(result);
 }
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index feaec85b69e..e2f2b2d35b4 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.81 2003/03/20 06:02:59 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.82 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -728,12 +728,7 @@ now(PG_FUNCTION_ARGS)
 
 	sec = GetCurrentTransactionStartTimeUsec(&usec);
 
-#ifdef HAVE_INT64_TIMESTAMP
-	result = (((sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400))
-			   * INT64CONST(1000000)) + usec);
-#else
-	result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400));
-#endif
+	result = AbsoluteTimeUsecToTimestampTz(sec, usec);
 
 	PG_RETURN_TIMESTAMPTZ(result);
 }
@@ -800,7 +795,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
 	struct tm  *tx;
 #endif
 
-	date0 = date2j(2000, 1, 1);
+	date0 = POSTGRES_EPOCH_JDATE;
 
 	/*
 	 * If HasCTZSet is true then we have a brute force time zone
@@ -871,9 +866,9 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
 		{
 #ifdef HAVE_INT64_TIMESTAMP
 			utime = ((dt / INT64CONST(1000000))
-				   + ((date0 - date2j(1970, 1, 1)) * INT64CONST(86400)));
+				   + ((date0 - UNIX_EPOCH_JDATE) * INT64CONST(86400)));
 #else
-			utime = (dt + ((date0 - date2j(1970, 1, 1)) * 86400));
+			utime = (dt + ((date0 - UNIX_EPOCH_JDATE) * 86400));
 #endif
 
 #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
@@ -960,7 +955,7 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
 	if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
 		return -1;
 
-	date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
+	date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 	time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
 #ifdef HAVE_INT64_TIMESTAMP
 	*result = ((date * INT64CONST(86400000000)) + time);
@@ -2675,7 +2670,7 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
 	day4 = date2j(*year, 1, 4);
 
 	/* day0 == offset to first day of week (Monday) */
-	day0 = (j2day(day4 - 1) % 7);
+	day0 = j2day(day4 - 1);
 
 	dayn = ((woy - 1) * 7) + (day4 - day0);
 
@@ -2701,7 +2696,7 @@ date2isoweek(int year, int mon, int mday)
 	day4 = date2j(year, 1, 4);
 
 	/* day0 == offset to first day of week (Monday) */
-	day0 = (j2day(day4 - 1) % 7);
+	day0 = j2day(day4 - 1);
 
 	/*
 	 * We need the first week containing a Thursday, otherwise this day
@@ -2709,10 +2704,10 @@ date2isoweek(int year, int mon, int mday)
 	 */
 	if (dayn < (day4 - day0))
 	{
-		day4 = date2j((year - 1), 1, 4);
+		day4 = date2j(year - 1, 1, 4);
 
 		/* day0 == offset to first day of week (Monday) */
-		day0 = (j2day(day4 - 1) % 7);
+		day0 = j2day(day4 - 1);
 	}
 
 	result = (((dayn - (day4 - day0)) / 7) + 1);
@@ -2723,10 +2718,10 @@ date2isoweek(int year, int mon, int mday)
 	 */
 	if (result >= 53)
 	{
-		day4 = date2j((year + 1), 1, 4);
+		day4 = date2j(year + 1, 1, 4);
 
 		/* day0 == offset to first day of week (Monday) */
-		day0 = (j2day(day4 - 1) % 7);
+		day0 = j2day(day4 - 1);
 
 		if (dayn >= (day4 - day0))
 			result = (((dayn - (day4 - day0)) / 7) + 1);
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 39905ebb15e..3a419615489 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: datetime.h,v 1.36 2003/02/20 05:24:55 tgl Exp $
+ * $Id: datetime.h,v 1.37 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -259,6 +259,10 @@ extern int	day_tab[2][13];
  || (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
   || (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
 
+/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
+#define UNIX_EPOCH_JDATE		2440588		/* == date2j(1970, 1, 1) */
+#define POSTGRES_EPOCH_JDATE	2451545		/* == date2j(2000, 1, 1) */
+
 
 extern void GetCurrentDateTime(struct tm * tm);
 extern void GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp);
@@ -289,7 +293,7 @@ extern int	EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str);
 
 extern int	DecodeSpecial(int field, char *lowtoken, int *val);
 extern int	DecodeUnits(int field, char *lowtoken, int *val);
-extern bool ClearDateCache(bool, bool, bool);
+extern bool ClearDateCache(bool newval, bool doit, bool interactive);
 
 extern int	j2day(int jd);
 
diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h
index d9391366430..0992e1abee1 100644
--- a/src/include/utils/nabstime.h
+++ b/src/include/utils/nabstime.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nabstime.h,v 1.37 2002/09/01 00:58:07 tgl Exp $
+ * $Id: nabstime.h,v 1.38 2003/04/04 04:50:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -157,6 +157,7 @@ extern Datum timeofday(PG_FUNCTION_ARGS);
 /* non-fmgr-callable support routines */
 extern AbsoluteTime GetCurrentAbsoluteTime(void);
 extern AbsoluteTime GetCurrentAbsoluteTimeUsec(int *usec);
+extern TimestampTz AbsoluteTimeUsecToTimestampTz(AbsoluteTime sec, int usec);
 extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char **tzn);
 
 #endif   /* NABSTIME_H */
-- 
GitLab