From a7801b62f21bd051444bd1119cd3745ecc8e14ec Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 9 Sep 2011 13:23:41 -0400
Subject: [PATCH] Move Timestamp/Interval typedefs and basic macros into
 datatype/timestamp.h.

As per my recent proposal, this refactors things so that these typedefs and
macros are available in a header that can be included in frontend-ish code.
I also changed various headers that were undesirably including
utils/timestamp.h to include datatype/timestamp.h instead.  Unsurprisingly,
this showed that half the system was getting utils/timestamp.h by way of
xlog.h.

No actual code changes here, just header refactoring.
---
 contrib/btree_gist/btree_utils_num.c  |   1 +
 contrib/spi/moddatetime.c             |   1 +
 doc/src/sgml/xfunc.sgml               |   4 +-
 src/backend/access/transam/twophase.c |   1 +
 src/backend/access/transam/xact.c     |   1 +
 src/backend/access/transam/xlog.c     |   1 +
 src/backend/commands/analyze.c        |   1 +
 src/backend/commands/async.c          |   1 +
 src/backend/commands/prepare.c        |   1 +
 src/backend/commands/user.c           |   1 +
 src/backend/commands/vacuumlazy.c     |   1 +
 src/backend/commands/variable.c       |   1 +
 src/backend/libpq/crypt.c             |   1 +
 src/backend/parser/parse_node.c       |   1 +
 src/backend/postmaster/autovacuum.c   |   1 +
 src/backend/postmaster/pgstat.c       |   1 +
 src/backend/replication/walreceiver.c |   1 +
 src/backend/replication/walsender.c   |   1 +
 src/backend/storage/buffer/bufmgr.c   |   1 +
 src/backend/storage/ipc/standby.c     |   1 +
 src/backend/storage/lmgr/proc.c       |   1 +
 src/backend/tcop/postgres.c           |   1 +
 src/backend/utils/adt/date.c          |   1 +
 src/backend/utils/adt/genfile.c       |   1 +
 src/backend/utils/adt/misc.c          |   5 +-
 src/backend/utils/adt/nabstime.c      |   1 +
 src/backend/utils/adt/pgstatfuncs.c   |   5 +-
 src/backend/utils/adt/selfuncs.c      |   1 +
 src/backend/utils/mmgr/portalmem.c    |   1 +
 src/include/access/gist_private.h     |   1 +
 src/include/access/xlog.h             |   2 +-
 src/include/access/xlog_internal.h    |   2 +
 src/include/commands/sequence.h       |   3 +-
 src/include/datatype/timestamp.h      | 163 ++++++++++++++++++++++++++
 src/include/libpq/libpq-be.h          |   2 +-
 src/include/pgstat.h                  |   3 +-
 src/include/replication/walprotocol.h |   2 +-
 src/include/replication/walsender.h   |   1 +
 src/include/storage/proc.h            |   2 +-
 src/include/utils/datetime.h          |  29 +----
 src/include/utils/nabstime.h          |   3 +-
 src/include/utils/portal.h            |   2 +-
 src/include/utils/timestamp.h         | 108 +----------------
 43 files changed, 213 insertions(+), 150 deletions(-)
 create mode 100644 src/include/datatype/timestamp.h

diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c
index 2b1252b78e2..832dbc500b1 100644
--- a/contrib/btree_gist/btree_utils_num.c
+++ b/contrib/btree_gist/btree_utils_num.c
@@ -7,6 +7,7 @@
 #include "btree_utils_num.h"
 #include "utils/cash.h"
 #include "utils/date.h"
+#include "utils/timestamp.h"
 
 
 GISTENTRY *
diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
index d0bc4078f9e..2ec96540368 100644
--- a/contrib/spi/moddatetime.c
+++ b/contrib/spi/moddatetime.c
@@ -19,6 +19,7 @@ OH, me, I'm Terry Mackintosh <terry@terrym.com>
 #include "executor/spi.h"
 #include "commands/trigger.h"
 #include "utils/rel.h"
