Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* timestamp.c
|
2002-09-21 21:52:41 +02:00
|
|
|
* Functions for the built-in SQL92 types "timestamp" and "interval".
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*
|
2004-12-31 23:04:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2005-07-24 06:37:07 +02:00
|
|
|
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.146 2005/07/24 04:37:07 momjian Exp $
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2000-05-29 03:59:17 +02:00
|
|
|
|
|
|
|
#include "postgres.h"
|
|
|
|
|
1997-04-03 21:58:11 +02:00
|
|
|
#include <ctype.h>
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
#include <limits.h>
|
2005-06-30 05:48:58 +02:00
|
|
|
#include <sys/time.h>
|
2000-07-13 00:59:15 +02:00
|
|
|
|
2000-06-19 05:55:01 +02:00
|
|
|
#include "access/hash.h"
|
2000-05-29 03:59:17 +02:00
|
|
|
#include "access/xact.h"
|
2002-08-26 19:54:02 +02:00
|
|
|
#include "catalog/pg_type.h"
|
2003-05-13 01:08:52 +02:00
|
|
|
#include "libpq/pqformat.h"
|
1997-07-01 02:22:46 +02:00
|
|
|
#include "miscadmin.h"
|
2004-05-07 02:24:59 +02:00
|
|
|
#include "parser/scansup.h"
|
2000-07-17 05:05:41 +02:00
|
|
|
#include "utils/array.h"
|
1997-03-14 06:58:13 +01:00
|
|
|
#include "utils/builtins.h"
|
2005-06-30 00:51:57 +02:00
|
|
|
#include "utils/datetime.h"
|
|
|
|
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2002-09-21 21:52:41 +02:00
|
|
|
/*
|
|
|
|
* gcc's -ffast-math switch breaks routines that expect exact results from
|
2005-07-21 05:56:25 +02:00
|
|
|
* expressions like timeval / SECS_PER_HOUR, where timeval is double.
|
2002-09-21 21:52:41 +02:00
|
|
|
*/
|
|
|
|
#ifdef __FAST_MATH__
|
|
|
|
#error -ffast-math is known to break this code
|
|
|
|
#endif
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-06-30 00:51:57 +02:00
|
|
|
/* Set at postmaster start */
|
|
|
|
TimestampTz PgStartTime;
|
|
|
|
|
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#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
|
2000-06-09 00:38:00 +02:00
|
|
|
static int EncodeSpecialTimestamp(Timestamp dt, char *str);
|
|
|
|
static Timestamp dt2local(Timestamp dt, int timezone);
|
2001-10-03 17:50:48 +02:00
|
|
|
static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod);
|
2001-10-18 19:30:21 +02:00
|
|
|
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod);
|
2004-03-22 02:38:18 +01:00
|
|
|
static TimestampTz timestamp2timestamptz(Timestamp timestamp);
|
2001-09-28 10:09:14 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* USER I/O ROUTINES *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/* timestamp_in()
|
|
|
|
* Convert a string to internal form.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_in(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
char *str = PG_GETARG_CSTRING(0);
|
2001-10-25 07:50:21 +02:00
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp result;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
int tz;
|
|
|
|
int dtype;
|
|
|
|
int nf;
|
2003-08-28 01:29:29 +02:00
|
|
|
int dterr;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
char *field[MAXDATEFIELDS];
|
|
|
|
int ftype[MAXDATEFIELDS];
|
2005-05-26 04:04:14 +02:00
|
|
|
char workbuf[MAXDATELEN + MAXDATEFIELDS];
|
2002-08-04 08:44:47 +02:00
|
|
|
|
2005-05-26 04:04:14 +02:00
|
|
|
dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
|
|
|
|
field, ftype, MAXDATEFIELDS, &nf);
|
2003-08-28 01:29:29 +02:00
|
|
|
if (dterr == 0)
|
|
|
|
dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
|
|
|
|
if (dterr != 0)
|
|
|
|
DateTimeParseError(dterr, str, "timestamp");
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
switch (dtype)
|
|
|
|
{
|
|
|
|
case DTK_DATE:
|
2001-09-28 10:09:14 +02:00
|
|
|
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range: \"%s\"", str)));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_EPOCH:
|
2001-09-28 10:09:14 +02:00
|
|
|
result = SetEpochTimestamp();
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_LATE:
|
2000-06-09 03:11:16 +02:00
|
|
|
TIMESTAMP_NOEND(result);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_EARLY:
|
2000-06-09 03:11:16 +02:00
|
|
|
TIMESTAMP_NOBEGIN(result);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_INVALID:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("date/time value \"%s\" is no longer supported", str)));
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
TIMESTAMP_NOEND(result);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
1997-07-01 02:22:46 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"",
|
|
|
|
dtype, str);
|
2001-09-28 10:09:14 +02:00
|
|
|
TIMESTAMP_NOEND(result);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
AdjustTimestampForTypmod(&result, typmod);
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/* timestamp_out()
|
|
|
|
* Convert a timestamp to external form.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_out(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
1997-09-08 04:41:22 +02:00
|
|
|
char *result;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
char *tzn = NULL;
|
|
|
|
char buf[MAXDATELEN + 1];
|
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
EncodeSpecialTimestamp(timestamp, buf);
|
2005-06-15 02:34:11 +02:00
|
|
|
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
EncodeDateTime(tm, fsec, NULL, &tzn, DateStyle, buf);
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
result = pstrdup(buf);
|
|
|
|
PG_RETURN_CSTRING(result);
|
|
|
|
}
|
|
|
|
|
2003-05-13 01:08:52 +02:00
|
|
|
/*
|
|
|
|
* timestamp_recv - converts external binary format to timestamp
|
|
|
|
*
|
|
|
|
* We make no attempt to provide compatibility between int and float
|
|
|
|
* timestamp representations ...
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_recv(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
2005-07-10 23:14:00 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2004-06-03 19:57:09 +02:00
|
|
|
*tm = &tt;
|
|
|
|
fsec_t fsec;
|
2003-05-13 01:08:52 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2004-06-03 19:57:09 +02:00
|
|
|
timestamp = (Timestamp) pq_getmsgint64(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#else
|
2004-06-03 19:57:09 +02:00
|
|
|
timestamp = (Timestamp) pq_getmsgfloat8(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#endif
|
2004-06-03 19:57:09 +02:00
|
|
|
|
|
|
|
/* rangecheck: see if timestamp_out would like it */
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
2004-08-29 07:07:03 +02:00
|
|
|
/* ok */ ;
|
2005-07-10 23:14:00 +02:00
|
|
|
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2004-06-03 19:57:09 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
AdjustTimestampForTypmod(×tamp, typmod);
|
|
|
|
|
2004-06-03 19:57:09 +02:00
|
|
|
PG_RETURN_TIMESTAMP(timestamp);
|
2003-05-13 01:08:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* timestamp_send - converts timestamp to binary format
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_send(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
StringInfoData buf;
|
|
|
|
|
|
|
|
pq_begintypsend(&buf);
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
pq_sendint64(&buf, timestamp);
|
|
|
|
#else
|
|
|
|
pq_sendfloat8(&buf, timestamp);
|
|
|
|
#endif
|
|
|
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
/* timestamp_scale()
|
|
|
|
* Adjust time type for specified scale factor.
|
|
|
|
* Used by PostgreSQL type system to stuff columns.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_scale(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
2001-10-03 07:29:27 +02:00
|
|
|
int32 typmod = PG_GETARG_INT32(1);
|
|
|
|
Timestamp result;
|
|
|
|
|
|
|
|
result = timestamp;
|
|
|
|
|
2001-10-03 17:50:48 +02:00
|
|
|
AdjustTimestampForTypmod(&result, typmod);
|
2001-10-03 07:29:27 +02:00
|
|
|
|
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
|
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2002-09-04 22:31:48 +02:00
|
|
|
static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
|
2002-04-21 21:52:18 +02:00
|
|
|
INT64CONST(1000000),
|
|
|
|
INT64CONST(100000),
|
|
|
|
INT64CONST(10000),
|
|
|
|
INT64CONST(1000),
|
|
|
|
INT64CONST(100),
|
|
|
|
INT64CONST(10),
|
|
|
|
INT64CONST(1)
|
|
|
|
};
|
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
static const int64 TimestampOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
|
2003-01-09 02:06:57 +01:00
|
|
|
INT64CONST(500000),
|
|
|
|
INT64CONST(50000),
|
|
|
|
INT64CONST(5000),
|
|
|
|
INT64CONST(500),
|
|
|
|
INT64CONST(50),
|
|
|
|
INT64CONST(5),
|
2002-04-21 21:52:18 +02:00
|
|
|
INT64CONST(0)
|
|
|
|
};
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-09-04 22:31:48 +02:00
|
|
|
static const double TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
|
2002-04-21 21:52:18 +02:00
|
|
|
1,
|
|
|
|
10,
|
|
|
|
100,
|
|
|
|
1000,
|
|
|
|
10000,
|
|
|
|
100000,
|
|
|
|
1000000
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!TIMESTAMP_NOT_FINITE(*time)
|
|
|
|
&& (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
|
2001-10-03 07:29:27 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
if (typmod < 0 || typmod > MAX_TIMESTAMP_PRECISION)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("timestamp(%d) precision must be between %d and %d",
|
|
|
|
typmod, 0, MAX_TIMESTAMP_PRECISION)));
|
2001-10-03 07:29:27 +02:00
|
|
|
|
2003-01-09 02:06:57 +01:00
|
|
|
/*
|
|
|
|
* Note: this round-to-nearest code is not completely consistent
|
|
|
|
* about rounding values that are exactly halfway between integral
|
2003-08-04 02:43:34 +02:00
|
|
|
* values. On most platforms, rint() will implement
|
|
|
|
* round-to-nearest-even, but the integer code always rounds up
|
|
|
|
* (away from zero). Is it worth trying to be consistent?
|
2003-01-09 02:06:57 +01:00
|
|
|
*/
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
if (*time >= INT64CONST(0))
|
|
|
|
{
|
2005-05-24 04:09:45 +02:00
|
|
|
*time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
|
|
|
|
TimestampScales[typmod];
|
2002-04-21 21:52:18 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
*time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
|
|
|
|
* TimestampScales[typmod]);
|
2002-04-21 21:52:18 +02:00
|
|
|
}
|
2003-01-09 02:06:57 +01:00
|
|
|
#else
|
2005-05-24 04:09:45 +02:00
|
|
|
*time = rint((double)*time * TimestampScales[typmod]) / TimestampScales[typmod];
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-03 07:29:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
/* timestamptz_in()
|
|
|
|
* Convert a string to internal form.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_in(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
char *str = PG_GETARG_CSTRING(0);
|
2001-10-25 07:50:21 +02:00
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
|
|
|
int tz;
|
|
|
|
int dtype;
|
|
|
|
int nf;
|
2003-08-28 01:29:29 +02:00
|
|
|
int dterr;
|
2001-09-28 10:09:14 +02:00
|
|
|
char *field[MAXDATEFIELDS];
|
|
|
|
int ftype[MAXDATEFIELDS];
|
2005-05-26 04:04:14 +02:00
|
|
|
char workbuf[MAXDATELEN + MAXDATEFIELDS];
|
2002-08-04 08:44:47 +02:00
|
|
|
|
2005-05-26 04:04:14 +02:00
|
|
|
dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
|
|
|
|
field, ftype, MAXDATEFIELDS, &nf);
|
2003-08-28 01:29:29 +02:00
|
|
|
if (dterr == 0)
|
|
|
|
dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
|
|
|
|
if (dterr != 0)
|
|
|
|
DateTimeParseError(dterr, str, "timestamp with time zone");
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
switch (dtype)
|
|
|
|
{
|
|
|
|
case DTK_DATE:
|
|
|
|
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range: \"%s\"", str)));
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_EPOCH:
|
|
|
|
result = SetEpochTimestamp();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_LATE:
|
|
|
|
TIMESTAMP_NOEND(result);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_EARLY:
|
|
|
|
TIMESTAMP_NOBEGIN(result);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_INVALID:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("date/time value \"%s\" is no longer supported", str)));
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
TIMESTAMP_NOEND(result);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"",
|
|
|
|
dtype, str);
|
2001-09-28 10:09:14 +02:00
|
|
|
TIMESTAMP_NOEND(result);
|
|
|
|
}
|
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
AdjustTimestampForTypmod(&result, typmod);
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* timestamptz_out()
|
|
|
|
* Convert a timestamp to external form.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_out(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz dt = PG_GETARG_TIMESTAMPTZ(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
char *result;
|
1997-09-08 04:41:22 +02:00
|
|
|
int tz;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
1997-09-08 04:41:22 +02:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
char *tzn;
|
1997-09-08 04:41:22 +02:00
|
|
|
char buf[MAXDATELEN + 1];
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(dt))
|
2000-06-09 03:11:16 +02:00
|
|
|
EncodeSpecialTimestamp(dt, buf);
|
2005-06-15 02:34:11 +02:00
|
|
|
else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = pstrdup(buf);
|
|
|
|
PG_RETURN_CSTRING(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2003-05-13 01:08:52 +02:00
|
|
|
/*
|
|
|
|
* timestamptz_recv - converts external binary format to timestamptz
|
|
|
|
*
|
|
|
|
* We make no attempt to provide compatibility between int and float
|
|
|
|
* timestamp representations ...
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_recv(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
2005-07-10 23:14:00 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz timestamp;
|
2004-06-03 19:57:09 +02:00
|
|
|
int tz;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2004-06-03 19:57:09 +02:00
|
|
|
*tm = &tt;
|
|
|
|
fsec_t fsec;
|
|
|
|
char *tzn;
|
2003-05-13 01:08:52 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2004-06-03 19:57:09 +02:00
|
|
|
timestamp = (TimestampTz) pq_getmsgint64(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#else
|
2004-06-03 19:57:09 +02:00
|
|
|
timestamp = (TimestampTz) pq_getmsgfloat8(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#endif
|
2004-06-03 19:57:09 +02:00
|
|
|
|
|
|
|
/* rangecheck: see if timestamptz_out would like it */
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
2004-08-29 07:07:03 +02:00
|
|
|
/* ok */ ;
|
2005-07-21 06:41:43 +02:00
|
|
|
else if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2004-06-03 19:57:09 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
AdjustTimestampForTypmod(×tamp, typmod);
|
|
|
|
|
2004-06-03 19:57:09 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(timestamp);
|
2003-05-13 01:08:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* timestamptz_send - converts timestamptz to binary format
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_send(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
StringInfoData buf;
|
|
|
|
|
|
|
|
pq_begintypsend(&buf);
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
pq_sendint64(&buf, timestamp);
|
|
|
|
#else
|
|
|
|
pq_sendfloat8(&buf, timestamp);
|
|
|
|
#endif
|
|
|
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
/* timestamptz_scale()
|
|
|
|
* Adjust time type for specified scale factor.
|
|
|
|
* Used by PostgreSQL type system to stuff columns.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_scale(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
2001-10-03 07:29:27 +02:00
|
|
|
int32 typmod = PG_GETARG_INT32(1);
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
2001-10-03 07:29:27 +02:00
|
|
|
|
|
|
|
result = timestamp;
|
|
|
|
|
2001-10-03 17:50:48 +02:00
|
|
|
AdjustTimestampForTypmod(&result, typmod);
|
2001-10-03 07:29:27 +02:00
|
|
|
|
|
|
|
PG_RETURN_TIMESTAMPTZ(result);
|
|
|
|
}
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* interval_in()
|
|
|
|
* Convert a string to internal form.
|
|
|
|
*
|
|
|
|
* External format(s):
|
|
|
|
* Uses the generic date/time parsing and decoding routines.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_in(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
char *str = PG_GETARG_CSTRING(0);
|
2001-10-25 07:50:21 +02:00
|
|
|
|
2001-10-18 19:30:21 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2001-09-28 10:09:14 +02:00
|
|
|
Interval *result;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
int dtype;
|
|
|
|
int nf;
|
2003-08-28 01:29:29 +02:00
|
|
|
int dterr;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
char *field[MAXDATEFIELDS];
|
|
|
|
int ftype[MAXDATEFIELDS];
|
2005-05-26 04:04:14 +02:00
|
|
|
char workbuf[256];
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
tm->tm_year = 0;
|
|
|
|
tm->tm_mon = 0;
|
|
|
|
tm->tm_mday = 0;
|
|
|
|
tm->tm_hour = 0;
|
|
|
|
tm->tm_min = 0;
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
fsec = 0;
|
|
|
|
|
2005-05-26 04:04:14 +02:00
|
|
|
dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
|
|
|
|
ftype, MAXDATEFIELDS, &nf);
|
2003-08-28 01:29:29 +02:00
|
|
|
if (dterr == 0)
|
|
|
|
dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec);
|
|
|
|
if (dterr != 0)
|
|
|
|
{
|
|
|
|
if (dterr == DTERR_FIELD_OVERFLOW)
|
|
|
|
dterr = DTERR_INTERVAL_OVERFLOW;
|
|
|
|
DateTimeParseError(dterr, str, "interval");
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
switch (dtype)
|
|
|
|
{
|
|
|
|
case DTK_DELTA:
|
2001-09-28 10:09:14 +02:00
|
|
|
if (tm2interval(tm, fsec, result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("interval out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_INVALID:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("date/time value \"%s\" is no longer supported", str)));
|
1997-10-09 07:02:17 +02:00
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
1997-10-09 07:02:17 +02:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
|
|
|
|
dtype, str);
|
1997-10-09 07:02:17 +02:00
|
|
|
}
|
1998-02-26 05:46:47 +01:00
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
AdjustIntervalForTypmod(result, typmod);
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* interval_out()
|
|
|
|
* Convert a time span to external form.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_out(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
char *result;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
char buf[MAXDATELEN + 1];
|
|
|
|
|
|
|
|
if (interval2tm(*span, tm, &fsec) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "could not convert interval to tm");
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
if (EncodeInterval(tm, fsec, DateStyle, buf) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "could not format interval");
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = pstrdup(buf);
|
|
|
|
PG_RETURN_CSTRING(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2003-05-13 01:08:52 +02:00
|
|
|
/*
|
|
|
|
* interval_recv - converts external binary format to interval
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_recv(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
2005-07-10 23:14:00 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
Oid typelem = PG_GETARG_OID(1);
|
|
|
|
#endif
|
|
|
|
int32 typmod = PG_GETARG_INT32(2);
|
2003-05-13 01:08:52 +02:00
|
|
|
Interval *interval;
|
|
|
|
|
|
|
|
interval = (Interval *) palloc(sizeof(Interval));
|
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = pq_getmsgint64(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = pq_getmsgfloat8(buf);
|
2003-05-13 01:08:52 +02:00
|
|
|
#endif
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = pq_getmsgint(buf, sizeof(interval->day));
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = pq_getmsgint(buf, sizeof(interval->month));
|
2003-05-13 01:08:52 +02:00
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
AdjustIntervalForTypmod(interval, typmod);
|
|
|
|
|
2003-05-13 01:08:52 +02:00
|
|
|
PG_RETURN_INTERVAL_P(interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* interval_send - converts interval to binary format
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_send(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(0);
|
|
|
|
StringInfoData buf;
|
|
|
|
|
|
|
|
pq_begintypsend(&buf);
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
pq_sendint64(&buf, interval->time);
|
|
|
|
#else
|
|
|
|
pq_sendfloat8(&buf, interval->time);
|
|
|
|
#endif
|
2005-07-20 18:42:32 +02:00
|
|
|
pq_sendint(&buf, interval->day, sizeof(interval->day));
|
2003-05-13 01:08:52 +02:00
|
|
|
pq_sendint(&buf, interval->month, sizeof(interval->month));
|
|
|
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-10-18 19:30:21 +02:00
|
|
|
/* interval_scale()
|
|
|
|
* Adjust interval type for specified fields.
|
|
|
|
* Used by PostgreSQL type system to stuff columns.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_scale(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(0);
|
|
|
|
int32 typmod = PG_GETARG_INT32(1);
|
|
|
|
Interval *result;
|
|
|
|
|
|
|
|
result = palloc(sizeof(Interval));
|
|
|
|
*result = *interval;
|
|
|
|
|
|
|
|
AdjustIntervalForTypmod(result, typmod);
|
|
|
|
|
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
2005-07-12 18:05:12 +02:00
|
|
|
/*
|
|
|
|
* Adjust interval for specified precision, in both YEAR to SECOND
|
|
|
|
* range and sub-second precision.
|
|
|
|
*/
|
2001-10-18 19:30:21 +02:00
|
|
|
static void
|
|
|
|
AdjustIntervalForTypmod(Interval *interval, int32 typmod)
|
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2002-09-04 22:31:48 +02:00
|
|
|
static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
|
2002-04-21 21:52:18 +02:00
|
|
|
INT64CONST(1000000),
|
|
|
|
INT64CONST(100000),
|
|
|
|
INT64CONST(10000),
|
|
|
|
INT64CONST(1000),
|
|
|
|
INT64CONST(100),
|
|
|
|
INT64CONST(10),
|
|
|
|
INT64CONST(1)
|
|
|
|
};
|
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
|
2003-01-09 02:06:57 +01:00
|
|
|
INT64CONST(500000),
|
|
|
|
INT64CONST(50000),
|
|
|
|
INT64CONST(5000),
|
|
|
|
INT64CONST(500),
|
|
|
|
INT64CONST(50),
|
|
|
|
INT64CONST(5),
|
2002-04-21 21:52:18 +02:00
|
|
|
INT64CONST(0)
|
|
|
|
};
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-09-04 22:31:48 +02:00
|
|
|
static const double IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
|
2002-05-14 15:37:27 +02:00
|
|
|
1,
|
2002-04-21 21:52:18 +02:00
|
|
|
10,
|
2002-05-14 15:37:27 +02:00
|
|
|
100,
|
|
|
|
1000,
|
|
|
|
10000,
|
|
|
|
100000,
|
|
|
|
1000000
|
2002-04-21 21:52:18 +02:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
/*
|
|
|
|
* Unspecified range and precision? Then not necessary to adjust.
|
2002-08-04 08:44:47 +02:00
|
|
|
* Setting typmod to -1 is the convention for all types.
|
|
|
|
*/
|
2001-10-18 19:30:21 +02:00
|
|
|
if (typmod != -1)
|
|
|
|
{
|
2002-08-04 08:44:47 +02:00
|
|
|
int range = INTERVAL_RANGE(typmod);
|
|
|
|
int precision = INTERVAL_PRECISION(typmod);
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2002-08-04 08:44:47 +02:00
|
|
|
if (range == INTERVAL_FULL_RANGE)
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
|
|
|
/* Do nothing... */
|
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(YEAR))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->month = (interval->month / MONTHS_PER_YEAR) * MONTHS_PER_YEAR;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = 0;
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(MONTH))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->month %= MONTHS_PER_YEAR;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = 0;
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* YEAR TO MONTH */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
|
2005-07-20 18:42:32 +02:00
|
|
|
{
|
|
|
|
/* month is already year to month */
|
|
|
|
interval->day = 0;
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(DAY))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->time = 0;
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(HOUR))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
interval->time = (interval->time / USECS_PER_HOUR) *
|
|
|
|
USECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->time = ((int)(interval->time / SECS_PER_HOUR)) * (double)SECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(MINUTE))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 hour;
|
|
|
|
#else
|
2001-10-25 07:50:21 +02:00
|
|
|
double hour;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
hour = interval->time / USECS_PER_HOUR;
|
|
|
|
interval->time -= hour * USECS_PER_HOUR;
|
|
|
|
interval->time = (interval->time / USECS_PER_MINUTE) *
|
|
|
|
USECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
TMODULO(interval->time, hour, (double)SECS_PER_HOUR);
|
|
|
|
interval->time = ((int)(interval->time / SECS_PER_MINUTE)) * (double)SECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == INTERVAL_MASK(SECOND))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 minute;
|
|
|
|
#else
|
|
|
|
double minute;
|
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
minute = interval->time / USECS_PER_MINUTE;
|
|
|
|
interval->time -= minute * USECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
TMODULO(interval->time, minute, (double)SECS_PER_MINUTE);
|
2005-07-20 18:42:32 +02:00
|
|
|
/* return subseconds too */
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* DAY TO HOUR */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(DAY) |
|
|
|
|
INTERVAL_MASK(HOUR)))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
interval->time = (interval->time / USECS_PER_HOUR) *
|
|
|
|
USECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->time = ((int) (interval->time / SECS_PER_HOUR)) * (double)SECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* DAY TO MINUTE */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(DAY) |
|
|
|
|
INTERVAL_MASK(HOUR) |
|
|
|
|
INTERVAL_MASK(MINUTE)))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
interval->time = (interval->time / USECS_PER_MINUTE) *
|
|
|
|
USECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->time = ((int)(interval->time / SECS_PER_MINUTE)) * (double)SECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* DAY TO SECOND */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(DAY) |
|
|
|
|
INTERVAL_MASK(HOUR) |
|
|
|
|
INTERVAL_MASK(MINUTE) |
|
|
|
|
INTERVAL_MASK(SECOND)))
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2001-10-18 19:30:21 +02:00
|
|
|
/* HOUR TO MINUTE */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(HOUR) |
|
|
|
|
INTERVAL_MASK(MINUTE)))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
interval->time = (interval->time / USECS_PER_MINUTE) *
|
|
|
|
USECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
interval->time = ((int)(interval->time / SECS_PER_MINUTE)) * (double)SECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* HOUR TO SECOND */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(HOUR) |
|
|
|
|
INTERVAL_MASK(MINUTE) |
|
|
|
|
INTERVAL_MASK(SECOND)))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
|
|
|
/* return subseconds too */
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
/* MINUTE TO SECOND */
|
2002-08-04 08:44:47 +02:00
|
|
|
else if (range == (INTERVAL_MASK(MINUTE) |
|
|
|
|
INTERVAL_MASK(SECOND)))
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 hour;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2001-10-25 07:50:21 +02:00
|
|
|
double hour;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
interval->day = 0;
|
2004-08-30 04:54:42 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
hour = interval->time / USECS_PER_HOUR;
|
|
|
|
interval->time -= hour * USECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
TMODULO(interval->time, hour, (double)SECS_PER_HOUR);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "unrecognized interval typmod: %d", typmod);
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2005-07-12 18:05:12 +02:00
|
|
|
/* Need to adjust subsecond precision? */
|
2002-08-04 08:44:47 +02:00
|
|
|
if (precision != INTERVAL_FULL_PRECISION)
|
2001-10-18 19:30:21 +02:00
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
if (precision < 0 || precision > MAX_INTERVAL_PRECISION)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("interval(%d) precision must be between %d and %d",
|
|
|
|
precision, 0, MAX_INTERVAL_PRECISION)));
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2003-01-09 02:06:57 +01:00
|
|
|
/*
|
2003-08-04 02:43:34 +02:00
|
|
|
* Note: this round-to-nearest code is not completely
|
|
|
|
* consistent about rounding values that are exactly halfway
|
|
|
|
* between integral values. On most platforms, rint() will
|
|
|
|
* implement round-to-nearest-even, but the integer code
|
|
|
|
* always rounds up (away from zero). Is it worth trying to
|
|
|
|
* be consistent?
|
2003-01-09 02:06:57 +01:00
|
|
|
*/
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
if (interval->time >= INT64CONST(0))
|
|
|
|
{
|
2005-05-24 04:09:45 +02:00
|
|
|
interval->time = ((interval->time +
|
2005-05-23 19:13:14 +02:00
|
|
|
IntervalOffsets[precision]) /
|
|
|
|
IntervalScales[precision]) *
|
|
|
|
IntervalScales[precision];
|
2002-04-21 21:52:18 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = -(((-interval->time +
|
|
|
|
IntervalOffsets[precision]) /
|
|
|
|
IntervalScales[precision]) *
|
|
|
|
IntervalScales[precision]);
|
2002-04-21 21:52:18 +02:00
|
|
|
}
|
2003-01-09 02:06:57 +01:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
interval->time = rint(((double) interval->time) *
|
|
|
|
IntervalScales[precision]) /
|
|
|
|
IntervalScales[precision];
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-10-18 19:30:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* EncodeSpecialTimestamp()
|
|
|
|
* Convert reserved timestamp data type to string.
|
|
|
|
*/
|
2000-06-09 00:38:00 +02:00
|
|
|
static int
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
EncodeSpecialTimestamp(Timestamp dt, char *str)
|
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_IS_NOBEGIN(dt))
|
|
|
|
strcpy(str, EARLY);
|
|
|
|
else if (TIMESTAMP_IS_NOEND(dt))
|
|
|
|
strcpy(str, LATE);
|
|
|
|
else
|
|
|
|
return FALSE;
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
return TRUE;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
} /* EncodeSpecialTimestamp() */
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
now(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2005-06-30 00:51:57 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(GetCurrentTransactionStartTimestamp());
|
1997-03-14 06:58:13 +01:00
|
|
|
}
|
|
|
|
|
2005-06-14 23:04:42 +02:00
|
|
|
Datum
|
|
|
|
pgsql_postmaster_start_time(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2005-06-30 00:51:57 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(PgStartTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GetCurrentTimestamp -- get the current operating system time
|
|
|
|
*
|
|
|
|
* Result is in the form of a TimestampTz value, and is expressed to the
|
|
|
|
* full precision of the gettimeofday() syscall
|
|
|
|
*/
|
|
|
|
TimestampTz
|
|
|
|
GetCurrentTimestamp(void)
|
|
|
|
{
|
|
|
|
TimestampTz result;
|
|
|
|
struct timeval tp;
|
|
|
|
|
|
|
|
gettimeofday(&tp, NULL);
|
|
|
|
|
|
|
|
result = tp.tv_sec -
|
|
|
|
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
|
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
result = (result * USECS_PER_SEC) + tp.tv_usec;
|
|
|
|
#else
|
|
|
|
result = result + (tp.tv_usec / 1000000.0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return result;
|
2005-06-14 23:04:42 +02:00
|
|
|
}
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
void
|
2002-04-21 21:52:18 +02:00
|
|
|
dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 time;
|
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
double time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
time = jd;
|
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
*hour = time / USECS_PER_HOUR;
|
|
|
|
time -= (*hour) * USECS_PER_HOUR;
|
|
|
|
*min = time / USECS_PER_MINUTE;
|
|
|
|
time -= (*min) * USECS_PER_MINUTE;
|
|
|
|
*sec = time / USECS_PER_SEC;
|
|
|
|
*fsec = time - (*sec * USECS_PER_SEC);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
*hour = time / SECS_PER_HOUR;
|
|
|
|
time -= (*hour) * SECS_PER_HOUR;
|
|
|
|
*min = time / SECS_PER_MINUTE;
|
|
|
|
time -= (*min) * SECS_PER_MINUTE;
|
2002-04-21 21:52:18 +02:00
|
|
|
*sec = time;
|
|
|
|
*fsec = JROUND(time - *sec);
|
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
} /* dt2time() */
|
|
|
|
|
|
|
|
|
2004-06-03 04:08:07 +02:00
|
|
|
/*
|
|
|
|
* timestamp2tm() - Convert timestamp data type to POSIX time structure.
|
|
|
|
*
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Note that year is _not_ 1900-based, but is an explicit full value.
|
|
|
|
* Also, month is one-based, _not_ zero-based.
|
|
|
|
* Returns:
|
|
|
|
* 0 on success
|
|
|
|
* -1 on out of range
|
2005-06-15 02:34:11 +02:00
|
|
|
*
|
|
|
|
* If attimezone is NULL, the global timezone (including possblly brute forced
|
|
|
|
* timezone) will be used.
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
|
|
|
int
|
2005-07-20 18:42:32 +02:00
|
|
|
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn, pg_tz *attimezone)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp date;
|
2004-06-03 19:57:09 +02:00
|
|
|
Timestamp time;
|
2004-06-03 04:08:07 +02:00
|
|
|
pg_time_t utime;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
/*
|
|
|
|
* If HasCTZSet is true then we have a brute force time zone
|
|
|
|
* specified. Go ahead and rotate to the local time zone since we will
|
|
|
|
* later bypass any calls which adjust the tm fields.
|
2001-10-18 19:30:21 +02:00
|
|
|
*/
|
2005-07-22 21:00:55 +02:00
|
|
|
if (attimezone == NULL && HasCTZSet && tzp != NULL)
|
2003-02-22 06:57:45 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
dt -= CTimeZone * USECS_PER_SEC;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2001-10-18 19:30:21 +02:00
|
|
|
dt -= CTimeZone;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2003-02-22 06:57:45 +01:00
|
|
|
}
|
2001-10-18 19:30:21 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
time = dt;
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
TMODULO(time, date, USECS_PER_DAY);
|
2002-04-21 21:52:18 +02:00
|
|
|
|
|
|
|
if (time < INT64CONST(0))
|
|
|
|
{
|
2005-05-23 20:56:55 +02:00
|
|
|
time += USECS_PER_DAY;
|
2005-05-23 19:13:14 +02:00
|
|
|
date -= 1;
|
2002-04-21 21:52:18 +02:00
|
|
|
}
|
|
|
|
#else
|
2005-05-23 20:56:55 +02:00
|
|
|
TMODULO(time, date, (double)SECS_PER_DAY);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
if (time < 0)
|
|
|
|
{
|
2005-05-23 23:54:02 +02:00
|
|
|
time += SECS_PER_DAY;
|
2005-05-23 19:13:14 +02:00
|
|
|
date -=1;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* add offset to go from J2000 back to standard Julian date */
|
2005-07-22 23:16:15 +02:00
|
|
|
date += POSTGRES_EPOCH_JDATE;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-06-03 19:57:09 +02:00
|
|
|
/* Julian day routine does not work for negative Julian days */
|
2004-08-30 04:54:42 +02:00
|
|
|
if (date <0 || date >(Timestamp) INT_MAX)
|
2004-06-03 19:57:09 +02:00
|
|
|
return -1;
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
2002-04-21 21:52:18 +02:00
|
|
|
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-06-03 04:08:07 +02:00
|
|
|
/* Done if no TZ conversion wanted */
|
|
|
|
if (tzp == NULL)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2004-06-03 04:08:07 +02:00
|
|
|
tm->tm_isdst = -1;
|
|
|
|
tm->tm_gmtoff = 0;
|
|
|
|
tm->tm_zone = NULL;
|
|
|
|
if (tzn != NULL)
|
|
|
|
*tzn = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
2001-10-18 19:30:21 +02:00
|
|
|
|
2004-06-03 04:08:07 +02:00
|
|
|
/*
|
|
|
|
* We have a brute force time zone per SQL99? Then use it without
|
|
|
|
* change since we have already rotated to the time zone.
|
|
|
|
*/
|
2005-07-22 21:00:55 +02:00
|
|
|
if (attimezone == NULL && HasCTZSet)
|
2004-06-03 04:08:07 +02:00
|
|
|
{
|
|
|
|
*tzp = CTimeZone;
|
|
|
|
tm->tm_isdst = 0;
|
|
|
|
tm->tm_gmtoff = CTimeZone;
|
|
|
|
tm->tm_zone = NULL;
|
|
|
|
if (tzn != NULL)
|
|
|
|
*tzn = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the time falls within the range of pg_time_t, use pg_localtime()
|
|
|
|
* to rotate to the local time zone.
|
|
|
|
*
|
|
|
|
* First, convert to an integral timestamp, avoiding possibly
|
|
|
|
* platform-specific roundoff-in-wrong-direction errors, and adjust to
|
2004-08-29 07:07:03 +02:00
|
|
|
* Unix epoch. Then see if we can convert to pg_time_t without loss.
|
2004-06-03 04:08:07 +02:00
|
|
|
* This coding avoids hardwiring any assumptions about the width of
|
|
|
|
* pg_time_t, so it should behave sanely on machines without int64.
|
|
|
|
*/
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
dt = (dt - *fsec) / USECS_PER_SEC +
|
2005-05-23 23:54:02 +02:00
|
|
|
(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2004-06-03 04:08:07 +02:00
|
|
|
dt = rint(dt - *fsec +
|
2005-05-23 23:54:02 +02:00
|
|
|
(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2004-06-03 04:08:07 +02:00
|
|
|
utime = (pg_time_t) dt;
|
|
|
|
if ((Timestamp) utime == dt)
|
|
|
|
{
|
2005-07-22 05:46:34 +02:00
|
|
|
struct pg_tm *tx = pg_localtime(&utime, (attimezone != NULL) ?
|
|
|
|
attimezone : global_timezone);
|
2004-06-03 04:08:07 +02:00
|
|
|
|
|
|
|
tm->tm_year = tx->tm_year + 1900;
|
|
|
|
tm->tm_mon = tx->tm_mon + 1;
|
|
|
|
tm->tm_mday = tx->tm_mday;
|
|
|
|
tm->tm_hour = tx->tm_hour;
|
|
|
|
tm->tm_min = tx->tm_min;
|
|
|
|
tm->tm_sec = tx->tm_sec;
|
|
|
|
tm->tm_isdst = tx->tm_isdst;
|
|
|
|
tm->tm_gmtoff = tx->tm_gmtoff;
|
|
|
|
tm->tm_zone = tx->tm_zone;
|
2005-07-22 21:00:55 +02:00
|
|
|
*tzp = -tm->tm_gmtoff;
|
2004-06-03 04:08:07 +02:00
|
|
|
if (tzn != NULL)
|
|
|
|
*tzn = (char *) tm->tm_zone;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-06-03 04:08:07 +02:00
|
|
|
/*
|
|
|
|
* When out of range of pg_time_t, treat as GMT
|
|
|
|
*/
|
|
|
|
*tzp = 0;
|
|
|
|
/* Mark this as *no* time zone available */
|
2001-10-20 03:02:22 +02:00
|
|
|
tm->tm_isdst = -1;
|
2004-06-03 04:08:07 +02:00
|
|
|
tm->tm_gmtoff = 0;
|
|
|
|
tm->tm_zone = NULL;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
if (tzn != NULL)
|
|
|
|
*tzn = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2003-07-27 06:53:12 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* tm2timestamp()
|
|
|
|
* Convert a tm structure to a timestamp data type.
|
|
|
|
* Note that year is _not_ 1900-based, but is an explicit full value.
|
|
|
|
* Also, month is one-based, _not_ zero-based.
|
2003-07-04 20:21:14 +02:00
|
|
|
*
|
2003-07-27 06:53:12 +02:00
|
|
|
* Returns -1 on failure (value out of range).
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
|
|
|
int
|
2005-07-20 18:42:32 +02:00
|
|
|
tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2004-08-30 04:54:42 +02:00
|
|
|
int date;
|
2002-09-04 22:31:48 +02:00
|
|
|
int64 time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2004-08-30 04:54:42 +02:00
|
|
|
double date,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* Julian day routines are not correct for negative Julian days */
|
|
|
|
if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
|
|
|
|
return -1;
|
|
|
|
|
2003-04-04 06:50:44 +02:00
|
|
|
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
2002-04-21 21:52:18 +02:00
|
|
|
time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
|
2005-07-22 23:16:15 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
*result = date * USECS_PER_DAY + time;
|
2003-07-04 20:21:14 +02:00
|
|
|
/* check for major overflow */
|
2005-05-23 20:56:55 +02:00
|
|
|
if ((*result - time) / USECS_PER_DAY != date)
|
2003-07-04 20:21:14 +02:00
|
|
|
return -1;
|
|
|
|
/* check for just-barely overflow (okay except time-of-day wraps) */
|
2005-05-23 19:13:14 +02:00
|
|
|
if ((*result < 0 && date >= 0) ||
|
|
|
|
(*result >= 0 && date < 0))
|
2003-07-04 20:21:14 +02:00
|
|
|
return -1;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 23:54:02 +02:00
|
|
|
*result = date * SECS_PER_DAY + time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
if (tzp != NULL)
|
|
|
|
*result = dt2local(*result, -(*tzp));
|
|
|
|
|
|
|
|
return 0;
|
2003-07-27 06:53:12 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* interval2tm()
|
|
|
|
* Convert a interval data type to a tm structure.
|
|
|
|
*/
|
2001-09-06 05:22:42 +02:00
|
|
|
int
|
2005-07-20 18:42:32 +02:00
|
|
|
interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 time;
|
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
double time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_year = span.month / MONTHS_PER_YEAR;
|
|
|
|
tm->tm_mon = span.month % MONTHS_PER_YEAR;
|
2005-07-20 18:42:32 +02:00
|
|
|
tm->tm_mday = span.day;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
time = span.time;
|
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 06:41:43 +02:00
|
|
|
tm->tm_hour = time / USECS_PER_HOUR;
|
|
|
|
time -= tm->tm_hour * USECS_PER_HOUR;
|
|
|
|
tm->tm_min = time / USECS_PER_MINUTE;
|
|
|
|
time -= tm->tm_min * USECS_PER_MINUTE;
|
|
|
|
tm->tm_sec = time / USECS_PER_SEC;
|
|
|
|
*fsec = time - (tm->tm_sec * USECS_PER_SEC);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
TMODULO(time, tm->tm_hour, (double)SECS_PER_HOUR);
|
|
|
|
TMODULO(time, tm->tm_min, (double)SECS_PER_MINUTE);
|
2005-07-12 17:17:44 +02:00
|
|
|
TMODULO(time, tm->tm_sec, 1.0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*fsec = time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
return 0;
|
2003-07-27 06:53:12 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-06 05:22:42 +02:00
|
|
|
int
|
2005-07-20 18:42:32 +02:00
|
|
|
tm2interval(struct pg_tm *tm, fsec_t fsec, Interval *span)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
span->month = tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon;
|
2005-07-20 18:42:32 +02:00
|
|
|
span->day = tm->tm_mday;
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 07:18:26 +02:00
|
|
|
span->time = (((((tm->tm_hour * INT64CONST(60)) +
|
|
|
|
tm->tm_min) * INT64CONST(60)) +
|
2005-05-24 04:09:45 +02:00
|
|
|
tm->tm_sec) * USECS_PER_SEC) + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 20:06:13 +02:00
|
|
|
span->time = (((tm->tm_hour * (double)MINS_PER_HOUR) +
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_min) * (double)SECS_PER_MINUTE) +
|
2005-05-24 04:09:45 +02:00
|
|
|
tm->tm_sec;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
span->time = JROUND(span->time + fsec);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
return 0;
|
2003-07-27 06:53:12 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
static int64
|
|
|
|
time2t(const int hour, const int min, const int sec, const fsec_t fsec)
|
|
|
|
{
|
2005-07-21 20:06:13 +02:00
|
|
|
return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
} /* time2t() */
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
static double
|
2002-04-21 21:52:18 +02:00
|
|
|
time2t(const int hour, const int min, const int sec, const fsec_t fsec)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 20:06:13 +02:00
|
|
|
return (((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec + fsec;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
} /* time2t() */
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 00:38:00 +02:00
|
|
|
static Timestamp
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
dt2local(Timestamp dt, int tz)
|
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
dt -= (tz * USECS_PER_SEC);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
dt -= tz;
|
|
|
|
dt = JROUND(dt);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
return dt;
|
|
|
|
} /* dt2local() */
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* PUBLIC ROUTINES *
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_finite(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
PG_RETURN_BOOL(!TIMESTAMP_NOT_FINITE(timestamp));
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_finite(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_BOOL(true);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Relational operators for timestamp.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
void
|
2005-07-20 18:42:32 +02:00
|
|
|
GetEpochTime(struct pg_tm *tm)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm *t0;
|
|
|
|
pg_time_t epoch = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-05-21 07:08:06 +02:00
|
|
|
t0 = pg_gmtime(&epoch);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
tm->tm_year = t0->tm_year;
|
|
|
|
tm->tm_mon = t0->tm_mon;
|
|
|
|
tm->tm_mday = t0->tm_mday;
|
|
|
|
tm->tm_hour = t0->tm_hour;
|
|
|
|
tm->tm_min = t0->tm_min;
|
|
|
|
tm->tm_sec = t0->tm_sec;
|
|
|
|
|
2004-06-03 04:08:07 +02:00
|
|
|
tm->tm_year += 1900;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_mon++;
|
2004-06-03 04:08:07 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
Timestamp
|
2001-09-28 10:09:14 +02:00
|
|
|
SetEpochTimestamp(void)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
Timestamp dt;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
GetEpochTime(tm);
|
2003-07-27 06:53:12 +02:00
|
|
|
/* we don't bother to test for failure ... */
|
2001-09-28 10:09:14 +02:00
|
|
|
tm2timestamp(tm, 0, NULL, &dt);
|
1997-03-14 06:58:13 +01:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
return dt;
|
2001-09-28 10:09:14 +02:00
|
|
|
} /* SetEpochTimestamp() */
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
/*
|
2003-08-08 02:10:31 +02:00
|
|
|
* We are currently sharing some code between timestamp and timestamptz.
|
|
|
|
* The comparison functions are among them. - thomas 2001-09-25
|
|
|
|
*
|
2000-06-09 03:11:16 +02:00
|
|
|
* timestamp_relop - is timestamp1 relop timestamp2
|
2001-05-03 21:00:37 +02:00
|
|
|
*
|
|
|
|
* collate invalid timestamp at the end
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
2004-02-14 21:16:18 +01:00
|
|
|
int
|
2001-05-03 21:00:37 +02:00
|
|
|
timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
|
|
|
|
{
|
2003-08-08 02:10:31 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-24 04:09:45 +02:00
|
|
|
return (dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0);
|
2003-08-08 02:10:31 +02:00
|
|
|
#else
|
2003-08-08 23:42:59 +02:00
|
|
|
|
2003-08-08 02:10:31 +02:00
|
|
|
/*
|
|
|
|
* When using float representation, we have to be wary of NaNs.
|
|
|
|
*
|
2003-08-08 23:42:59 +02:00
|
|
|
* We consider all NANs to be equal and larger than any non-NAN. This is
|
|
|
|
* somewhat arbitrary; the important thing is to have a consistent
|
2003-08-08 02:10:31 +02:00
|
|
|
* sort order.
|
|
|
|
*/
|
|
|
|
if (isnan(dt1))
|
|
|
|
{
|
|
|
|
if (isnan(dt2))
|
|
|
|
return 0; /* NAN = NAN */
|
|
|
|
else
|
|
|
|
return 1; /* NAN > non-NAN */
|
|
|
|
}
|
|
|
|
else if (isnan(dt2))
|
|
|
|
{
|
|
|
|
return -1; /* non-NAN < NAN */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (dt1 > dt2)
|
|
|
|
return 1;
|
|
|
|
else if (dt1 < dt2)
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2001-05-03 21:00:37 +02:00
|
|
|
}
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_eq(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_ne(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_lt(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
1997-03-14 06:58:13 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_gt(PG_FUNCTION_ARGS)
|
1997-03-14 06:58:13 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_le(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_ge(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_cmp(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2004-03-22 02:38:18 +01:00
|
|
|
/*
|
|
|
|
* Crosstype comparison functions for timestamp vs timestamptz
|
|
|
|
*/
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_le_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
|
|
|
TimestampTz dt1;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt1 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_le_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
2004-08-29 07:07:03 +02:00
|
|
|
TimestampTz dt2;
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
dt2 = timestamp2timestamptz(timestampVal);
|
|
|
|
|
|
|
|
PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
/*
|
|
|
|
* interval_relop - is interval1 relop interval2
|
2001-05-03 21:00:37 +02:00
|
|
|
*
|
|
|
|
* collate invalid interval at the end
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
2001-05-03 21:00:37 +02:00
|
|
|
static int
|
|
|
|
interval_cmp_internal(Interval *interval1, Interval *interval2)
|
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
int64 span1,
|
|
|
|
span2;
|
|
|
|
#else
|
2001-09-28 10:09:14 +02:00
|
|
|
double span1,
|
|
|
|
span2;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-05-03 21:00:37 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
span1 = interval1->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
span2 = interval2->time;
|
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 07:18:26 +02:00
|
|
|
span1 += interval1->month * INT64CONST(30) * USECS_PER_DAY;
|
|
|
|
span1 += interval1->day * INT64CONST(24) * USECS_PER_HOUR;
|
|
|
|
span2 += interval2->month * INT64CONST(30) * USECS_PER_DAY;
|
|
|
|
span2 += interval2->day * INT64CONST(24) * USECS_PER_HOUR;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
span1 += interval1->month * ((double)DAYS_PER_MONTH * SECS_PER_DAY);
|
|
|
|
span1 += interval1->day * ((double)HOURS_PER_DAY * SECS_PER_HOUR);
|
|
|
|
span2 += interval2->month * ((double)DAYS_PER_MONTH * SECS_PER_DAY);
|
|
|
|
span2 += interval2->day * ((double)HOURS_PER_DAY * SECS_PER_HOUR);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-05-03 21:00:37 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);
|
2001-05-03 21:00:37 +02:00
|
|
|
}
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_eq(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_ne(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_lt(PG_FUNCTION_ARGS)
|
From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
Subject: [HACKERS] More date time functions
Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).
I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.
These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).
The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
1997-04-02 20:36:24 +02:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_gt(PG_FUNCTION_ARGS)
|
1997-10-25 07:22:58 +02:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_le(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_ge(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_cmp(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-05-03 21:00:37 +02:00
|
|
|
PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-19 05:55:01 +02:00
|
|
|
/*
|
|
|
|
* interval, being an unusual size, needs a specialized hash function.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_hash(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *key = PG_GETARG_INTERVAL_P(0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Specify hash length as sizeof(double) + sizeof(int4), not as
|
|
|
|
* sizeof(Interval), so that any garbage pad bytes in the structure
|
|
|
|
* won't be included in the hash!
|
|
|
|
*/
|
2005-07-20 18:42:32 +02:00
|
|
|
return hash_any((unsigned char *) key,
|
|
|
|
sizeof(key->time) + sizeof(key->day) + sizeof(key->month));
|
2000-06-19 05:55:01 +02:00
|
|
|
}
|
|
|
|
|
2000-12-07 19:38:59 +01:00
|
|
|
/* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator.
|
|
|
|
*
|
|
|
|
* Algorithm is per SQL92 spec. This is much harder than you'd think
|
|
|
|
* because the spec requires us to deliver a non-null answer in some cases
|
|
|
|
* where some of the inputs are null.
|
2000-03-15 00:06:59 +01:00
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
overlaps_timestamp(PG_FUNCTION_ARGS)
|
2000-03-15 00:06:59 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
|
|
|
* The arguments are Timestamps, but we leave them as generic Datums
|
2000-12-07 19:38:59 +01:00
|
|
|
* to avoid unnecessary conversions between value and reference forms
|
|
|
|
* --- not to mention possible dereferences of null pointers.
|
2000-06-09 03:11:16 +02:00
|
|
|
*/
|
|
|
|
Datum ts1 = PG_GETARG_DATUM(0);
|
|
|
|
Datum te1 = PG_GETARG_DATUM(1);
|
|
|
|
Datum ts2 = PG_GETARG_DATUM(2);
|
|
|
|
Datum te2 = PG_GETARG_DATUM(3);
|
2000-12-07 19:38:59 +01:00
|
|
|
bool ts1IsNull = PG_ARGISNULL(0);
|
|
|
|
bool te1IsNull = PG_ARGISNULL(1);
|
|
|
|
bool ts2IsNull = PG_ARGISNULL(2);
|
|
|
|
bool te2IsNull = PG_ARGISNULL(3);
|
2000-06-09 03:11:16 +02:00
|
|
|
|
|
|
|
#define TIMESTAMP_GT(t1,t2) \
|
|
|
|
DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
|
|
|
|
#define TIMESTAMP_LT(t1,t2) \
|
|
|
|
DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
|
|
|
|
|
2000-12-07 19:38:59 +01:00
|
|
|
/*
|
2001-03-22 05:01:46 +01:00
|
|
|
* If both endpoints of interval 1 are null, the result is null
|
|
|
|
* (unknown). If just one endpoint is null, take ts1 as the non-null
|
|
|
|
* one. Otherwise, take ts1 as the lesser endpoint.
|
2000-12-07 19:38:59 +01:00
|
|
|
*/
|
|
|
|
if (ts1IsNull)
|
2000-03-15 00:06:59 +01:00
|
|
|
{
|
2000-12-07 19:38:59 +01:00
|
|
|
if (te1IsNull)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
/* swap null for non-null */
|
2000-03-15 00:06:59 +01:00
|
|
|
ts1 = te1;
|
2000-12-07 19:38:59 +01:00
|
|
|
te1IsNull = true;
|
2000-03-15 00:06:59 +01:00
|
|
|
}
|
2000-12-07 19:38:59 +01:00
|
|
|
else if (!te1IsNull)
|
2000-03-15 00:06:59 +01:00
|
|
|
{
|
2000-12-07 19:38:59 +01:00
|
|
|
if (TIMESTAMP_GT(ts1, te1))
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
Datum tt = ts1;
|
2000-04-12 19:17:23 +02:00
|
|
|
|
2000-12-07 19:38:59 +01:00
|
|
|
ts1 = te1;
|
|
|
|
te1 = tt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Likewise for interval 2. */
|
|
|
|
if (ts2IsNull)
|
|
|
|
{
|
|
|
|
if (te2IsNull)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
/* swap null for non-null */
|
2000-03-15 00:06:59 +01:00
|
|
|
ts2 = te2;
|
2000-12-07 19:38:59 +01:00
|
|
|
te2IsNull = true;
|
2000-03-15 00:06:59 +01:00
|
|
|
}
|
2000-12-07 19:38:59 +01:00
|
|
|
else if (!te2IsNull)
|
|
|
|
{
|
|
|
|
if (TIMESTAMP_GT(ts2, te2))
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
Datum tt = ts2;
|
2000-03-15 00:06:59 +01:00
|
|
|
|
2000-12-07 19:38:59 +01:00
|
|
|
ts2 = te2;
|
|
|
|
te2 = tt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* At this point neither ts1 nor ts2 is null, so we can consider three
|
|
|
|
* cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
|
|
|
|
*/
|
|
|
|
if (TIMESTAMP_GT(ts1, ts2))
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
|
|
|
* This case is ts1 < te2 OR te1 < te2, which may look redundant
|
2000-12-07 19:38:59 +01:00
|
|
|
* but in the presence of nulls it's not quite completely so.
|
|
|
|
*/
|
|
|
|
if (te2IsNull)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
if (TIMESTAMP_LT(ts1, te2))
|
|
|
|
PG_RETURN_BOOL(true);
|
|
|
|
if (te1IsNull)
|
|
|
|
PG_RETURN_NULL();
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If te1 is not null then we had ts1 <= te1 above, and we just
|
2000-12-07 19:38:59 +01:00
|
|
|
* found ts1 >= te2, hence te1 >= te2.
|
|
|
|
*/
|
|
|
|
PG_RETURN_BOOL(false);
|
|
|
|
}
|
|
|
|
else if (TIMESTAMP_LT(ts1, ts2))
|
|
|
|
{
|
|
|
|
/* This case is ts2 < te1 OR te2 < te1 */
|
|
|
|
if (te1IsNull)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
if (TIMESTAMP_LT(ts2, te1))
|
|
|
|
PG_RETURN_BOOL(true);
|
|
|
|
if (te2IsNull)
|
|
|
|
PG_RETURN_NULL();
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If te2 is not null then we had ts2 <= te2 above, and we just
|
2000-12-07 19:38:59 +01:00
|
|
|
* found ts2 >= te1, hence te2 >= te1.
|
|
|
|
*/
|
|
|
|
PG_RETURN_BOOL(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
|
|
|
* For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
|
|
|
|
* rather silly way of saying "true if both are nonnull, else
|
|
|
|
* null".
|
2000-12-07 19:38:59 +01:00
|
|
|
*/
|
|
|
|
if (te1IsNull || te2IsNull)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
PG_RETURN_BOOL(true);
|
|
|
|
}
|
2000-06-09 03:11:16 +02:00
|
|
|
|
|
|
|
#undef TIMESTAMP_GT
|
|
|
|
#undef TIMESTAMP_LT
|
|
|
|
}
|
2000-03-15 00:06:59 +01:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* "Arithmetic" operators on date/times.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_smaller(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
|
|
|
Timestamp result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2003-08-08 02:10:31 +02:00
|
|
|
/* use timestamp_cmp_internal to be sure this agrees with comparisons */
|
|
|
|
if (timestamp_cmp_internal(dt1, dt2) < 0)
|
|
|
|
result = dt1;
|
|
|
|
else
|
|
|
|
result = dt2;
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_larger(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
|
|
|
Timestamp result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2003-08-08 02:10:31 +02:00
|
|
|
if (timestamp_cmp_internal(dt1, dt2) > 0)
|
|
|
|
result = dt1;
|
|
|
|
else
|
|
|
|
result = dt2;
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_mi(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2))
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("cannot subtract infinite timestamps")));
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
result->time = 0;
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 06:41:43 +02:00
|
|
|
result->time = dt1 - dt2;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
result->time = JROUND(dt1 - dt2);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
result->month = 0;
|
2005-07-20 18:42:32 +02:00
|
|
|
result->day = 0;
|
|
|
|
|
|
|
|
result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
|
|
|
|
IntervalPGetDatum(result)));
|
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* interval_justify_hours()
|
|
|
|
* Adjust interval so 'time' contains less than a whole day, and
|
|
|
|
* 'day' contains an integral number of days. This is useful for
|
|
|
|
* situations (such as non-TZ) where '1 day' = '24 hours' is valid,
|
|
|
|
* e.g. interval subtraction and division. The SQL standard requires
|
|
|
|
* such conversion in these cases, but not the conversion of days to months.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_justify_hours(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *result;
|
|
|
|
|
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
|
|
|
result->month = span->month;
|
|
|
|
result->time = span->time;
|
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
result->time += span->day * USECS_PER_DAY;
|
|
|
|
result->day = result->time / USECS_PER_DAY;
|
|
|
|
result->time -= result->day * USECS_PER_DAY;
|
|
|
|
#else
|
|
|
|
result->time += span->day * (double)SECS_PER_DAY;
|
|
|
|
TMODULO(result->time, result->day, (double)SECS_PER_DAY);
|
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-20 18:42:32 +02:00
|
|
|
/* interval_justify_days()
|
|
|
|
* Adjust interval so 'time' contains less than 30 days, and
|
|
|
|
* adds as months.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
interval_justify_days(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *result;
|
|
|
|
|
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
|
|
|
result->day = span->day;
|
|
|
|
result->time = span->time;
|
|
|
|
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 05:56:25 +02:00
|
|
|
result->day += span->month * (double)DAYS_PER_MONTH;
|
|
|
|
result->month = span->day / DAYS_PER_MONTH;
|
|
|
|
result->day -= result->month * DAYS_PER_MONTH;
|
2005-07-20 18:42:32 +02:00
|
|
|
#else
|
2005-07-21 05:56:25 +02:00
|
|
|
result->day += span->month * (double)DAYS_PER_MONTH;
|
|
|
|
TMODULO(result->day, result->month, (double)DAYS_PER_MONTH);
|
2005-07-20 18:42:32 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-02-14 21:16:18 +01:00
|
|
|
/* timestamp_pl_interval()
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Add a interval to a timestamp data type.
|
2005-07-20 18:42:32 +02:00
|
|
|
* Note that interval has provisions for qualitative year/month and day
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* units, so try to do the right thing with them.
|
|
|
|
* To add a month, increment the month, and use the same day of month.
|
|
|
|
* Then, if the next month has fewer days, set the day of month
|
|
|
|
* to the last day of month.
|
2005-07-20 18:42:32 +02:00
|
|
|
* To add a day, increment the mday, and use the same time of day.
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
* Lastly, add in the "quantitative time".
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
2004-02-14 21:16:18 +01:00
|
|
|
timestamp_pl_interval(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(1);
|
|
|
|
Timestamp result;
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
result = timestamp;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (span->month != 0)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
|
|
|
tm->tm_mon += span->month;
|
2005-07-21 05:56:25 +02:00
|
|
|
if (tm->tm_mon > MONTHS_PER_YEAR)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
|
|
|
|
tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
2003-07-27 06:53:12 +02:00
|
|
|
else if (tm->tm_mon < 1)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
|
|
|
|
tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
2003-07-27 06:53:12 +02:00
|
|
|
|
|
|
|
/* adjust for end of month boundary problems... */
|
|
|
|
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
|
|
|
tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
|
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (tm2timestamp(tm, fsec, NULL, ×tamp) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
|
2005-07-20 18:42:32 +02:00
|
|
|
if (span->day != 0)
|
|
|
|
{
|
|
|
|
struct pg_tm tt,
|
|
|
|
*tm = &tt;
|
|
|
|
fsec_t fsec;
|
|
|
|
int julian;
|
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2005-07-20 18:42:32 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
|
|
|
/* Add days by converting to and from julian */
|
|
|
|
julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day;
|
|
|
|
j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (tm2timestamp(tm, fsec, NULL, ×tamp) != 0)
|
2005-07-20 18:42:32 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
}
|
|
|
|
|
|
|
|
timestamp += span->time;
|
2001-09-28 10:09:14 +02:00
|
|
|
result = timestamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
2004-02-14 21:16:18 +01:00
|
|
|
timestamp_mi_interval(PG_FUNCTION_ARGS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(1);
|
|
|
|
Interval tspan;
|
|
|
|
|
|
|
|
tspan.month = -span->month;
|
2005-07-20 18:42:32 +02:00
|
|
|
tspan.day = -span->day;
|
2001-09-28 10:09:14 +02:00
|
|
|
tspan.time = -span->time;
|
|
|
|
|
2004-02-14 21:16:18 +01:00
|
|
|
return DirectFunctionCall2(timestamp_pl_interval,
|
2001-09-28 10:09:14 +02:00
|
|
|
TimestampGetDatum(timestamp),
|
|
|
|
PointerGetDatum(&tspan));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-14 21:16:18 +01:00
|
|
|
/* timestamptz_pl_interval()
|
2001-09-28 10:09:14 +02:00
|
|
|
* Add a interval to a timestamp with time zone data type.
|
|
|
|
* Note that interval has provisions for qualitative year/month
|
|
|
|
* units, so try to do the right thing with them.
|
|
|
|
* To add a month, increment the month, and use the same day of month.
|
|
|
|
* Then, if the next month has fewer days, set the day of month
|
|
|
|
* to the last day of month.
|
|
|
|
* Lastly, add in the "quantitative time".
|
|
|
|
*/
|
|
|
|
Datum
|
2004-02-14 21:16:18 +01:00
|
|
|
timestamptz_pl_interval(PG_FUNCTION_ARGS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(1);
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int tz;
|
|
|
|
char *tzn;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
result = timestamp;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (span->month != 0)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2000-11-06 16:57:00 +01:00
|
|
|
|
2003-07-27 06:53:12 +02:00
|
|
|
tm->tm_mon += span->month;
|
2005-07-21 05:56:25 +02:00
|
|
|
if (tm->tm_mon > MONTHS_PER_YEAR)
|
2003-07-27 06:53:12 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
|
|
|
|
tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
2003-07-27 06:53:12 +02:00
|
|
|
else if (tm->tm_mon < 1)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
|
|
|
|
tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
2003-07-27 06:53:12 +02:00
|
|
|
|
|
|
|
/* adjust for end of month boundary problems... */
|
|
|
|
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
|
|
|
tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
|
|
|
|
|
2005-07-23 16:25:34 +02:00
|
|
|
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2005-07-20 18:42:32 +02:00
|
|
|
if (span->day != 0)
|
|
|
|
{
|
|
|
|
struct pg_tm tt,
|
|
|
|
*tm = &tt;
|
|
|
|
fsec_t fsec;
|
|
|
|
int julian;
|
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2005-07-20 18:42:32 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
|
|
|
/* Add days by converting to and from julian */
|
|
|
|
julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day;
|
|
|
|
j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
|
|
|
|
2005-07-23 16:25:34 +02:00
|
|
|
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
2005-07-20 18:42:32 +02:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0)
|
2005-07-20 18:42:32 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
}
|
|
|
|
|
|
|
|
timestamp += span->time;
|
2001-09-28 10:09:14 +02:00
|
|
|
result = timestamp;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
2004-02-14 21:16:18 +01:00
|
|
|
timestamptz_mi_interval(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval tspan;
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
tspan.month = -span->month;
|
2005-07-20 18:42:32 +02:00
|
|
|
tspan.day = -span->day;
|
2001-03-22 05:01:46 +01:00
|
|
|
tspan.time = -span->time;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-02-14 21:16:18 +01:00
|
|
|
return DirectFunctionCall2(timestamptz_pl_interval,
|
2000-06-09 03:11:16 +02:00
|
|
|
TimestampGetDatum(timestamp),
|
|
|
|
PointerGetDatum(&tspan));
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_um(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
result->time = -interval->time;
|
|
|
|
result->day = -interval->day;
|
|
|
|
result->month = -interval->month;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_smaller(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2003-08-08 02:10:31 +02:00
|
|
|
/* use interval_cmp_internal to be sure this agrees with comparisons */
|
|
|
|
if (interval_cmp_internal(interval1, interval2) < 0)
|
|
|
|
result = interval1;
|
2001-09-28 10:09:14 +02:00
|
|
|
else
|
2003-08-08 02:10:31 +02:00
|
|
|
result = interval2;
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_larger(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *interval2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2003-08-08 02:10:31 +02:00
|
|
|
if (interval_cmp_internal(interval1, interval2) > 0)
|
|
|
|
result = interval1;
|
2001-09-28 10:09:14 +02:00
|
|
|
else
|
2003-08-08 02:10:31 +02:00
|
|
|
result = interval2;
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_pl(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *span1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *span2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
result->month = span1->month + span2->month;
|
|
|
|
result->day = span1->day + span2->day;
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 06:41:43 +02:00
|
|
|
result->time = span1->time + span2->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
result->time = JROUND(span1->time + span2->time);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_mi(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *span1 = PG_GETARG_INTERVAL_P(0);
|
|
|
|
Interval *span2 = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-21 06:41:43 +02:00
|
|
|
result->month = span1->month - span2->month;
|
|
|
|
result->day = span1->day - span2->day;
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 06:41:43 +02:00
|
|
|
result->time = span1->time - span2->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
result->time = JROUND(span1->time - span2->time);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_mul(PG_FUNCTION_ARGS)
|
2000-04-07 15:40:45 +02:00
|
|
|
{
|
2005-07-24 06:37:07 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(0);
|
2000-06-09 03:11:16 +02:00
|
|
|
float8 factor = PG_GETARG_FLOAT8(1);
|
2005-07-24 06:37:07 +02:00
|
|
|
double month_remainder, day_remainder;
|
2000-04-07 15:40:45 +02:00
|
|
|
Interval *result;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
2000-04-07 15:40:45 +02:00
|
|
|
|
2005-07-24 06:37:07 +02:00
|
|
|
result->month = span->month * factor;
|
|
|
|
result->day = span->day * factor;
|
|
|
|
|
|
|
|
/* Compute remainders */
|
|
|
|
month_remainder = span->month * factor - result->month;
|
|
|
|
day_remainder = span->day * factor - result->day;
|
|
|
|
|
|
|
|
/* Cascade fractions to lower units */
|
|
|
|
/* fractional months full days into days */
|
|
|
|
result->day += month_remainder * DAYS_PER_MONTH;
|
|
|
|
/* fractional months partial days into time */
|
|
|
|
day_remainder += (month_remainder * DAYS_PER_MONTH) -
|
|
|
|
(int)(month_remainder * DAYS_PER_MONTH);
|
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-24 06:37:07 +02:00
|
|
|
result->time = rint(span->time * factor +
|
|
|
|
day_remainder * USECS_PER_DAY);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-24 06:37:07 +02:00
|
|
|
result->time = JROUND(span->time * factor +
|
|
|
|
day_remainder * SECS_PER_DAY);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2000-04-07 15:40:45 +02:00
|
|
|
|
2005-07-24 06:37:07 +02:00
|
|
|
result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
|
|
|
|
IntervalPGetDatum(result)));
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
2000-04-07 15:40:45 +02:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
mul_d_interval(PG_FUNCTION_ARGS)
|
2000-04-07 15:40:45 +02:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
/* Args are float8 and Interval *, but leave them as generic Datum */
|
|
|
|
Datum factor = PG_GETARG_DATUM(0);
|
2005-07-24 06:37:07 +02:00
|
|
|
Datum span = PG_GETARG_DATUM(1);
|
2000-04-07 15:40:45 +02:00
|
|
|
|
2005-07-24 06:37:07 +02:00
|
|
|
return DirectFunctionCall2(interval_mul, span, factor);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
interval_div(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
Interval *span = PG_GETARG_INTERVAL_P(0);
|
2000-06-09 03:11:16 +02:00
|
|
|
float8 factor = PG_GETARG_FLOAT8(1);
|
2005-07-20 18:42:32 +02:00
|
|
|
double month_remainder, day_remainder;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (factor == 0.0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-20 18:42:32 +02:00
|
|
|
result->month = span->month / factor;
|
|
|
|
result->day = span->day / factor;
|
|
|
|
result->time = span->time / factor;
|
|
|
|
|
2005-07-23 16:53:21 +02:00
|
|
|
/* Compute remainders */
|
|
|
|
month_remainder = span->month / factor - result->month;
|
|
|
|
day_remainder = span->day / factor - result->day;
|
2005-07-20 18:42:32 +02:00
|
|
|
|
|
|
|
/* Cascade fractions to lower units */
|
|
|
|
/* fractional months full days into days */
|
2005-07-21 05:56:25 +02:00
|
|
|
result->day += month_remainder * DAYS_PER_MONTH;
|
2005-07-20 18:42:32 +02:00
|
|
|
/* fractional months partial days into time */
|
2005-07-24 06:37:07 +02:00
|
|
|
day_remainder += (month_remainder * DAYS_PER_MONTH) -
|
|
|
|
(int)(month_remainder * DAYS_PER_MONTH);
|
2005-07-20 18:42:32 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-24 06:37:07 +02:00
|
|
|
result->time += rint(day_remainder * USECS_PER_DAY);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-20 18:42:32 +02:00
|
|
|
result->time += day_remainder * SECS_PER_DAY;
|
|
|
|
result->time = JROUND(result->time);
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-20 18:42:32 +02:00
|
|
|
result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
|
|
|
|
IntervalPGetDatum(result)));
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-07-17 05:05:41 +02:00
|
|
|
/*
|
|
|
|
* interval_accum and interval_avg implement the AVG(interval) aggregate.
|
|
|
|
*
|
|
|
|
* The transition datatype for this aggregate is a 2-element array of
|
|
|
|
* intervals, where the first is the running sum and the second contains
|
|
|
|
* the number of values so far in its 'time' field. This is a bit ugly
|
|
|
|
* but it beats inventing a specialized datatype for the purpose.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Datum
|
|
|
|
interval_accum(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
Interval *newval = PG_GETARG_INTERVAL_P(1);
|
|
|
|
Datum *transdatums;
|
|
|
|
int ndatums;
|
|
|
|
Interval sumX,
|
|
|
|
N;
|
|
|
|
Interval *newsum;
|
|
|
|
ArrayType *result;
|
|
|
|
|
|
|
|
deconstruct_array(transarray,
|
2005-07-20 18:42:32 +02:00
|
|
|
INTERVALOID, sizeof(Interval), false, 'd',
|
2000-07-17 05:05:41 +02:00
|
|
|
&transdatums, &ndatums);
|
|
|
|
if (ndatums != 2)
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "expected 2-element interval array");
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-07-17 05:05:41 +02:00
|
|
|
/*
|
|
|
|
* XXX memcpy, instead of just extracting a pointer, to work around
|
|
|
|
* buggy array code: it won't ensure proper alignment of Interval
|
2001-03-22 05:01:46 +01:00
|
|
|
* objects on machines where double requires 8-byte alignment. That
|
|
|
|
* should be fixed, but in the meantime...
|
2001-11-21 19:29:48 +01:00
|
|
|
*
|
2002-09-04 22:31:48 +02:00
|
|
|
* Note: must use DatumGetPointer here, not DatumGetIntervalP, else some
|
|
|
|
* compilers optimize into double-aligned load/store anyway.
|
2000-07-17 05:05:41 +02:00
|
|
|
*/
|
2001-11-21 19:29:48 +01:00
|
|
|
memcpy((void *) &sumX, DatumGetPointer(transdatums[0]), sizeof(Interval));
|
|
|
|
memcpy((void *) &N, DatumGetPointer(transdatums[1]), sizeof(Interval));
|
2000-07-17 05:05:41 +02:00
|
|
|
|
|
|
|
newsum = DatumGetIntervalP(DirectFunctionCall2(interval_pl,
|
2001-10-25 07:50:21 +02:00
|
|
|
IntervalPGetDatum(&sumX),
|
|
|
|
IntervalPGetDatum(newval)));
|
2000-07-17 05:05:41 +02:00
|
|
|
N.time += 1;
|
|
|
|
|
|
|
|
transdatums[0] = IntervalPGetDatum(newsum);
|
|
|
|
transdatums[1] = IntervalPGetDatum(&N);
|
|
|
|
|
|
|
|
result = construct_array(transdatums, 2,
|
2005-07-20 18:42:32 +02:00
|
|
|
INTERVALOID, sizeof(Interval), false, 'd');
|
2000-07-17 05:05:41 +02:00
|
|
|
|
|
|
|
PG_RETURN_ARRAYTYPE_P(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
interval_avg(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
Datum *transdatums;
|
|
|
|
int ndatums;
|
|
|
|
Interval sumX,
|
|
|
|
N;
|
|
|
|
|
|
|
|
deconstruct_array(transarray,
|
2005-07-20 18:42:32 +02:00
|
|
|
INTERVALOID, sizeof(Interval), false, 'd',
|
2000-07-17 05:05:41 +02:00
|
|
|
&transdatums, &ndatums);
|
|
|
|
if (ndatums != 2)
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "expected 2-element interval array");
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-07-17 05:05:41 +02:00
|
|
|
/*
|
|
|
|
* XXX memcpy, instead of just extracting a pointer, to work around
|
|
|
|
* buggy array code: it won't ensure proper alignment of Interval
|
2001-03-22 05:01:46 +01:00
|
|
|
* objects on machines where double requires 8-byte alignment. That
|
|
|
|
* should be fixed, but in the meantime...
|
2001-11-21 19:29:48 +01:00
|
|
|
*
|
2002-09-04 22:31:48 +02:00
|
|
|
* Note: must use DatumGetPointer here, not DatumGetIntervalP, else some
|
|
|
|
* compilers optimize into double-aligned load/store anyway.
|
2000-07-17 05:05:41 +02:00
|
|
|
*/
|
2001-11-21 19:29:48 +01:00
|
|
|
memcpy((void *) &sumX, DatumGetPointer(transdatums[0]), sizeof(Interval));
|
|
|
|
memcpy((void *) &N, DatumGetPointer(transdatums[1]), sizeof(Interval));
|
2000-07-17 05:05:41 +02:00
|
|
|
|
|
|
|
/* SQL92 defines AVG of no values to be NULL */
|
|
|
|
if (N.time == 0)
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
|
|
|
|
return DirectFunctionCall2(interval_div,
|
|
|
|
IntervalPGetDatum(&sumX),
|
|
|
|
Float8GetDatum(N.time));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/* timestamp_age()
|
|
|
|
* Calculate time difference while retaining year/month fields.
|
|
|
|
* Note that this does not result in an accurate absolute time span
|
|
|
|
* since year and month are out of context once the arithmetic
|
|
|
|
* is done.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_age(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
|
|
|
|
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
fsec1,
|
|
|
|
fsec2;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt1,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm1 = &tt1;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt2,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm2 = &tt2;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
|
|
|
|
timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
|
|
|
fsec = (fsec1 - fsec2);
|
2005-05-24 04:09:45 +02:00
|
|
|
tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
|
|
|
|
tm->tm_min = tm1->tm_min - tm2->tm_min;
|
|
|
|
tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
|
|
|
|
tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
|
|
|
|
tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
|
|
|
|
tm->tm_year = tm1->tm_year - tm2->tm_year;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* flip sign if necessary... */
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
fsec = -fsec;
|
|
|
|
tm->tm_sec = -tm->tm_sec;
|
|
|
|
tm->tm_min = -tm->tm_min;
|
|
|
|
tm->tm_hour = -tm->tm_hour;
|
|
|
|
tm->tm_mday = -tm->tm_mday;
|
|
|
|
tm->tm_mon = -tm->tm_mon;
|
|
|
|
tm->tm_year = -tm->tm_year;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_sec < 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_sec += SECS_PER_MINUTE;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_min--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_min < 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 20:06:13 +02:00
|
|
|
tm->tm_min += MINS_PER_HOUR;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_hour--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_hour < 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_hour += HOURS_PER_DAY;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_mday--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_mday < 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
|
|
|
|
tm->tm_mon--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
|
|
|
|
tm->tm_mon--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_mon < 0)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_mon += MONTHS_PER_YEAR;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_year--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* recover sign if necessary... */
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
fsec = -fsec;
|
|
|
|
tm->tm_sec = -tm->tm_sec;
|
|
|
|
tm->tm_min = -tm->tm_min;
|
|
|
|
tm->tm_hour = -tm->tm_hour;
|
|
|
|
tm->tm_mday = -tm->tm_mday;
|
|
|
|
tm->tm_mon = -tm->tm_mon;
|
|
|
|
tm->tm_year = -tm->tm_year;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tm2interval(tm, fsec, result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("interval out of range")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* timestamptz_age()
|
|
|
|
* Calculate time difference while retaining year/month fields.
|
|
|
|
* Note that this does not result in an accurate absolute time span
|
|
|
|
* since year and month are out of context once the arithmetic
|
|
|
|
* is done.
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
2001-09-28 10:09:14 +02:00
|
|
|
timestamptz_age(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
|
|
|
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
2001-09-28 10:09:14 +02:00
|
|
|
Interval *result;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec,
|
2001-09-28 10:09:14 +02:00
|
|
|
fsec1,
|
|
|
|
fsec2;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt1,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm1 = &tt1;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt2,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm2 = &tt2;
|
2004-12-01 20:57:49 +01:00
|
|
|
int tz1;
|
|
|
|
int tz2;
|
|
|
|
char *tzn;
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
if (timestamp2tm(dt1, &tz1, tm1, &fsec1, &tzn, NULL) == 0 &&
|
|
|
|
timestamp2tm(dt2, &tz2, tm2, &fsec2, &tzn, NULL) == 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-05-24 04:09:45 +02:00
|
|
|
fsec = fsec1 - fsec2;
|
|
|
|
tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
|
|
|
|
tm->tm_min = tm1->tm_min - tm2->tm_min;
|
|
|
|
tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
|
|
|
|
tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
|
|
|
|
tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
|
|
|
|
tm->tm_year = tm1->tm_year - tm2->tm_year;
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
/* flip sign if necessary... */
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
fsec = -fsec;
|
|
|
|
tm->tm_sec = -tm->tm_sec;
|
|
|
|
tm->tm_min = -tm->tm_min;
|
|
|
|
tm->tm_hour = -tm->tm_hour;
|
|
|
|
tm->tm_mday = -tm->tm_mday;
|
|
|
|
tm->tm_mon = -tm->tm_mon;
|
|
|
|
tm->tm_year = -tm->tm_year;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_sec < 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_sec += SECS_PER_MINUTE;
|
2001-09-28 10:09:14 +02:00
|
|
|
tm->tm_min--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_min < 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 20:06:13 +02:00
|
|
|
tm->tm_min += MINS_PER_HOUR;
|
2001-09-28 10:09:14 +02:00
|
|
|
tm->tm_hour--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_hour < 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_hour += HOURS_PER_DAY;
|
2001-09-28 10:09:14 +02:00
|
|
|
tm->tm_mday--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_mday < 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
|
|
|
|
tm->tm_mon--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
|
|
|
|
tm->tm_mon--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
while (tm->tm_mon < 0)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 05:56:25 +02:00
|
|
|
tm->tm_mon += MONTHS_PER_YEAR;
|
2001-09-28 10:09:14 +02:00
|
|
|
tm->tm_year--;
|
|
|
|
}
|
|
|
|
|
2004-12-01 20:57:49 +01:00
|
|
|
/*
|
|
|
|
* Note: we deliberately ignore any difference between tz1 and tz2.
|
|
|
|
*/
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* recover sign if necessary... */
|
|
|
|
if (dt1 < dt2)
|
|
|
|
{
|
|
|
|
fsec = -fsec;
|
|
|
|
tm->tm_sec = -tm->tm_sec;
|
|
|
|
tm->tm_min = -tm->tm_min;
|
|
|
|
tm->tm_hour = -tm->tm_hour;
|
|
|
|
tm->tm_mday = -tm->tm_mday;
|
|
|
|
tm->tm_mon = -tm->tm_mon;
|
|
|
|
tm->tm_year = -tm->tm_year;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tm2interval(tm, fsec, result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("interval out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Conversion operators.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
/* timestamp_text()
|
|
|
|
* Convert timestamp to text data type.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_text(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
/* Input is a Timestamp, but may as well leave it in Datum form */
|
2004-08-30 04:54:42 +02:00
|
|
|
Datum timestamp = PG_GETARG_DATUM(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
text *result;
|
|
|
|
char *str;
|
|
|
|
int len;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
str = DatumGetCString(DirectFunctionCall1(timestamp_out, timestamp));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
len = (strlen(str) + VARHDRSZ);
|
|
|
|
|
|
|
|
result = palloc(len);
|
|
|
|
|
2000-07-04 01:10:14 +02:00
|
|
|
VARATT_SIZEP(result) = len;
|
2005-07-22 23:16:15 +02:00
|
|
|
memmove(VARDATA(result), str, len - VARHDRSZ);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
pfree(str);
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TEXT_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* text_timestamp()
|
|
|
|
* Convert text string to timestamp.
|
|
|
|
* Text type is not null terminated, so use temporary string
|
|
|
|
* then call the standard input routine.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
text_timestamp(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *str = PG_GETARG_TEXT_P(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int i;
|
|
|
|
char *sp,
|
|
|
|
*dp,
|
|
|
|
dstr[MAXDATELEN + 1];
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("invalid input syntax for type timestamp: \"%s\"",
|
2003-07-27 06:53:12 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
2003-08-04 02:43:34 +02:00
|
|
|
PointerGetDatum(str))))));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
sp = VARDATA(str);
|
|
|
|
dp = dstr;
|
2005-07-22 23:16:15 +02:00
|
|
|
for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*dp++ = *sp++;
|
|
|
|
*dp = '\0';
|
|
|
|
|
2001-10-04 16:49:57 +02:00
|
|
|
return DirectFunctionCall3(timestamp_in,
|
|
|
|
CStringGetDatum(dstr),
|
|
|
|
ObjectIdGetDatum(InvalidOid),
|
|
|
|
Int32GetDatum(-1));
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* timestamptz_text()
|
|
|
|
* Convert timestamp with time zone to text data type.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_text(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
/* Input is a Timestamp, but may as well leave it in Datum form */
|
2004-08-30 04:54:42 +02:00
|
|
|
Datum timestamp = PG_GETARG_DATUM(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
text *result;
|
|
|
|
char *str;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
str = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp));
|
|
|
|
|
2005-07-22 23:16:15 +02:00
|
|
|
len = strlen(str) + VARHDRSZ;
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
result = palloc(len);
|
|
|
|
|
|
|
|
VARATT_SIZEP(result) = len;
|
2005-07-22 23:16:15 +02:00
|
|
|
memmove(VARDATA(result), str, len - VARHDRSZ);
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
pfree(str);
|
|
|
|
|
|
|
|
PG_RETURN_TEXT_P(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* text_timestamptz()
|
|
|
|
* Convert text string to timestamp with time zone.
|
|
|
|
* Text type is not null terminated, so use temporary string
|
|
|
|
* then call the standard input routine.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
text_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *str = PG_GETARG_TEXT_P(0);
|
|
|
|
int i;
|
|
|
|
char *sp,
|
|
|
|
*dp,
|
|
|
|
dstr[MAXDATELEN + 1];
|
|
|
|
|
|
|
|
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("invalid input syntax for type timestamp with time zone: \"%s\"",
|
2003-07-27 06:53:12 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
2003-08-04 02:43:34 +02:00
|
|
|
PointerGetDatum(str))))));
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
sp = VARDATA(str);
|
|
|
|
dp = dstr;
|
2005-07-22 23:16:15 +02:00
|
|
|
for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++)
|
2001-09-28 10:09:14 +02:00
|
|
|
*dp++ = *sp++;
|
|
|
|
*dp = '\0';
|
|
|
|
|
2001-10-04 16:49:57 +02:00
|
|
|
return DirectFunctionCall3(timestamptz_in,
|
|
|
|
CStringGetDatum(dstr),
|
|
|
|
ObjectIdGetDatum(InvalidOid),
|
|
|
|
Int32GetDatum(-1));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/* interval_text()
|
|
|
|
* Convert interval to text data type.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_text(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
text *result;
|
|
|
|
char *str;
|
|
|
|
int len;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
str = DatumGetCString(DirectFunctionCall1(interval_out,
|
2001-10-25 07:50:21 +02:00
|
|
|
IntervalPGetDatum(interval)));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-07-22 23:16:15 +02:00
|
|
|
len = strlen(str) + VARHDRSZ;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
result = palloc(len);
|
|
|
|
|
2000-07-04 01:10:14 +02:00
|
|
|
VARATT_SIZEP(result) = len;
|
2005-07-20 18:42:32 +02:00
|
|
|
memmove(VARDATA(result), str, len - VARHDRSZ);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
pfree(str);
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_TEXT_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* text_interval()
|
|
|
|
* Convert text string to interval.
|
|
|
|
* Text type may not be null terminated, so copy to temporary string
|
|
|
|
* then call the standard input routine.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
text_interval(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *str = PG_GETARG_TEXT_P(0);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int i;
|
|
|
|
char *sp,
|
|
|
|
*dp,
|
|
|
|
dstr[MAXDATELEN + 1];
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("invalid input syntax for type interval: \"%s\"",
|
2003-07-27 06:53:12 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
2003-08-04 02:43:34 +02:00
|
|
|
PointerGetDatum(str))))));
|
2003-07-27 06:53:12 +02:00
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
sp = VARDATA(str);
|
|
|
|
dp = dstr;
|
|
|
|
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
|
|
|
|
*dp++ = *sp++;
|
|
|
|
*dp = '\0';
|
|
|
|
|
2001-10-18 19:30:21 +02:00
|
|
|
return DirectFunctionCall3(interval_in,
|
|
|
|
CStringGetDatum(dstr),
|
|
|
|
ObjectIdGetDatum(InvalidOid),
|
|
|
|
Int32GetDatum(-1));
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* timestamp_trunc()
|
2001-09-28 10:09:14 +02:00
|
|
|
* Truncate timestamp to specified units.
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_trunc(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
|
2000-06-09 03:11:16 +02:00
|
|
|
Timestamp result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int type,
|
|
|
|
val;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
PG_RETURN_TIMESTAMP(timestamp);
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
|
|
|
|
2003-07-27 06:53:12 +02:00
|
|
|
if (type == UNITS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
switch (val)
|
|
|
|
{
|
2004-03-05 03:41:14 +01:00
|
|
|
case DTK_WEEK:
|
2005-04-01 16:25:23 +02:00
|
|
|
{
|
|
|
|
int woy;
|
|
|
|
|
|
|
|
woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
|
|
|
/*
|
|
|
|
* If it is week 52/53 and the month is January,
|
|
|
|
* then the week must belong to the previous year.
|
2005-07-04 16:38:31 +02:00
|
|
|
* Also, some December dates belong to the next year.
|
2005-04-01 16:25:23 +02:00
|
|
|
*/
|
|
|
|
if (woy >= 52 && tm->tm_mon == 1)
|
|
|
|
--tm->tm_year;
|
2005-07-21 05:56:25 +02:00
|
|
|
if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
|
2005-07-04 16:38:31 +02:00
|
|
|
++tm->tm_year;
|
2005-04-01 16:25:23 +02:00
|
|
|
isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
2004-03-05 03:41:14 +01:00
|
|
|
tm->tm_hour = 0;
|
|
|
|
tm->tm_min = 0;
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
fsec = 0;
|
|
|
|
break;
|
2005-04-01 16:25:23 +02:00
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MILLENNIUM:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamptz_trunc */
|
|
|
|
if (tm->tm_year > 0)
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_CENTURY:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamptz_trunc */
|
|
|
|
if (tm->tm_year > 0)
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DECADE:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamptz_trunc */
|
|
|
|
if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
|
|
|
|
{
|
|
|
|
if (tm->tm_year > 0)
|
|
|
|
tm->tm_year = (tm->tm_year / 10) * 10;
|
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_YEAR:
|
|
|
|
tm->tm_mon = 1;
|
|
|
|
case DTK_QUARTER:
|
2003-07-26 17:17:36 +02:00
|
|
|
tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MONTH:
|
|
|
|
tm->tm_mday = 1;
|
|
|
|
case DTK_DAY:
|
|
|
|
tm->tm_hour = 0;
|
|
|
|
case DTK_HOUR:
|
|
|
|
tm->tm_min = 0;
|
|
|
|
case DTK_MINUTE:
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
case DTK_SECOND:
|
|
|
|
fsec = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 19:13:14 +02:00
|
|
|
fsec = (fsec / 1000) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2001-09-28 10:09:14 +02:00
|
|
|
fsec = rint(fsec * 1000) / 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifndef HAVE_INT64_TIMESTAMP
|
2001-09-28 10:09:14 +02:00
|
|
|
fsec = rint(fsec * 1000000) / 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("timestamp units \"%s\" not supported",
|
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("timestamp units \"%s\" not recognized",
|
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* timestamptz_trunc()
|
|
|
|
* Truncate timestamp to specified units.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_trunc(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
2001-09-28 10:09:14 +02:00
|
|
|
int tz;
|
|
|
|
int type,
|
|
|
|
val;
|
2004-11-01 23:00:30 +01:00
|
|
|
bool redotz = false;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
char *tzn;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
PG_RETURN_TIMESTAMPTZ(timestamp);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
|
|
|
|
2003-07-27 06:53:12 +02:00
|
|
|
if (type == UNITS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
switch (val)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2004-03-05 03:41:14 +01:00
|
|
|
case DTK_WEEK:
|
2005-04-01 16:25:23 +02:00
|
|
|
{
|
|
|
|
int woy;
|
|
|
|
|
|
|
|
woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
|
|
|
/*
|
|
|
|
* If it is week 52/53 and the month is January,
|
|
|
|
* then the week must belong to the previous year.
|
2005-07-04 16:38:31 +02:00
|
|
|
* Also, some December dates belong to the next year.
|
2005-04-01 16:25:23 +02:00
|
|
|
*/
|
|
|
|
if (woy >= 52 && tm->tm_mon == 1)
|
|
|
|
--tm->tm_year;
|
2005-07-21 05:56:25 +02:00
|
|
|
if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
|
2005-07-04 16:38:31 +02:00
|
|
|
++tm->tm_year;
|
2005-04-01 16:25:23 +02:00
|
|
|
isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
2004-03-05 03:41:14 +01:00
|
|
|
tm->tm_hour = 0;
|
|
|
|
tm->tm_min = 0;
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
fsec = 0;
|
2004-11-01 23:00:30 +01:00
|
|
|
redotz = true;
|
2004-03-05 03:41:14 +01:00
|
|
|
break;
|
2005-04-01 16:25:23 +02:00
|
|
|
}
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* one may consider DTK_THOUSAND and DTK_HUNDRED... */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MILLENNIUM:
|
2004-08-29 07:07:03 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* truncating to the millennium? what is this supposed to
|
|
|
|
* mean? let us put the first year of the millennium...
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
* i.e. -1000, 1, 1001, 2001...
|
|
|
|
*/
|
|
|
|
if (tm->tm_year > 0)
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_CENTURY:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* truncating to the century? as above: -100, 1, 101... */
|
|
|
|
if (tm->tm_year > 0)
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DECADE:
|
2004-08-29 07:07:03 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* truncating to the decade? first year of the decade.
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
* must not be applied if year was truncated before!
|
|
|
|
*/
|
|
|
|
if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
|
|
|
|
{
|
|
|
|
if (tm->tm_year > 0)
|
|
|
|
tm->tm_year = (tm->tm_year / 10) * 10;
|
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
}
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_YEAR:
|
|
|
|
tm->tm_mon = 1;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_QUARTER:
|
2003-07-26 17:17:36 +02:00
|
|
|
tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MONTH:
|
|
|
|
tm->tm_mday = 1;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DAY:
|
|
|
|
tm->tm_hour = 0;
|
2004-11-01 23:00:30 +01:00
|
|
|
redotz = true; /* for all cases >= DAY */
|
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_HOUR:
|
|
|
|
tm->tm_min = 0;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MINUTE:
|
|
|
|
tm->tm_sec = 0;
|
2004-11-01 23:00:30 +01:00
|
|
|
/* FALL THRU */
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_SECOND:
|
|
|
|
fsec = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-22 23:16:15 +02:00
|
|
|
fsec = (fsec / 1000) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2001-09-28 10:09:14 +02:00
|
|
|
fsec = rint(fsec * 1000) / 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifndef HAVE_INT64_TIMESTAMP
|
2001-09-28 10:09:14 +02:00
|
|
|
fsec = rint(fsec * 1000000) / 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("timestamp with time zone units \"%s\" not "
|
|
|
|
"supported", lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
|
2004-11-01 23:00:30 +01:00
|
|
|
if (redotz)
|
2005-07-23 16:25:34 +02:00
|
|
|
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("timestamp with time zone units \"%s\" not recognized",
|
|
|
|
lowunits)));
|
2003-07-27 06:53:12 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(result);
|
2000-06-09 03:11:16 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
/* interval_trunc()
|
|
|
|
* Extract specified field from interval.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_trunc(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(1);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
Interval *result;
|
|
|
|
int type,
|
|
|
|
val;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
result = (Interval *) palloc(sizeof(Interval));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (type == UNITS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
|
|
|
if (interval2tm(*interval, tm, &fsec) == 0)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
2005-07-20 18:42:32 +02:00
|
|
|
/* fall through */
|
2000-04-14 17:22:10 +02:00
|
|
|
case DTK_MILLENNIUM:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_year = (tm->tm_year / 1000) * 1000;
|
|
|
|
case DTK_CENTURY:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_year = (tm->tm_year / 100) * 100;
|
|
|
|
case DTK_DECADE:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
tm->tm_year = (tm->tm_year / 10) * 10;
|
|
|
|
case DTK_YEAR:
|
|
|
|
tm->tm_mon = 0;
|
|
|
|
case DTK_QUARTER:
|
2005-05-24 04:09:45 +02:00
|
|
|
tm->tm_mon = 3 * (tm->tm_mon / 3);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
case DTK_MONTH:
|
|
|
|
tm->tm_mday = 0;
|
|
|
|
case DTK_DAY:
|
|
|
|
tm->tm_hour = 0;
|
|
|
|
case DTK_HOUR:
|
|
|
|
tm->tm_min = 0;
|
|
|
|
case DTK_MINUTE:
|
|
|
|
tm->tm_sec = 0;
|
|
|
|
case DTK_SECOND:
|
|
|
|
fsec = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-22 23:16:15 +02:00
|
|
|
fsec = (fsec / 1000) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
fsec = rint(fsec * 1000) / 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifndef HAVE_INT64_TIMESTAMP
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
fsec = rint(fsec * 1000000) / 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("interval units \"%s\" not supported",
|
2003-08-04 02:43:34 +02:00
|
|
|
lowunits)));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tm2interval(tm, fsec, result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("interval out of range")));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "could not convert interval to tm");
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("interval units \"%s\" not recognized",
|
2003-08-04 02:43:34 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
|
|
|
PointerGetDatum(units))))));
|
2001-09-28 10:09:14 +02:00
|
|
|
*result = *interval;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_INTERVAL_P(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* isoweek2date()
|
2001-01-03 17:48:02 +01:00
|
|
|
* Convert ISO week of year number to date.
|
2003-12-25 04:36:24 +01:00
|
|
|
* The year field must be specified with the ISO year!
|
2001-01-03 17:48:02 +01:00
|
|
|
* karel 2000/08/07
|
2000-08-29 06:41:48 +02:00
|
|
|
*/
|
|
|
|
void
|
2001-03-22 05:01:46 +01:00
|
|
|
isoweek2date(int woy, int *year, int *mon, int *mday)
|
2000-08-29 06:41:48 +02:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
int day0,
|
|
|
|
day4,
|
|
|
|
dayn;
|
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
if (!*year)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2004-08-29 07:07:03 +02:00
|
|
|
errmsg("cannot calculate week number without year information")));
|
2000-08-29 06:41:48 +02:00
|
|
|
|
|
|
|
/* fourth day of current year */
|
|
|
|
day4 = date2j(*year, 1, 4);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* day0 == offset to first day of week (Monday) */
|
2003-04-04 06:50:44 +02:00
|
|
|
day0 = j2day(day4 - 1);
|
2000-08-29 06:41:48 +02:00
|
|
|
|
|
|
|
dayn = ((woy - 1) * 7) + (day4 - day0);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
j2date(dayn, year, mon, mday);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* date2isoweek()
|
2001-03-22 05:01:46 +01:00
|
|
|
*
|
2000-08-29 06:41:48 +02:00
|
|
|
* Returns ISO week number of year.
|
|
|
|
*/
|
|
|
|
int
|
2001-03-22 05:01:46 +01:00
|
|
|
date2isoweek(int year, int mon, int mday)
|
2000-08-29 06:41:48 +02:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
float8 result;
|
|
|
|
int day0,
|
|
|
|
day4,
|
|
|
|
dayn;
|
|
|
|
|
|
|
|
/* current day */
|
2000-08-29 06:41:48 +02:00
|
|
|
dayn = date2j(year, mon, mday);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* fourth day of current year */
|
|
|
|
day4 = date2j(year, 1, 4);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* day0 == offset to first day of week (Monday) */
|
2003-04-04 06:50:44 +02:00
|
|
|
day0 = j2day(day4 - 1);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We need the first week containing a Thursday, otherwise this day
|
|
|
|
* falls into the previous year for purposes of counting weeks
|
2000-08-29 06:41:48 +02:00
|
|
|
*/
|
2005-05-23 19:13:14 +02:00
|
|
|
if (dayn < day4 - day0)
|
2000-08-29 06:41:48 +02:00
|
|
|
{
|
2003-04-04 06:50:44 +02:00
|
|
|
day4 = date2j(year - 1, 1, 4);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* day0 == offset to first day of week (Monday) */
|
2003-04-04 06:50:44 +02:00
|
|
|
day0 = j2day(day4 - 1);
|
2000-08-29 06:41:48 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (dayn - (day4 - day0)) / 7 + 1;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Sometimes the last few days in a year will fall into the first week
|
|
|
|
* of the next year, so check for this.
|
2000-08-29 06:41:48 +02:00
|
|
|
*/
|
2005-04-01 16:25:23 +02:00
|
|
|
if (result >= 52)
|
2000-08-29 06:41:48 +02:00
|
|
|
{
|
2003-04-04 06:50:44 +02:00
|
|
|
day4 = date2j(year + 1, 1, 4);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
/* day0 == offset to first day of week (Monday) */
|
2003-04-04 06:50:44 +02:00
|
|
|
day0 = j2day(day4 - 1);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
if (dayn >= day4 - day0)
|
|
|
|
result = (dayn - (day4 - day0)) / 7 + 1;
|
2000-08-29 06:41:48 +02:00
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
return (int) result;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-25 04:36:24 +01:00
|
|
|
/* date2isoyear()
|
|
|
|
*
|
|
|
|
* Returns ISO 8601 year number.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
date2isoyear(int year, int mon, int mday)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
float8 result;
|
|
|
|
int day0,
|
|
|
|
day4,
|
|
|
|
dayn;
|
2003-12-25 04:36:24 +01:00
|
|
|
|
|
|
|
/* current day */
|
|
|
|
dayn = date2j(year, mon, mday);
|
|
|
|
|
|
|
|
/* fourth day of current year */
|
|
|
|
day4 = date2j(year, 1, 4);
|
|
|
|
|
|
|
|
/* day0 == offset to first day of week (Monday) */
|
|
|
|
day0 = j2day(day4 - 1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need the first week containing a Thursday, otherwise this day
|
|
|
|
* falls into the previous year for purposes of counting weeks
|
|
|
|
*/
|
2005-05-23 19:13:14 +02:00
|
|
|
if (dayn < day4 - day0)
|
2003-12-25 04:36:24 +01:00
|
|
|
{
|
|
|
|
day4 = date2j(year - 1, 1, 4);
|
|
|
|
|
|
|
|
/* day0 == offset to first day of week (Monday) */
|
|
|
|
day0 = j2day(day4 - 1);
|
|
|
|
|
|
|
|
year--;
|
|
|
|
}
|
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (dayn - (day4 - day0)) / 7 + 1;
|
2003-12-25 04:36:24 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Sometimes the last few days in a year will fall into the first week
|
|
|
|
* of the next year, so check for this.
|
|
|
|
*/
|
2005-04-01 16:25:23 +02:00
|
|
|
if (result >= 52)
|
2003-12-25 04:36:24 +01:00
|
|
|
{
|
|
|
|
day4 = date2j(year + 1, 1, 4);
|
|
|
|
|
|
|
|
/* day0 == offset to first day of week (Monday) */
|
|
|
|
day0 = j2day(day4 - 1);
|
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
if (dayn >= day4 - day0)
|
2003-12-25 04:36:24 +01:00
|
|
|
year++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return year;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
/* timestamp_part()
|
|
|
|
* Extract specified field from timestamp.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_part(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
|
2000-06-09 03:11:16 +02:00
|
|
|
float8 result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int type,
|
|
|
|
val;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
|
|
|
if (type == UNKNOWN_FIELD)
|
|
|
|
type = DecodeSpecial(0, lowunits, &val);
|
|
|
|
|
2003-07-27 06:53:12 +02:00
|
|
|
if (type == UNITS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
switch (val)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000000.0 + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-03-04 04:55:50 +01:00
|
|
|
result = (tm->tm_sec + fsec) * 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000.0 + fsec / 1000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-03-04 04:55:50 +01:00
|
|
|
result = (tm->tm_sec + fsec) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_SECOND:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec + fsec / 1000000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
result = tm->tm_sec + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MINUTE:
|
|
|
|
result = tm->tm_min;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_HOUR:
|
|
|
|
result = tm->tm_hour;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DAY:
|
|
|
|
result = tm->tm_mday;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MONTH:
|
|
|
|
result = tm->tm_mon;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_QUARTER:
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (tm->tm_mon - 1) / 3 + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_WEEK:
|
|
|
|
result = (float8) date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_YEAR:
|
2004-03-30 17:53:18 +02:00
|
|
|
if (tm->tm_year > 0)
|
|
|
|
result = tm->tm_year;
|
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
/* there is no year 0, just 1 BC and 1 AD */
|
|
|
|
result = tm->tm_year - 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DECADE:
|
2004-08-29 07:07:03 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* what is a decade wrt dates? let us assume that decade
|
|
|
|
* 199 is 1990 thru 1999... decade 0 starts on year 1 BC,
|
|
|
|
* and -1 is 11 BC thru 2 BC...
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
*/
|
2004-08-29 07:07:03 +02:00
|
|
|
if (tm->tm_year >= 0)
|
2005-07-21 06:41:43 +02:00
|
|
|
result = tm->tm_year / 10;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((8 - (tm->tm_year - 1)) / 10);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_CENTURY:
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2005-05-23 19:13:14 +02:00
|
|
|
/* ----
|
|
|
|
* centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
|
|
|
|
* centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
|
|
|
|
* there is no number 0 century.
|
|
|
|
* ----
|
Please find a small patch to fix the brain damage "century" and
"millennium" date part implementation in postgresql, both in the code
and the documentation, so that it conforms to the official definition.
If you do not agree with the official definition, please send your
complaint to "pope@vatican.org". I'm not responsible for them;-)
With the previous version, the centuries and millenniums had a wrong
number and started the wrong year. Moreover century number 0, which does
not exist in reality, lasted 200 years. Also, millennium number 0 lasted
2000 years.
If you want postgresql to have it's own definition of "century" and
"millennium" that does not conform to the one of the society, just give
them another name. I would suggest "pgCENTURY" and "pgMILLENNIUM";-)
IMO, if someone may use the options, it means that postgresql is used for
historical data, so it make sense to have an historical definition. Also,
I just want to divide the year by 100 or 1000, I can do that quite easily.
BACKWARD INCOMPATIBLE CHANGE
Fabien Coelho - coelho@cri.ensmp.fr
2004-04-10 20:02:59 +02:00
|
|
|
*/
|
|
|
|
if (tm->tm_year > 0)
|
2005-05-24 04:09:45 +02:00
|
|
|
result = (tm->tm_year + 99) / 100;
|
Please find a small patch to fix the brain damage "century" and
"millennium" date part implementation in postgresql, both in the code
and the documentation, so that it conforms to the official definition.
If you do not agree with the official definition, please send your
complaint to "pope@vatican.org". I'm not responsible for them;-)
With the previous version, the centuries and millenniums had a wrong
number and started the wrong year. Moreover century number 0, which does
not exist in reality, lasted 200 years. Also, millennium number 0 lasted
2000 years.
If you want postgresql to have it's own definition of "century" and
"millennium" that does not conform to the one of the society, just give
them another name. I would suggest "pgCENTURY" and "pgMILLENNIUM";-)
IMO, if someone may use the options, it means that postgresql is used for
historical data, so it make sense to have an historical definition. Also,
I just want to divide the year by 100 or 1000, I can do that quite easily.
BACKWARD INCOMPATIBLE CHANGE
Fabien Coelho - coelho@cri.ensmp.fr
2004-04-10 20:02:59 +02:00
|
|
|
else
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((99 - (tm->tm_year - 1)) / 100);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLENNIUM:
|
Please find a small patch to fix the brain damage "century" and
"millennium" date part implementation in postgresql, both in the code
and the documentation, so that it conforms to the official definition.
If you do not agree with the official definition, please send your
complaint to "pope@vatican.org". I'm not responsible for them;-)
With the previous version, the centuries and millenniums had a wrong
number and started the wrong year. Moreover century number 0, which does
not exist in reality, lasted 200 years. Also, millennium number 0 lasted
2000 years.
If you want postgresql to have it's own definition of "century" and
"millennium" that does not conform to the one of the society, just give
them another name. I would suggest "pgCENTURY" and "pgMILLENNIUM";-)
IMO, if someone may use the options, it means that postgresql is used for
historical data, so it make sense to have an historical definition. Also,
I just want to divide the year by 100 or 1000, I can do that quite easily.
BACKWARD INCOMPATIBLE CHANGE
Fabien Coelho - coelho@cri.ensmp.fr
2004-04-10 20:02:59 +02:00
|
|
|
/* see comments above. */
|
|
|
|
if (tm->tm_year > 0)
|
2005-07-21 06:41:43 +02:00
|
|
|
result = (tm->tm_year + 999) / 1000;
|
Please find a small patch to fix the brain damage "century" and
"millennium" date part implementation in postgresql, both in the code
and the documentation, so that it conforms to the official definition.
If you do not agree with the official definition, please send your
complaint to "pope@vatican.org". I'm not responsible for them;-)
With the previous version, the centuries and millenniums had a wrong
number and started the wrong year. Moreover century number 0, which does
not exist in reality, lasted 200 years. Also, millennium number 0 lasted
2000 years.
If you want postgresql to have it's own definition of "century" and
"millennium" that does not conform to the one of the society, just give
them another name. I would suggest "pgCENTURY" and "pgMILLENNIUM";-)
IMO, if someone may use the options, it means that postgresql is used for
historical data, so it make sense to have an historical definition. Also,
I just want to divide the year by 100 or 1000, I can do that quite easily.
BACKWARD INCOMPATIBLE CHANGE
Fabien Coelho - coelho@cri.ensmp.fr
2004-04-10 20:02:59 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((999 - (tm->tm_year - 1)) / 1000);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
2001-12-29 19:31:48 +01:00
|
|
|
case DTK_JULIAN:
|
|
|
|
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 20:06:13 +02:00
|
|
|
result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
|
2005-07-12 17:17:44 +02:00
|
|
|
tm->tm_sec + (fsec / 1000000.0)) / (double)SECS_PER_DAY;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 20:06:13 +02:00
|
|
|
result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
|
2005-05-23 20:56:55 +02:00
|
|
|
tm->tm_sec + fsec) / (double)SECS_PER_DAY;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-12-29 19:31:48 +01:00
|
|
|
break;
|
|
|
|
|
2001-10-03 07:29:27 +02:00
|
|
|
case DTK_TZ:
|
|
|
|
case DTK_TZ_MINUTE:
|
|
|
|
case DTK_TZ_HOUR:
|
2001-09-28 10:09:14 +02:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("timestamp units \"%s\" not supported",
|
2003-08-04 02:43:34 +02:00
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == RESERV)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
|
|
|
case DTK_EPOCH:
|
2003-08-04 02:43:34 +02:00
|
|
|
{
|
|
|
|
int tz;
|
|
|
|
TimestampTz timestamptz;
|
2003-02-27 22:36:58 +01:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
/*
|
|
|
|
* convert to timestamptz to produce consistent
|
|
|
|
* results
|
|
|
|
*/
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-08-04 02:43:34 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2003-02-27 22:36:58 +01:00
|
|
|
|
2005-07-23 16:25:34 +02:00
|
|
|
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
2003-02-27 22:36:58 +01:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2003-02-27 22:36:58 +01:00
|
|
|
|
2002-09-04 00:55:54 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = (timestamptz - SetEpochTimestamp()) / 1000000.0;
|
2002-09-04 00:55:54 +02:00
|
|
|
#else
|
2003-08-04 02:43:34 +02:00
|
|
|
result = timestamptz - SetEpochTimestamp();
|
2002-09-04 00:55:54 +02:00
|
|
|
#endif
|
2003-08-04 02:43:34 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DOW:
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
|
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DOY:
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
|
|
|
|
- date2j(tm->tm_year, 1, 1) + 1);
|
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("timestamp units \"%s\" not supported",
|
2003-08-04 02:43:34 +02:00
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("timestamp units \"%s\" not recognized", lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
2000-04-14 17:22:10 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* timestamptz_part()
|
|
|
|
* Extract specified field from timestamp with time zone.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_part(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
|
2001-09-28 10:09:14 +02:00
|
|
|
float8 result;
|
|
|
|
int tz;
|
|
|
|
int type,
|
|
|
|
val;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2001-09-28 10:09:14 +02:00
|
|
|
double dummy;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
char *tzn;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
{
|
|
|
|
result = 0;
|
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
|
|
|
if (type == UNKNOWN_FIELD)
|
|
|
|
type = DecodeSpecial(0, lowunits, &val);
|
|
|
|
|
2003-07-27 06:53:12 +02:00
|
|
|
if (type == UNITS)
|
2001-09-28 10:09:14 +02:00
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
switch (val)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_TZ:
|
2003-07-17 02:55:37 +02:00
|
|
|
result = -tz;
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_TZ_MINUTE:
|
2003-07-17 02:55:37 +02:00
|
|
|
result = -tz;
|
2005-07-21 20:06:13 +02:00
|
|
|
result /= MINS_PER_HOUR;
|
|
|
|
FMODULO(result, dummy, (double)MINS_PER_HOUR);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_TZ_HOUR:
|
2003-07-17 02:55:37 +02:00
|
|
|
dummy = -tz;
|
2005-07-21 05:56:25 +02:00
|
|
|
FMODULO(dummy, result, (double)SECS_PER_HOUR);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000000.0 + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-03-04 04:55:50 +01:00
|
|
|
result = (tm->tm_sec + fsec) * 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000.0 + fsec / 1000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-03-04 04:55:50 +01:00
|
|
|
result = (tm->tm_sec + fsec) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_SECOND:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec + fsec / 1000000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
result = tm->tm_sec + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MINUTE:
|
|
|
|
result = tm->tm_min;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_HOUR:
|
|
|
|
result = tm->tm_hour;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DAY:
|
|
|
|
result = tm->tm_mday;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MONTH:
|
|
|
|
result = tm->tm_mon;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_QUARTER:
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (tm->tm_mon - 1) / 3 + 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_WEEK:
|
|
|
|
result = (float8) date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_YEAR:
|
2004-11-20 23:12:44 +01:00
|
|
|
if (tm->tm_year > 0)
|
|
|
|
result = tm->tm_year;
|
|
|
|
else
|
|
|
|
/* there is no year 0, just 1 BC and 1 AD */
|
|
|
|
result = tm->tm_year - 1;
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DECADE:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamp_part */
|
2004-08-29 07:07:03 +02:00
|
|
|
if (tm->tm_year > 0)
|
2005-07-21 06:41:43 +02:00
|
|
|
result = tm->tm_year / 10;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((8 - (tm->tm_year - 1)) / 10);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_CENTURY:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamp_part */
|
|
|
|
if (tm->tm_year > 0)
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (tm->tm_year + 99) / 100;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((99 - (tm->tm_year - 1)) / 100);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MILLENNIUM:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* see comments in timestamp_part */
|
|
|
|
if (tm->tm_year > 0)
|
2005-05-23 19:13:14 +02:00
|
|
|
result = (tm->tm_year + 999) / 1000;
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
else
|
2004-08-29 07:07:03 +02:00
|
|
|
result = -((999 - (tm->tm_year - 1)) / 1000);
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
|
|
|
|
2001-12-29 19:31:48 +01:00
|
|
|
case DTK_JULIAN:
|
|
|
|
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-21 20:06:13 +02:00
|
|
|
result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
|
2005-07-12 17:17:44 +02:00
|
|
|
tm->tm_sec + (fsec / 1000000.0)) / (double)SECS_PER_DAY;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-21 20:06:13 +02:00
|
|
|
result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
|
2005-05-23 20:56:55 +02:00
|
|
|
tm->tm_sec + fsec) / (double)SECS_PER_DAY;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-12-29 19:31:48 +01:00
|
|
|
break;
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("timestamp with time zone units \"%s\" not supported",
|
2003-08-04 02:43:34 +02:00
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
else if (type == RESERV)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
|
|
|
case DTK_EPOCH:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = (timestamp - SetEpochTimestamp()) /1000000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
result = timestamp - SetEpochTimestamp();
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2001-09-28 10:09:14 +02:00
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DOW:
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
|
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
case DTK_DOY:
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
|
|
|
|
- date2j(tm->tm_year, 1, 1) + 1);
|
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("timestamp with time zone units \"%s\" not supported",
|
2003-08-04 02:43:34 +02:00
|
|
|
lowunits)));
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("timestamp with time zone units \"%s\" not recognized",
|
|
|
|
lowunits)));
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
result = 0;
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* interval_part()
|
|
|
|
* Extract specified field from interval.
|
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
interval_part(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *units = PG_GETARG_TEXT_P(0);
|
|
|
|
Interval *interval = PG_GETARG_INTERVAL_P(1);
|
|
|
|
float8 result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int type,
|
|
|
|
val;
|
2004-05-07 02:24:59 +02:00
|
|
|
char *lowunits;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*tm = &tt;
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
lowunits = downcase_truncate_identifier(VARDATA(units),
|
|
|
|
VARSIZE(units) - VARHDRSZ,
|
|
|
|
false);
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
type = DecodeUnits(0, lowunits, &val);
|
2001-10-18 19:30:21 +02:00
|
|
|
if (type == UNKNOWN_FIELD)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
type = DecodeSpecial(0, lowunits, &val);
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (type == UNITS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
|
|
|
if (interval2tm(*interval, tm, &fsec) == 0)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
case DTK_MICROSEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000000.0 + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-09-04 22:31:48 +02:00
|
|
|
result = (tm->tm_sec + fsec) * 1000000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
case DTK_MILLISEC:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec * 1000.0 + fsec / 1000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2002-09-04 22:31:48 +02:00
|
|
|
result = (tm->tm_sec + fsec) * 1000;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
case DTK_SECOND:
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = tm->tm_sec + fsec / 1000000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
result = tm->tm_sec + fsec;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
case DTK_MINUTE:
|
2000-06-09 03:11:16 +02:00
|
|
|
result = tm->tm_min;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_HOUR:
|
2000-06-09 03:11:16 +02:00
|
|
|
result = tm->tm_hour;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DAY:
|
2000-06-09 03:11:16 +02:00
|
|
|
result = tm->tm_mday;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_MONTH:
|
2000-06-09 03:11:16 +02:00
|
|
|
result = tm->tm_mon;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_QUARTER:
|
2003-07-26 17:17:36 +02:00
|
|
|
result = (tm->tm_mon / 3) + 1;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_YEAR:
|
2000-06-09 03:11:16 +02:00
|
|
|
result = tm->tm_year;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_DECADE:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
2005-07-21 06:41:43 +02:00
|
|
|
result = tm->tm_year / 10;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DTK_CENTURY:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
2005-07-21 06:41:43 +02:00
|
|
|
result = tm->tm_year / 100;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
2000-04-14 17:22:10 +02:00
|
|
|
case DTK_MILLENNIUM:
|
> After all that about numbering centuries and millenia correctly,
> why does CVS tip still give me
>
> regression=# select extract(century from now());
> date_part
> -----------
> 20
> (1 row)
> [ ... looks in code ... ]
>
> Apparently it's because you fixed only timestamp_part, and not
> timestamptz_part. I'm not too sure about what timestamp_trunc or
> timestamptz_trunc should do, but they may be wrong as well.
Sigh... as usual, what is not tested does not work:-(
> Could we have a more complete patch?
Please find a submission attached. I hope it really fixes all decade,
century and millenium issues for extract and *_trunc functions on
interval
and other timestamp types. If someone could check that the results
are reasonnable, it would be great.
I indeed overlooked the fact that there were two functions. The patch
fixes the code so that both variants agree.
I added comments to interval extractions, because it relies on the C
division to have a negative remainder: -7/10 = 0 and remains -7.
As for *_trunc functions, I have chosen to put the first year of the
century or millennium: -100, 1, 101... 1001 2001 etc. Indeed, I don't
think it would make sense to put 2000 (last year of the 2nd millennium)
for rounding all years of the third millenium.
I also fixed the code so that all decades last 10 years and decade 199
means the 1990's.
I have added some tests that are relevant to deal with tricky cases. The
formula may be simplified, but all these cases must pass. Please keep
them.
Fabien Coelho
2004-08-20 05:45:14 +02:00
|
|
|
/* caution: C division may have negative remainder */
|
2005-07-21 06:41:43 +02:00
|
|
|
result = tm->tm_year / 1000;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("interval units \"%s\" not supported",
|
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
2003-08-04 02:43:34 +02:00
|
|
|
PointerGetDatum(units))))));
|
2000-06-09 03:11:16 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "could not convert interval to tm");
|
2000-06-09 03:11:16 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
}
|
2005-05-23 19:13:14 +02:00
|
|
|
else if (type == RESERV && val == DTK_EPOCH)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-07-12 17:17:44 +02:00
|
|
|
result = interval->time / 1000000.0;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2000-06-09 03:11:16 +02:00
|
|
|
result = interval->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2005-07-21 05:56:25 +02:00
|
|
|
result += (DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
|
|
|
|
result += ((double)DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
|
2005-07-20 18:42:32 +02:00
|
|
|
result += interval->day * SECS_PER_DAY;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("interval units \"%s\" not recognized",
|
2003-08-04 02:43:34 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(textout,
|
|
|
|
PointerGetDatum(units))))));
|
2000-06-09 03:11:16 +02:00
|
|
|
result = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
|
|
|
|
2005-07-23 04:02:27 +02:00
|
|
|
/* timestamp_zone()
|
|
|
|
* Encode timestamp type with specified time zone.
|
2005-07-23 16:25:34 +02:00
|
|
|
* This function is just timestamp2timestamptz() except instead of
|
|
|
|
* shifting to the global timezone, we shift to the specified timezone.
|
|
|
|
* This is different from the other AT TIME ZONE cases because instead
|
|
|
|
* of shifting to a _to_ a new time zone, it sets the time to _be_ the
|
|
|
|
* specified timezone.
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
*/
|
2000-06-09 03:11:16 +02:00
|
|
|
Datum
|
|
|
|
timestamp_zone(PG_FUNCTION_ARGS)
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
{
|
2000-06-09 03:11:16 +02:00
|
|
|
text *zone = PG_GETARG_TEXT_P(0);
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
|
2005-07-22 23:16:15 +02:00
|
|
|
TimestampTz result;
|
2001-09-28 10:09:14 +02:00
|
|
|
int tz;
|
2005-06-15 02:34:11 +02:00
|
|
|
pg_tz *tzp;
|
|
|
|
char tzname[TZ_STRLEN_MAX+1];
|
|
|
|
int len;
|
|
|
|
struct pg_tm tm;
|
|
|
|
fsec_t fsec;
|
2005-07-23 16:25:34 +02:00
|
|
|
bool fail;
|
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
PG_RETURN_TIMESTAMPTZ(timestamp);
|
|
|
|
|
2005-07-23 16:25:34 +02:00
|
|
|
/* Find the specified timezone */
|
2005-07-22 17:15:38 +02:00
|
|
|
len = (VARSIZE(zone) - VARHDRSZ>TZ_STRLEN_MAX) ?
|
|
|
|
TZ_STRLEN_MAX : VARSIZE(zone) - VARHDRSZ;
|
|
|
|
memcpy(tzname, VARDATA(zone), len);
|
2005-06-15 02:34:11 +02:00
|
|
|
tzname[len] = 0;
|
|
|
|
tzp = pg_tzset(tzname);
|
2005-07-22 17:15:38 +02:00
|
|
|
if (!tzp)
|
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2005-06-15 02:34:11 +02:00
|
|
|
errmsg("time zone \"%s\" not recognised",
|
|
|
|
tzname)));
|
2001-09-28 10:09:14 +02:00
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
/* Apply the timezone change */
|
2005-07-23 16:25:34 +02:00
|
|
|
fail = (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0);
|
|
|
|
if (!fail)
|
|
|
|
{
|
|
|
|
tz = DetermineTimeZoneOffset(&tm, tzp);
|
|
|
|
fail = (tm2timestamp(&tm, fsec, &tz, &result) != 0);
|
|
|
|
}
|
|
|
|
if (fail)
|
2005-07-22 17:15:38 +02:00
|
|
|
{
|
2005-06-15 02:34:11 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not convert to time zone \"%s\"",
|
|
|
|
tzname)));
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
2005-07-23 04:02:27 +02:00
|
|
|
|
2005-07-22 23:16:15 +02:00
|
|
|
PG_RETURN_TIMESTAMPTZ(result);
|
2005-07-22 17:15:38 +02:00
|
|
|
}
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
/* timestamp_izone()
|
|
|
|
* Encode timestamp type with specified time interval as time zone.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_izone(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Interval *zone = PG_GETARG_INTERVAL_P(0);
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
2001-09-28 10:09:14 +02:00
|
|
|
int tz;
|
|
|
|
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
PG_RETURN_TIMESTAMPTZ(timestamp);
|
|
|
|
|
|
|
|
if (zone->month != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("interval time zone \"%s\" must not specify month",
|
|
|
|
DatumGetCString(DirectFunctionCall1(interval_out,
|
|
|
|
PointerGetDatum(zone))))));
|
2001-09-28 10:09:14 +02:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
tz = zone->time / USECS_PER_SEC;
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-05-23 19:13:14 +02:00
|
|
|
tz = zone->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
result = dt2local(timestamp, tz);
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
PG_RETURN_TIMESTAMPTZ(result);
|
|
|
|
} /* timestamp_izone() */
|
|
|
|
|
|
|
|
/* timestamp_timestamptz()
|
|
|
|
* Convert local timestamp to timestamp at GMT
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamp_timestamptz(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-08-30 04:54:42 +02:00
|
|
|
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
2004-03-22 02:38:18 +01:00
|
|
|
|
|
|
|
PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(timestamp));
|
|
|
|
}
|
|
|
|
|
|
|
|
static TimestampTz
|
|
|
|
timestamp2timestamptz(Timestamp timestamp)
|
|
|
|
{
|
2001-10-25 07:50:21 +02:00
|
|
|
TimestampTz result;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
int tz;
|
|
|
|
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
result = timestamp;
|
|
|
|
else
|
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
|
2005-07-23 16:25:34 +02:00
|
|
|
tz = DetermineTimeZoneOffset(tm, global_timezone);
|
2001-09-28 10:09:14 +02:00
|
|
|
|
|
|
|
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
|
2004-03-22 02:38:18 +01:00
|
|
|
return result;
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* timestamptz_timestamp()
|
|
|
|
* Convert timestamp at GMT to local timestamp
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_timestamp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
2001-09-28 10:09:14 +02:00
|
|
|
Timestamp result;
|
2004-08-29 07:07:03 +02:00
|
|
|
struct pg_tm tt,
|
2001-09-28 10:09:14 +02:00
|
|
|
*tm = &tt;
|
2002-04-21 21:52:18 +02:00
|
|
|
fsec_t fsec;
|
2001-09-28 10:09:14 +02:00
|
|
|
char *tzn;
|
|
|
|
int tz;
|
|
|
|
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
|
|
|
result = timestamp;
|
|
|
|
else
|
|
|
|
{
|
2005-07-21 06:41:43 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("timestamp out of range")));
|
2001-09-28 10:09:14 +02:00
|
|
|
}
|
|
|
|
PG_RETURN_TIMESTAMP(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* timestamptz_zone()
|
2002-04-21 21:52:18 +02:00
|
|
|
* Evaluate timestamp with time zone type at the specified time zone.
|
|
|
|
* Returns a timestamp without time zone.
|
2001-09-28 10:09:14 +02:00
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
timestamptz_zone(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *zone = PG_GETARG_TEXT_P(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
|
2002-04-21 21:52:18 +02:00
|
|
|
Timestamp result;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
int tz;
|
2005-06-15 02:34:11 +02:00
|
|
|
pg_tz *tzp;
|
|
|
|
char tzname[TZ_STRLEN_MAX];
|
|
|
|
int len;
|
|
|
|
struct pg_tm tm;
|
|
|
|
fsec_t fsec = 0;
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2000-06-09 03:11:16 +02:00
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
2002-04-21 21:52:18 +02:00
|
|
|
PG_RETURN_NULL();
|
2001-09-28 10:09:14 +02:00
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
/* Find the specified zone */
|
2005-07-22 17:15:38 +02:00
|
|
|
len = (VARSIZE(zone) - VARHDRSZ > TZ_STRLEN_MAX) ?
|
|
|
|
TZ_STRLEN_MAX : VARSIZE(zone) - VARHDRSZ;
|
|
|
|
memcpy(tzname, VARDATA(zone), len);
|
2005-06-15 02:34:11 +02:00
|
|
|
tzname[len] = 0;
|
|
|
|
tzp = pg_tzset(tzname);
|
2004-05-07 02:24:59 +02:00
|
|
|
|
2005-07-22 17:15:38 +02:00
|
|
|
if (!tzp)
|
|
|
|
{
|
2005-06-15 02:34:11 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("time zone \"%s\" not recognized", tzname)));
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
PG_RETURN_NULL();
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
2003-07-27 06:53:12 +02:00
|
|
|
|
2005-06-15 02:34:11 +02:00
|
|
|
if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0 ||
|
2005-07-22 17:15:38 +02:00
|
|
|
tm2timestamp(&tm, fsec, NULL, &result))
|
|
|
|
{
|
2005-06-15 02:34:11 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("could not to convert to time zone \"%s\"", tzname)));
|
2002-04-21 21:52:18 +02:00
|
|
|
PG_RETURN_NULL();
|
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.
2000-02-16 18:26:26 +01:00
|
|
|
}
|
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
2005-07-22 17:15:38 +02:00
|
|
|
}
|
2000-11-06 16:57:00 +01:00
|
|
|
|
2001-09-28 10:09:14 +02:00
|
|
|
/* timestamptz_izone()
|
|
|
|
* Encode timestamp with time zone type with specified time interval as time zone.
|
2002-04-21 21:52:18 +02:00
|
|
|
* Returns a timestamp without time zone.
|
2000-11-06 16:57:00 +01:00
|
|
|
*/
|
|
|
|
Datum
|
2001-09-28 10:09:14 +02:00
|
|
|
timestamptz_izone(PG_FUNCTION_ARGS)
|
2000-11-06 16:57:00 +01:00
|
|
|
{
|
|
|
|
Interval *zone = PG_GETARG_INTERVAL_P(0);
|
2003-05-13 01:08:52 +02:00
|
|
|
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
|
2002-04-21 21:52:18 +02:00
|
|
|
Timestamp result;
|
2000-11-06 16:57:00 +01:00
|
|
|
int tz;
|
|
|
|
|
|
|
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
2002-04-21 21:52:18 +02:00
|
|
|
PG_RETURN_NULL();
|
2000-11-06 16:57:00 +01:00
|
|
|
|
|
|
|
if (zone->month != 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2003-08-04 02:43:34 +02:00
|
|
|
errmsg("interval time zone \"%s\" must not specify month",
|
|
|
|
DatumGetCString(DirectFunctionCall1(interval_out,
|
|
|
|
PointerGetDatum(zone))))));
|
2000-11-06 16:57:00 +01:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
2005-05-23 20:56:55 +02:00
|
|
|
tz = -(zone->time / USECS_PER_SEC);
|
2002-04-21 21:52:18 +02:00
|
|
|
#else
|
2005-07-22 21:00:55 +02:00
|
|
|
tz = -zone->time;
|
2002-04-21 21:52:18 +02:00
|
|
|
#endif
|
2000-11-06 16:57:00 +01:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
result = dt2local(timestamp, tz);
|
2000-11-06 16:57:00 +01:00
|
|
|
|
2002-04-21 21:52:18 +02:00
|
|
|
PG_RETURN_TIMESTAMP(result);
|
2005-07-22 17:15:38 +02:00
|
|
|
}
|