diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 70f60c94622448f29365213418dbe7db55be600d..5b6b9ebfa979ef3300ebe56aced5a14b6d9374d4 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.139 2008/02/17 02:09:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.140 2008/03/21 01:31:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1838,9 +1838,9 @@ timetztypmodout(PG_FUNCTION_ARGS)
 static int
 timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp)
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		trem = time->time;
+	TimeOffset	trem = time->time;
 
+#ifdef HAVE_INT64_TIMESTAMP
 	tm->tm_hour = trem / USECS_PER_HOUR;
 	trem -= tm->tm_hour * USECS_PER_HOUR;
 	tm->tm_min = trem / USECS_PER_MINUTE;
@@ -1848,8 +1848,6 @@ timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp)
 	tm->tm_sec = trem / USECS_PER_SEC;
 	*fsec = trem - tm->tm_sec * USECS_PER_SEC;
 #else
-	double		trem = time->time;
-
 recalc:
 	TMODULO(trem, tm->tm_hour, (double) SECS_PER_HOUR);
 	TMODULO(trem, tm->tm_min, (double) SECS_PER_MINUTE);
@@ -1895,17 +1893,14 @@ timetz_scale(PG_FUNCTION_ARGS)
 static int
 timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
 {
-	/* Primary sort is by true (GMT-equivalent) time */
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		t1,
+	TimeOffset	t1,
 				t2;
 
+	/* Primary sort is by true (GMT-equivalent) time */
+#ifdef HAVE_INT64_TIMESTAMP
 	t1 = time1->time + (time1->zone * USECS_PER_SEC);
 	t2 = time2->time + (time2->zone * USECS_PER_SEC);
 #else
-	double		t1,
-				t2;
-
 	t1 = time1->time + time1->zone;
 	t2 = time2->time + time2->zone;
 #endif
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 2265b7d903eca17e5462932f789e8a03942d5aa5..c1a484d9bb67b8790eb6567767542f05894f322b 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.153 2008/02/17 02:09:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.154 2008/03/21 01:31:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -831,12 +831,7 @@ interval_reltime(PG_FUNCTION_ARGS)
 	int			year,
 				month,
 				day;
-
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		span;
-#else
-	double		span;
-#endif
+	TimeOffset	span;
 
 	year = interval->month / MONTHS_PER_YEAR;
 	month = interval->month % MONTHS_PER_YEAR;
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index f450922f26e5c00b6acc3ae346acebd95e70b624..8ca6f998c9811d1b3378436bbef18a0f2ce043a1 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.185 2008/02/17 02:09:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.186 2008/03/21 01:31:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,11 +44,7 @@
 TimestampTz PgStartTime;
 
 
-#ifdef HAVE_INT64_TIMESTAMP
-static int64 time2t(const int hour, const int min, const int sec, const fsec_t fsec);
-#else
-static double time2t(const int hour, const int min, const int sec, const fsec_t fsec);
-#endif
+static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec);
 static int	EncodeSpecialTimestamp(Timestamp dt, char *str);
 static Timestamp dt2local(Timestamp dt, int timezone);
 static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod);