+#include "utils/timestamp.h"
 
 PG_MODULE_MAGIC;
 
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index a6d2a1355c6..34e2cc29150 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -1904,7 +1904,7 @@ memcpy(destination->data, buffer, 40);
         <row>
          <entry><type>interval</type></entry>
          <entry><type>Interval*</type></entry>
-         <entry><filename>utils/timestamp.h</filename></entry>
+         <entry><filename>datatype/timestamp.h</filename></entry>
         </row>
         <row>
          <entry><type>lseg</type></entry>
@@ -1969,7 +1969,7 @@ memcpy(destination->data, buffer, 40);
         <row>
          <entry><type>timestamp</type></entry>
          <entry><type>Timestamp*</type></entry>
-         <entry><filename>utils/timestamp.h</filename></entry>
+         <entry><filename>datatype/timestamp.h</filename></entry>
         </row>
         <row>
          <entry><type>tinterval</type></entry>
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 54176ee9df9..477982d5fa5 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -64,6 +64,7 @@
 #include "storage/smgr.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/timestamp.h"
 
 
 /*
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 7c0b463067e..de3f965b37a 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -49,6 +49,7 @@
 #include "utils/memutils.h"
 #include "utils/relmapper.h"
 #include "utils/snapmgr.h"
+#include "utils/timestamp.h"
 #include "pg_trace.h"
 
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 4abc5630e95..8f65ddcaa52 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -58,6 +58,7 @@
 #include "utils/guc.h"
 #include "utils/ps_status.h"
 #include "utils/relmapper.h"
+#include "utils/timestamp.h"
 #include "pg_trace.h"
 
 
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 6b0a4e70549..36cb40d4517 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -48,6 +48,7 @@
 #include "utils/pg_rusage.h"
 #include "utils/syscache.h"
 #include "utils/tuplesort.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 02f8f9cd635..4f20ca2ef73 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -132,6 +132,7 @@
 #include "utils/builtins.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
+#include "utils/timestamp.h"
 
 
 /*
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 6cf6da3f21a..d929e14e0ed 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -31,6 +31,7 @@
 #include "tcop/utility.h"
 #include "utils/builtins.h"
 #include "utils/snapmgr.h"
+#include "utils/timestamp.h"
 
 
 /*
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 10f44877473..fa312cb0719 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -33,6 +33,7 @@
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/syscache.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 /* Potentially set by contrib/pg_upgrade_support functions */
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index a2420a81313..cf8337b9e5d 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -53,6 +53,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/pg_rusage.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 8550869db3d..239acd07852 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -26,6 +26,7 @@
 #include "utils/builtins.h"
 #include "utils/syscache.h"
 #include "utils/snapmgr.h"
+#include "utils/timestamp.h"
 #include "mb/pg_wchar.h"
 
 /*
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c
index c9d7a34f50e..764bccda794 100644
--- a/src/backend/libpq/crypt.c
+++ b/src/backend/libpq/crypt.c
@@ -26,6 +26,7 @@
 #include "miscadmin.h"
 #include "utils/builtins.h"
 #include "utils/syscache.h"
+#include "utils/timestamp.h"
 
 
 int
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 494ef5fb4ba..7b5c040cb40 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -24,6 +24,7 @@
 #include "parser/parse_expr.h"
 #include "parser/parse_relation.h"
 #include "utils/builtins.h"
+#include "utils/int8.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
 #include "utils/varbit.h"
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index e425f9b17e7..4e211977b28 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -97,6 +97,7 @@
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index be32ca8dc54..eb9adc81f92 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -62,6 +62,7 @@
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/rel.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 6d7f215d405..1f12dcb62aa 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -50,6 +50,7 @@
 #include "utils/guc.h"
 #include "utils/ps_status.h"
 #include "utils/resowner.h"
+#include "utils/timestamp.h"
 
 /* Global variable to indicate if this process is a walreceiver process */
 bool		am_walreceiver;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 474567a2042..6e1d82acb11 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -62,6 +62,7 @@
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/resowner.h"
+#include "utils/timestamp.h"
 
 
 /* Array of WalSnds in shared memory */
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 4c7cfb0b404..8647eddcb42 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -47,6 +47,7 @@
 #include "storage/standby.h"
 #include "utils/rel.h"
 #include "utils/resowner.h"
