mirror of
https://github.com/postgres/postgres.git
synced 2025-12-21 05:21:08 +03:00
Support alternate storage scheme of 64-bit integer for date/time types.
Use "--enable-integer-datetimes" in configuration to use this rather than the original float8 storage. I would recommend the integer-based storage for any platform on which it is available. We perhaps should make this the default for the production release. Change timezone(timestamptz) results to return timestamp rather than a character string. Formerly, we didn't have a way to represent timestamps with an explicit time zone other than freezing the info into a string. Now, we can reasonably omit the explicit time zone from the result and return a timestamp with values appropriate for the specified time zone. Much cleaner, and if you need the time zone in the result you can put it into a character string pretty easily anyway. Allow fractional seconds in date/time types even for dates prior to 1BC. Limit timestamp data types to 6 decimal places of precision. Just right for a micro-second storage of int8 date/time types, and reduces the number of places ad-hoc rounding was occuring for the float8-based types. Use lookup tables for precision/rounding calculations for timestamp and interval types. Formerly used pow() to calculate the desired value but with a more limited range there is no reason to not type in a lookup table. Should be *much* better performance, though formerly there were some optimizations to help minimize the number of times pow() was called. Define a HAVE_INT64_TIMESTAMP variable. Based on the configure option "--enable-integer-datetimes" and the existing internal INT64_IS_BUSTED. Add explicit date/interval operators and functions for addition and subtraction. Formerly relied on implicit type promotion from date to timestamp with time zone. Change timezone conversion functions for the timetz type from "timetz()" to "timezone()". This is consistant with other time zone coersion functions for other types. Bump the catalog version to 200204201. Fix up regression tests to reflect changes in fractional seconds representation for date/times in BC eras. All regression tests pass on my Linux box.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: timestamp.h,v 1.24 2001/11/05 17:46:36 momjian Exp $
|
||||
* $Id: timestamp.h,v 1.25 2002/04/21 19:48:31 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -18,8 +18,11 @@
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "fmgr.h"
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
#include "utils/int8.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Timestamp represents absolute time.
|
||||
@@ -31,16 +34,22 @@
|
||||
* consisting of a beginning and ending time, not a time span - thomas 97/03/20
|
||||
*/
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
typedef int64 Timestamp;
|
||||
typedef int64 TimestampTz;
|
||||
#else
|
||||
typedef double Timestamp;
|
||||
|
||||
typedef double TimestampTz;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double time; /* all time units other than months and
|
||||
* years */
|
||||
int32 month; /* months and years, after time for
|
||||
* alignment */
|
||||
#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
|
||||
int32 month; /* months and years, after time for alignment */
|
||||
} Interval;
|
||||
|
||||
|
||||
@@ -50,6 +59,27 @@ typedef struct
|
||||
* For Timestamp, we make use of the same support routines as for float8.
|
||||
* Therefore Timestamp is pass-by-reference if and only if float8 is!
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
#define DatumGetTimestamp(X) ((Timestamp) DatumGetInt64(X))
|
||||
#define DatumGetTimestampTz(X) ((TimestampTz) DatumGetInt64(X))
|
||||
#define DatumGetIntervalP(X) ((Interval *) DatumGetPointer(X))
|
||||
|
||||
#define TimestampGetDatum(X) Int64GetDatum(X)
|
||||
#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_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_INTERVAL_P(x) return IntervalPGetDatum(x)
|
||||
|
||||
#define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1)
|
||||
#define DT_NOEND (INT64CONST(0x7fffffffffffffff))
|
||||
|
||||
#else
|
||||
#define DatumGetTimestamp(X) ((Timestamp) DatumGetFloat8(X))
|
||||
#define DatumGetTimestampTz(X) ((TimestampTz) DatumGetFloat8(X))
|
||||
#define DatumGetIntervalP(X) ((Interval *) DatumGetPointer(X))
|
||||
@@ -66,7 +96,6 @@ 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)
|
||||
@@ -74,6 +103,7 @@ typedef struct
|
||||
#define DT_NOBEGIN (-DBL_MAX)
|
||||
#define DT_NOEND (DBL_MAX)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define TIMESTAMP_NOBEGIN(j) do {j = DT_NOBEGIN;} while (0)
|
||||
#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
|
||||
@@ -83,8 +113,21 @@ typedef struct
|
||||
|
||||
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
|
||||
|
||||
|
||||
#define MAX_TIMESTAMP_PRECISION 6
|
||||
#define MAX_INTERVAL_PRECISION 6
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
typedef int32 fsec_t;
|
||||
|
||||
#define SECONDS_TO_TIMESTAMP(x) (INT64CONST(x000000))
|
||||
#else
|
||||
typedef double fsec_t;
|
||||
|
||||
#define SECONDS_TO_TIMESTAMP(x) (xe0)
|
||||
#define TIME_PREC_INV 1000000.0
|
||||
#define JROUND(j) (rint(((double) (j))*TIME_PREC_INV)/TIME_PREC_INV)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -167,13 +210,13 @@ extern Datum now(PG_FUNCTION_ARGS);
|
||||
|
||||
/* Internal routines (not fmgr-callable) */
|
||||
|
||||
extern int tm2timestamp(struct tm * tm, double fsec, int *tzp, Timestamp *dt);
|
||||
extern int tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
|
||||
extern int timestamp2tm(Timestamp dt, int *tzp, struct tm * tm,
|
||||
double *fsec, char **tzn);
|
||||
extern void dt2time(Timestamp dt, int *hour, int *min, double *sec);
|
||||
fsec_t *fsec, char **tzn);
|
||||
extern void dt2time(Timestamp dt, int *hour, int *min, int *sec, fsec_t *fsec);
|
||||
|
||||
extern int interval2tm(Interval span, struct tm * tm, float8 *fsec);
|
||||
extern int tm2interval(struct tm * tm, double fsec, Interval *span);
|
||||
extern int interval2tm(Interval span, struct tm * tm, fsec_t *fsec);
|
||||
extern int tm2interval(struct tm * tm, fsec_t fsec, Interval *span);
|
||||
|
||||
extern Timestamp SetEpochTimestamp(void);
|
||||
extern void GetEpochTime(struct tm * tm);
|
||||
|
||||
Reference in New Issue
Block a user