@@ -977,11 +973,7 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 		}
 		else if (range == INTERVAL_MASK(MINUTE))
 		{
-#ifdef HAVE_INT64_TIMESTAMP
-			int64		hour;
-#else
-			double		hour;
-#endif
+			TimeOffset	hour;
 
 			interval->month = 0;
 			interval->day = 0;
@@ -998,11 +990,7 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 		}
 		else if (range == INTERVAL_MASK(SECOND))
 		{
-#ifdef HAVE_INT64_TIMESTAMP
-			int64		minute;
-#else
-			double		minute;
-#endif
+			TimeOffset	minute;
 
 			interval->month = 0;
 			interval->day = 0;
@@ -1076,11 +1064,7 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
 		else if (range == (INTERVAL_MASK(MINUTE) |
 						   INTERVAL_MASK(SECOND)))
 		{
-#ifdef HAVE_INT64_TIMESTAMP
-			int64		hour;
-#else
-			double		hour;
-#endif
+			TimeOffset	hour;
 
 			interval->month = 0;
 			interval->day = 0;
@@ -1342,11 +1326,7 @@ timestamptz_to_str(TimestampTz t)
 void
 dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		time;
-#else
-	double		time;
-#endif
+	TimeOffset	time;
 
 	time = jd;
 
@@ -1547,13 +1527,8 @@ recalc_t:
 int
 tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int			date;
-	int64		time;
-#else
-	double		date,
-				time;
-#endif
+	TimeOffset	date;
+	TimeOffset	time;
 
 	/* Julian day routines are not correct for negative Julian days */
 	if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
@@ -1596,13 +1571,8 @@ tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
 int
 interval2tm(Interval span, struct pg_tm * tm, fsec_t *fsec)
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		time;
-	int64		tfrac;
-#else
-	double		time;
-	double		tfrac;
-#endif
+	TimeOffset	time;
+	TimeOffset	tfrac;
 
 	tm->tm_year = span.month / MONTHS_PER_YEAR;
 	tm->tm_mon = span.month % MONTHS_PER_YEAR;
@@ -1658,19 +1628,15 @@ tm2interval(struct pg_tm * tm, fsec_t fsec, Interval *span)
 	return 0;
 }
 
-#ifdef HAVE_INT64_TIMESTAMP
-static int64
+static TimeOffset
 time2t(const int hour, const int min, const int sec, const fsec_t fsec)
 {
+#ifdef HAVE_INT64_TIMESTAMP
 	return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
-}	/* time2t() */
 #else
-static double
-time2t(const int hour, const int min, const int sec, const fsec_t fsec)
-{
 	return (((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec + fsec;
-}	/* time2t() */
 #endif
+}
 
 static Timestamp
 dt2local(Timestamp dt, int tz)
@@ -1681,7 +1647,7 @@ dt2local(Timestamp dt, int tz)
 	dt -= tz;
 #endif
 	return dt;
-}	/* dt2local() */
+}
 
 
 /*****************************************************************************
@@ -2042,13 +2008,8 @@ timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
 static int
 interval_cmp_internal(Interval *interval1, Interval *interval2)
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		span1,
-				span2;
-#else
-	double		span1,
+	TimeOffset	span1,
 				span2;
-#endif
 
 	span1 = interval1->time;
 	span2 = interval2->time;
@@ -2387,12 +2348,7 @@ interval_justify_interval(PG_FUNCTION_ARGS)
 {
 	Interval   *span = PG_GETARG_INTERVAL_P(0);
 	Interval   *result;
-
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		wholeday;
-#else
-	double		wholeday;
-#endif
+	TimeOffset	wholeday;
 	int32		wholemonth;
 
 	result = (Interval *) palloc(sizeof(Interval));
@@ -2459,12 +2415,7 @@ interval_justify_hours(PG_FUNCTION_ARGS)
 {
 	Interval   *span = PG_GETARG_INTERVAL_P(0);
 	Interval   *result;
-
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		wholeday;
-#else
-	double		wholeday;
-#endif
+	TimeOffset	wholeday;
 
 	result = (Interval *) palloc(sizeof(Interval));
 	result->month = span->month;
diff --git a/src/include/utils/date.h b/src/include/utils/date.h
index eca2700ed1736b5965b688319ab78067cfcfda4b..5f235498363f8561a1bb7ca583685db6d2615149 100644
--- a/src/include/utils/date.h
+++ b/src/include/utils/date.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/date.h,v 1.39 2008/01/01 19:45:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/date.h,v 1.40 2008/03/21 01:31:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,11 +29,7 @@ typedef float8 TimeADT;
 
 typedef struct
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		time;			/* all time units other than months and years */
-#else
-	double		time;			/* all time units other than months and years */
-#endif
+	TimeADT		time;			/* all time units other than months and years */
 	int32		zone;			/* numeric time zone, in seconds */
 } TimeTzADT;
 