+#include "utils/timestamp.h"
 
 
 /* Note: these two macros only work on shared buffers, not local ones! */
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 5673c27cbe0..72c6b97b225 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -28,6 +28,7 @@
 #include "storage/sinvaladt.h"
 #include "storage/standby.h"
 #include "utils/ps_status.h"
+#include "utils/timestamp.h"
 
 /* User-settable GUC parameters */
 int			vacuum_defer_cleanup_age;
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index f4091ecc0fb..22cb0b82837 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -47,6 +47,7 @@
 #include "storage/procarray.h"
 #include "storage/procsignal.h"
 #include "storage/spin.h"
+#include "utils/timestamp.h"
 
 
 /* GUC variables */
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index ed815d137c0..b708328926a 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -72,6 +72,7 @@
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/snapmgr.h"
+#include "utils/timestamp.h"
 #include "mb/pg_wchar.h"
 
 
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index e737e720f5b..b06faf0c720 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -27,6 +27,7 @@
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/date.h"
+#include "utils/datetime.h"
 #include "utils/nabstime.h"
 
 /*
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index dfe38f555f5..6b3f77fec14 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -28,6 +28,7 @@
 #include "storage/fd.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/timestamp.h"
 
 typedef struct
 {
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 5a77340bdb0..63ec6fd9d4e 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -20,8 +20,8 @@
 #include <math.h>
 
 #include "catalog/catalog.h"
-#include "catalog/pg_type.h"
 #include "catalog/pg_tablespace.h"
+#include "catalog/pg_type.h"
 #include "commands/dbcommands.h"
 #include "funcapi.h"
 #include "miscadmin.h"
@@ -30,8 +30,9 @@
 #include "storage/fd.h"
 #include "storage/pmsignal.h"
 #include "storage/procarray.h"
-#include "utils/builtins.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
+#include "utils/timestamp.h"
 
 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
 
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 6771e78af8e..02dc24d5135 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -25,6 +25,7 @@
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
+#include "utils/datetime.h"
 #include "utils/nabstime.h"
 
 #define MIN_DAYNUM (-24856)		/* December 13, 1901 */
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index d065542e047..7792b33da0d 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -14,13 +14,14 @@
  */
 #include "postgres.h"
 
+#include "catalog/pg_type.h"
 #include "funcapi.h"
+#include "libpq/ip.h"
 #include "miscadmin.h"
 #include "pgstat.h"
-#include "catalog/pg_type.h"
 #include "utils/builtins.h"
 #include "utils/inet.h"
-#include "libpq/ip.h"
+#include "utils/timestamp.h"
 
 /* bogus ... these externs should be in a header file */
 extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 5d999e6bfa2..3e846799563 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -124,6 +124,7 @@
 #include "utils/selfuncs.h"
 #include "utils/spccache.h"
 #include "utils/syscache.h"
+#include "utils/timestamp.h"
 #include "utils/tqual.h"
 
 
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 186548dcba5..609758ecd23 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -24,6 +24,7 @@
 #include "miscadmin.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
