diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 70f60c9462..5b6b9ebfa9 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 2265b7d903..c1a484d9bb 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 f450922f26..8ca6f998c9 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; } +static TimeOffset +time2t(const int hour, const int min, const int sec, const fsec_t fsec) +{ #ifdef HAVE_INT64_TIMESTAMP -static int64 -time2t(const int hour, const int min, const int sec, const fsec_t fsec) -{ 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, + TimeOffset span1, span2; -#else - double 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 eca2700ed1..5f23549836 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 cc224aa147..8950979b94 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 + TimeOffset time; /* all time units other than days, months and * years */ -#else - double 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.