@@ -54,7 +50,8 @@ typedef struct
 #define DateADTGetDatum(X)	  Int32GetDatum(X)
 #define TimeADTGetDatum(X)	  Int64GetDatum(X)
 #define TimeTzADTPGetDatum(X) PointerGetDatum(X)
-#else
+
+#else  /* !HAVE_INT64_TIMESTAMP */
 
 #define MAX_TIME_PRECISION 10
 
@@ -69,6 +66,7 @@ typedef struct
 #define DateADTGetDatum(X)	  Int32GetDatum(X)
 #define TimeADTGetDatum(X)	  Float8GetDatum(X)
 #define TimeTzADTPGetDatum(X) PointerGetDatum(X)
+
 #endif   /* HAVE_INT64_TIMESTAMP */
 
 #define PG_GETARG_DATEADT(n)	 DatumGetDateADT(PG_GETARG_DATUM(n))
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index cc224aa147a4835d0dfd489ae14647bd9ffe5687..8950979b945e3913a289f1a0cc12750db5f8a9d1 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.75 2008/02/17 02:09:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.76 2008/03/21 01:31:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,31 +25,42 @@
 
 /*
  * Timestamp represents absolute time.
+ *
  * Interval represents delta time. Keep track of months (and years), days,
- *	and time separately since the elapsed time spanned is unknown until
- *	instantiated relative to an absolute time.
+ * 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.
  */
 
 #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
 {
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		time;			/* all time units other than days, months and
-								 * years */
-#else
-	double		time;			/* all time units other than days, months and
+	TimeOffset	time;			/* all time units other than days, months and
 								 * years */
-#endif
 	int32		day;			/* days, after time for alignment */
 	int32		month;			/* months and years, after time for alignment */
 } Interval;
@@ -106,17 +117,18 @@ typedef struct
 #define TimestampTzGetDatum(X) Int64GetDatum(X)
 #define IntervalPGetDatum(X) PointerGetDatum(X)
 
-#define PG_GETARG_TIMESTAMP(n) PG_GETARG_INT64(n)
-#define PG_GETARG_TIMESTAMPTZ(n) PG_GETARG_INT64(n)
+#define PG_GETARG_TIMESTAMP(n) DatumGetTimestamp(PG_GETARG_DATUM(n))
+#define PG_GETARG_TIMESTAMPTZ(n) DatumGetTimestampTz(PG_GETARG_DATUM(n))
 #define PG_GETARG_INTERVAL_P(n) DatumGetIntervalP(PG_GETARG_DATUM(n))
 
-#define PG_RETURN_TIMESTAMP(x) PG_RETURN_INT64(x)
-#define PG_RETURN_TIMESTAMPTZ(x) PG_RETURN_INT64(x)
+#define PG_RETURN_TIMESTAMP(x) return TimestampGetDatum(x)
+#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
+
+#else  /* !HAVE_INT64_TIMESTAMP */
 
 #define DatumGetTimestamp(X)  ((Timestamp) DatumGetFloat8(X))
 #define DatumGetTimestampTz(X)	((TimestampTz) DatumGetFloat8(X))
@@ -141,6 +153,7 @@ typedef struct
 #define DT_NOBEGIN		(-DBL_MAX)
 #define DT_NOEND		(DBL_MAX)
 #endif
+
 #endif   /* HAVE_INT64_TIMESTAMP */
 
 
@@ -154,14 +167,6 @@ typedef struct
 
 #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
 
-#ifdef HAVE_INT64_TIMESTAMP
-
-typedef int32 fsec_t;
-#else
-
-typedef double fsec_t;
-#endif
-
 /*
  *	Round off to MAX_TIMESTAMP_PRECISION decimal places.
  *	Note: this is also used for rounding off intervals.