+#include "utils/timestamp.h"
 
 /*
  * Estimate of the maximum number of open portals a user would have,
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 6ce2c7568de..8b3cb01ae41 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -16,6 +16,7 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
+#include "fmgr.h"
 #include "storage/bufmgr.h"
 #include "storage/buffile.h"
 #include "utils/rbtree.h"
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 3771ccbec4c..e4a13a18ab3 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -13,10 +13,10 @@
 
 #include "access/rmgr.h"
 #include "access/xlogdefs.h"
+#include "datatype/timestamp.h"
 #include "lib/stringinfo.h"
 #include "storage/buf.h"
 #include "utils/pg_crc.h"
-#include "utils/timestamp.h"
 
 /*
  * The overall layout of an XLOG record is:
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 68c06910159..4eaa243948b 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -17,6 +17,8 @@
 #define XLOG_INTERNAL_H
 
 #include "access/xlog.h"
+#include "fmgr.h"
+#include "pgtime.h"
 #include "storage/block.h"
 #include "storage/relfilenode.h"
 
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 85452b0cfdd..4177bc2a251 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -13,9 +13,10 @@
 #ifndef SEQUENCE_H
 #define SEQUENCE_H
 
+#include "access/xlog.h"
+#include "fmgr.h"
 #include "nodes/parsenodes.h"
 #include "storage/relfilenode.h"
-#include "access/xlog.h"
 
 
 typedef struct FormData_pg_sequence
diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h
new file mode 100644
index 00000000000..fa68dd9e190
--- /dev/null
+++ b/src/include/datatype/timestamp.h
@@ -0,0 +1,163 @@
+/*-------------------------------------------------------------------------
+ *
+ * timestamp.h
+ *	  Timestamp and Interval typedefs and related macros.
+ *
+ * Note: this file must be includable in both frontend and backend contexts.
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/datatype/timestamp.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef DATATYPE_TIMESTAMP_H
+#define DATATYPE_TIMESTAMP_H
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+
+/*
+ * Timestamp represents absolute time.
+ *
+ * Interval represents delta time. Keep track of months (and years), days,
+ * and hours/minutes/seconds separately since the elapsed time spanned is
+ * unknown until instantiated relative to an absolute time.
+ *
+ * Note that Postgres uses "time interval" to mean a bounded interval,
+ * consisting of a beginning and ending time, not a time span - thomas 97/03/20
+ *
+ * We have two implementations, one that uses int64 values with units of
+ * microseconds, and one that uses double values with units of seconds.
+ *
+ * TimeOffset and fsec_t are convenience typedefs for temporary variables
+ * that are of different types in the two cases.  Do not use fsec_t in values
+ * stored on-disk, since it is not the same size in both implementations.
+ * Also, fsec_t is only meant for *fractional* seconds; beware of overflow
+ * if the value you need to store could be many seconds.
+ */
+
+#ifdef HAVE_INT64_TIMESTAMP
+
+typedef int64 Timestamp;
+typedef int64 TimestampTz;
+typedef int64 TimeOffset;
+typedef int32 fsec_t;			/* fractional seconds (in microseconds) */
+#else
+
+typedef double Timestamp;
+typedef double TimestampTz;
+typedef double TimeOffset;
+typedef double fsec_t;			/* fractional seconds (in seconds) */
+#endif
+
+typedef struct
+{
+	TimeOffset	time;			/* all time units other than days, months and
+								 * years */
+	int32		day;			/* days, after time for alignment */
+	int32		month;			/* months and years, after time for alignment */
+} Interval;
+
+
+#define MAX_TIMESTAMP_PRECISION 6
+#define MAX_INTERVAL_PRECISION 6
+
+/*
+ *	Round off to MAX_TIMESTAMP_PRECISION decimal places.
+ *	Note: this is also used for rounding off intervals.
+ */
+#define TS_PREC_INV 1000000.0
+#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
+
+
+/*
+ * Assorted constants for datetime-related calculations
+ */
+
+#define DAYS_PER_YEAR	365.25	/* assumes leap year every four years */
+#define MONTHS_PER_YEAR 12
+/*
+ *	DAYS_PER_MONTH is very imprecise.  The more accurate value is
+ *	365.2425/12 = 30.436875, or '30 days 10:29:06'.  Right now we only
+ *	return an integral number of days, but someday perhaps we should
+ *	also return a 'time' value to be used as well.	ISO 8601 suggests
+ *	30 days.
+ */
+#define DAYS_PER_MONTH	30		/* assumes exactly 30 days per month */
+#define HOURS_PER_DAY	24		/* assume no daylight savings time changes */
+
+/*
+ *	This doesn't adjust for uneven daylight savings time intervals or leap
+ *	seconds, and it crudely estimates leap years.  A more accurate value
+ *	for days per years is 365.2422.
+ */
+#define SECS_PER_YEAR	(36525 * 864)	/* avoid floating-point computation */
+#define SECS_PER_DAY	86400
+#define SECS_PER_HOUR	3600
+#define SECS_PER_MINUTE 60
+#define MINS_PER_HOUR	60
+
+#define USECS_PER_DAY	INT64CONST(86400000000)
+#define USECS_PER_HOUR	INT64CONST(3600000000)
+#define USECS_PER_MINUTE INT64CONST(60000000)
+#define USECS_PER_SEC	INT64CONST(1000000)
+
+/*
+ * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity
+ */
+#ifdef HAVE_INT64_TIMESTAMP
+#define DT_NOBEGIN		(-INT64CONST(0x7fffffffffffffff) - 1)
+#define DT_NOEND		(INT64CONST(0x7fffffffffffffff))
+#else	/* !HAVE_INT64_TIMESTAMP */
+#ifdef HUGE_VAL
+#define DT_NOBEGIN		(-HUGE_VAL)
+#define DT_NOEND		(HUGE_VAL)
+#else
+#define DT_NOBEGIN		(-DBL_MAX)
+#define DT_NOEND		(DBL_MAX)
+#endif
+#endif   /* HAVE_INT64_TIMESTAMP */
+
+#define TIMESTAMP_NOBEGIN(j)	\
+	do {(j) = DT_NOBEGIN;} while (0)
+
+#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
+
+#define TIMESTAMP_NOEND(j)		\
+	do {(j) = DT_NOEND;} while (0)
+
+#define TIMESTAMP_IS_NOEND(j)	((j) == DT_NOEND)
+
+#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
+
+
+/*
+ * Julian date support.
+ *
+ * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
+ * about the maximum, since it's far enough out to not be especially
+ * interesting.
+ */
+
+#define JULIAN_MINYEAR (-4713)
+#define JULIAN_MINMONTH (11)
+#define JULIAN_MINDAY (24)
+#define JULIAN_MAXYEAR (5874898)
+
+#define IS_VALID_JULIAN(y,m,d) \
+	(((y) > JULIAN_MINYEAR \
+	  || ((y) == JULIAN_MINYEAR && \
+		  ((m) > JULIAN_MINMONTH \
+		   || ((m) == JULIAN_MINMONTH && (d) >= JULIAN_MINDAY)))) \
+	 && (y) < JULIAN_MAXYEAR)
+
+#define JULIAN_MAX (2147483494)			/* == date2j(JULIAN_MAXYEAR, 1, 1) */
+
+/* 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) */
+
+#endif   /* DATATYPE_TIMESTAMP_H */
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 77e190fd1a0..d9a565bd09e 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -65,9 +65,9 @@ typedef struct
 #endif
 #endif   /* ENABLE_SSPI */
 
+#include "datatype/timestamp.h"
 #include "libpq/hba.h"
 #include "libpq/pqcomm.h"
-#include "utils/timestamp.h"
 
 
 typedef enum CAC_state
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 5446fa04409..20c4d4354e9 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -11,11 +11,12 @@
 #ifndef PGSTAT_H
 #define PGSTAT_H
 
+#include "datatype/timestamp.h"
+#include "fmgr.h"
 #include "libpq/pqcomm.h"
 #include "portability/instr_time.h"
 #include "utils/hsearch.h"
 #include "utils/relcache.h"
-#include "utils/timestamp.h"
 
 
 /* Values for track_functions GUC variable --- order is significant! */
diff --git a/src/include/replication/walprotocol.h b/src/include/replication/walprotocol.h
index 94146679fa6..656c8fc17fd 100644
--- a/src/include/replication/walprotocol.h
+++ b/src/include/replication/walprotocol.h
@@ -13,7 +13,7 @@
 #define _WALPROTOCOL_H
 
 #include "access/xlogdefs.h"
-#include "utils/timestamp.h"
+#include "datatype/timestamp.h"
 
 
 /*
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index fe4dac81aaf..a386ea9b1b2 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -13,6 +13,7 @@
 #define _WALSENDER_H
 
 #include "access/xlog.h"
+#include "fmgr.h"
 #include "nodes/nodes.h"
 #include "storage/latch.h"
 #include "storage/shmem.h"
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 07e36a14282..46ec625e087 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -15,10 +15,10 @@
 #define _PROC_H_
 
 #include "access/xlog.h"
+#include "datatype/timestamp.h"
 #include "storage/latch.h"
 #include "storage/lock.h"
 #include "storage/pg_sema.h"
-#include "utils/timestamp.h"
 
 /*
  * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 2880304fdbc..cd9eddacb03 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * datetime.h
- *	  Definitions for the date/time and other date/time support code.
+ *	  Definitions for date/time support code.
  *	  The support code is shared with other date data types,
  *	   including abstime, reltime, date, and time.
  *
@@ -16,9 +16,6 @@
 #ifndef DATETIME_H
 #define DATETIME_H
 
-#include <limits.h>
-#include <math.h>
-
 #include "utils/timestamp.h"
 
 /* this struct is declared in utils/tzparser.h: */
@@ -254,30 +251,6 @@ extern const int day_tab[2][13];
 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
 
-/* Julian date support for date2j() and j2date()
- *
- * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
- * about the maximum, since it's far enough out to not be especially
- * interesting.
- */
-
-#define JULIAN_MINYEAR (-4713)
-#define JULIAN_MINMONTH (11)
-#define JULIAN_MINDAY (24)
-#define JULIAN_MAXYEAR (5874898)
-
-#define IS_VALID_JULIAN(y,m,d) ((((y) > JULIAN_MINYEAR) \
-  || (((y) == JULIAN_MINYEAR) && (((m) > JULIAN_MINMONTH) \
-  || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
- && ((y) < JULIAN_MAXYEAR))
-
-#define JULIAN_MAX (2147483494) /* == date2j(JULIAN_MAXYEAR, 1 ,1) */
-
-/* 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) */
-
-
 /*
  * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
  * return zero or a positive value on success.	On failure, they return
diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h
index d750d2be2cb..4c1d56a3cd7 100644
--- a/src/include/utils/nabstime.h
+++ b/src/include/utils/nabstime.h
@@ -17,8 +17,7 @@
 #include <limits.h>
 
 #include "fmgr.h"
-#include "utils/timestamp.h"
-#include "utils/datetime.h"
+#include "pgtime.h"
 
 
 /* ----------------------------------------------------------------
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 6af1cd5b106..a13a70fe025 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -46,9 +46,9 @@
 #ifndef PORTAL_H
 #define PORTAL_H
 
+#include "datatype/timestamp.h"
 #include "executor/execdesc.h"
 #include "utils/resowner.h"
-#include "utils/timestamp.h"
 
 /*
  * We have several execution strategies for Portals, depending on what
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index ca7a6e73c25..dc91f3eaaa1 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -13,91 +13,11 @@
 #ifndef TIMESTAMP_H
 #define TIMESTAMP_H
 
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-
+#include "datatype/timestamp.h"
 #include "fmgr.h"
 #include "pgtime.h"
-#ifdef HAVE_INT64_TIMESTAMP
-#include "utils/int8.h"
-#endif
-
-/*
- * Timestamp represents absolute time.
- *
- * Interval represents delta time. Keep track of months (and years), days,
- * and hours/minutes/seconds separately since the elapsed time spanned is
- * unknown until instantiated relative to an absolute time.
- *
- * Note that Postgres uses "time interval" to mean a bounded interval,
- * consisting of a beginning and ending time, not a time span - thomas 97/03/20
- *
- * We have two implementations, one that uses int64 values with units of
- * microseconds, and one that uses double values with units of seconds.
- *
- * TimeOffset and fsec_t are convenience typedefs for temporary variables
- * that are of different types in the two cases.  Do not use fsec_t in values
- * stored on-disk, since it is not the same size in both implementations.
- * Also, fsec_t is only meant for *fractional* seconds; beware of overflow
- * if the value you need to store could be many seconds.
- */
-
-#ifdef HAVE_INT64_TIMESTAMP
-
-typedef int64 Timestamp;
-typedef int64 TimestampTz;
-typedef int64 TimeOffset;
-typedef int32 fsec_t;			/* fractional seconds (in microseconds) */
-#else
-
-typedef double Timestamp;
-typedef double TimestampTz;
-typedef double TimeOffset;
-typedef double fsec_t;			/* fractional seconds (in seconds) */
-#endif
-
-typedef struct
-{
-	TimeOffset	time;			/* all time units other than days, months and
-								 * years */
-	int32		day;			/* days, after time for alignment */
-	int32		month;			/* months and years, after time for alignment */
-} Interval;
 
 
-#define MAX_TIMESTAMP_PRECISION 6
-#define MAX_INTERVAL_PRECISION 6
-
-/* in both timestamp.h and ecpg/dt.h */
-#define DAYS_PER_YEAR	365.25	/* assumes leap year every four years */
-#define MONTHS_PER_YEAR 12
-/*
- *	DAYS_PER_MONTH is very imprecise.  The more accurate value is
- *	365.2425/12 = 30.436875, or '30 days 10:29:06'.  Right now we only
- *	return an integral number of days, but someday perhaps we should
- *	also return a 'time' value to be used as well.	ISO 8601 suggests
- *	30 days.
- */
-#define DAYS_PER_MONTH	30		/* assumes exactly 30 days per month */
-#define HOURS_PER_DAY	24		/* assume no daylight savings time changes */
-
-/*
- *	This doesn't adjust for uneven daylight savings time intervals or leap
- *	seconds, and it crudely estimates leap years.  A more accurate value
- *	for days per years is 365.2422.
- */
-#define SECS_PER_YEAR	(36525 * 864)	/* avoid floating-point computation */
-#define SECS_PER_DAY	86400
-#define SECS_PER_HOUR	3600
-#define SECS_PER_MINUTE 60
-#define MINS_PER_HOUR	60
-
-#define USECS_PER_DAY	INT64CONST(86400000000)
-#define USECS_PER_HOUR	INT64CONST(3600000000)
-#define USECS_PER_MINUTE INT64CONST(60000000)
-#define USECS_PER_SEC	INT64CONST(1000000)
-
 /*
  * Macros for fmgr-callable functions.
  *
@@ -123,8 +43,6 @@ typedef struct
 #define PG_RETURN_TIMESTAMPTZ(x) return TimestampTzGetDatum(x)
 #define PG_RETURN_INTERVAL_P(x) return IntervalPGetDatum(x)
 
-#define DT_NOBEGIN		(-INT64CONST(0x7fffffffffffffff) - 1)
-#define DT_NOEND		(INT64CONST(0x7fffffffffffffff))
 #else							/* !HAVE_INT64_TIMESTAMP */
 
 #define DatumGetTimestamp(X)  ((Timestamp) DatumGetFloat8(X))
@@ -143,33 +61,9 @@ typedef struct
 #define PG_RETURN_TIMESTAMPTZ(x) return TimestampTzGetDatum(x)
 #define PG_RETURN_INTERVAL_P(x) return IntervalPGetDatum(x)
 
-#ifdef HUGE_VAL
-#define DT_NOBEGIN		(-HUGE_VAL)
-#define DT_NOEND		(HUGE_VAL)
-#else
-#define DT_NOBEGIN		(-DBL_MAX)
-#define DT_NOEND		(DBL_MAX)
-#endif
 #endif   /* HAVE_INT64_TIMESTAMP */
 
 
-#define TIMESTAMP_NOBEGIN(j)	\
-	do {(j) = DT_NOBEGIN;} while (0)
-#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
-
-#define TIMESTAMP_NOEND(j)		\
-	do {(j) = DT_NOEND;} while (0)
-#define TIMESTAMP_IS_NOEND(j)	((j) == DT_NOEND)
-
-#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
-
-/*
- *	Round off to MAX_TIMESTAMP_PRECISION decimal places.
- *	Note: this is also used for rounding off intervals.
- */
-#define TS_PREC_INV 1000000.0
-#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
-
 #define TIMESTAMP_MASK(b) (1 << (b))
 #define INTERVAL_MASK(b) (1 << (b))
 
-- 
GitLab