Extend the date type to support infinity and -infinity, analogously to
the timestamp types. Turns out this doesn't even reduce the available range of dates, since the restriction to dates that work for Julian-date arithmetic is much tighter than the int32 range anyway. Per a longstanding TODO item.
This commit is contained in:
parent
791359fe0e
commit
a303e4dc43
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.229 2008/10/03 15:37:18 petere Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.230 2008/10/14 17:12:32 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="datatype">
|
<chapter id="datatype">
|
||||||
<title id="datatype-title">Data Types</title>
|
<title id="datatype-title">Data Types</title>
|
||||||
@ -2032,12 +2032,12 @@ January 8 04:05:06 1999 PST
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>infinity</literal></entry>
|
<entry><literal>infinity</literal></entry>
|
||||||
<entry><type>timestamp</type></entry>
|
<entry><type>date</type>, <type>timestamp</type></entry>
|
||||||
<entry>later than all other time stamps</entry>
|
<entry>later than all other time stamps</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>-infinity</literal></entry>
|
<entry><literal>-infinity</literal></entry>
|
||||||
<entry><type>timestamp</type></entry>
|
<entry><type>date</type>, <type>timestamp</type></entry>
|
||||||
<entry>earlier than all other time stamps</entry>
|
<entry>earlier than all other time stamps</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.449 2008/10/13 16:25:19 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.450 2008/10/14 17:12:32 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="functions">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<title>Functions and Operators</title>
|
||||||
@ -5912,10 +5912,18 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
|
|||||||
<entry><literal>3</literal></entry>
|
<entry><literal>3</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal><function>isfinite</function>(<type>date</type>)</literal></entry>
|
||||||
|
<entry><type>boolean</type></entry>
|
||||||
|
<entry>Test for finite date (not +/-infinity)</entry>
|
||||||
|
<entry><literal>isfinite(date '2001-02-16')</literal></entry>
|
||||||
|
<entry><literal>true</literal></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><function>isfinite</function>(<type>timestamp</type>)</literal></entry>
|
<entry><literal><function>isfinite</function>(<type>timestamp</type>)</literal></entry>
|
||||||
<entry><type>boolean</type></entry>
|
<entry><type>boolean</type></entry>
|
||||||
<entry>Test for finite time stamp (not equal to infinity)</entry>
|
<entry>Test for finite time stamp (not +/-infinity)</entry>
|
||||||
<entry><literal>isfinite(timestamp '2001-02-16 21:28:30')</literal></entry>
|
<entry><literal>isfinite(timestamp '2001-02-16 21:28:30')</literal></entry>
|
||||||
<entry><literal>true</literal></entry>
|
<entry><literal>true</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.142 2008/07/07 18:09:46 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.143 2008/10/14 17:12:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -38,6 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void EncodeSpecialDate(DateADT dt, char *str);
|
||||||
static int time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec);
|
static int time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec);
|
||||||
static int timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp);
|
static int timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp);
|
||||||
static int tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result);
|
static int tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result);
|
||||||
@ -147,6 +148,14 @@ date_in(PG_FUNCTION_ARGS)
|
|||||||
GetEpochTime(tm);
|
GetEpochTime(tm);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTK_LATE:
|
||||||
|
DATE_NOEND(date);
|
||||||
|
PG_RETURN_DATEADT(date);
|
||||||
|
|
||||||
|
case DTK_EARLY:
|
||||||
|
DATE_NOBEGIN(date);
|
||||||
|
PG_RETURN_DATEADT(date);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DateTimeParseError(DTERR_BAD_FORMAT, str, "date");
|
DateTimeParseError(DTERR_BAD_FORMAT, str, "date");
|
||||||
break;
|
break;
|
||||||
@ -174,10 +183,14 @@ date_out(PG_FUNCTION_ARGS)
|
|||||||
*tm = &tt;
|
*tm = &tt;
|
||||||
char buf[MAXDATELEN + 1];
|
char buf[MAXDATELEN + 1];
|
||||||
|
|
||||||
j2date(date + POSTGRES_EPOCH_JDATE,
|
if (DATE_NOT_FINITE(date))
|
||||||
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
EncodeSpecialDate(date, buf);
|
||||||
|
else
|
||||||
EncodeDateOnly(tm, DateStyle, buf);
|
{
|
||||||
|
j2date(date + POSTGRES_EPOCH_JDATE,
|
||||||
|
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
||||||
|
EncodeDateOnly(tm, DateStyle, buf);
|
||||||
|
}
|
||||||
|
|
||||||
result = pstrdup(buf);
|
result = pstrdup(buf);
|
||||||
PG_RETURN_CSTRING(result);
|
PG_RETURN_CSTRING(result);
|
||||||
@ -208,6 +221,20 @@ date_send(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert reserved date values to string.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
EncodeSpecialDate(DateADT dt, char *str)
|
||||||
|
{
|
||||||
|
if (DATE_IS_NOBEGIN(dt))
|
||||||
|
strcpy(str, EARLY);
|
||||||
|
else if (DATE_IS_NOEND(dt))
|
||||||
|
strcpy(str, LATE);
|
||||||
|
else /* shouldn't happen */
|
||||||
|
elog(ERROR, "invalid argument for EncodeSpecialDate");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Comparison functions for dates
|
* Comparison functions for dates
|
||||||
@ -280,6 +307,14 @@ date_cmp(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_INT32(0);
|
PG_RETURN_INT32(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
date_finite(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
DateADT date = PG_GETARG_DATEADT(0);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(!DATE_NOT_FINITE(date));
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
date_larger(PG_FUNCTION_ARGS)
|
date_larger(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
@ -306,6 +341,11 @@ date_mi(PG_FUNCTION_ARGS)
|
|||||||
DateADT dateVal1 = PG_GETARG_DATEADT(0);
|
DateADT dateVal1 = PG_GETARG_DATEADT(0);
|
||||||
DateADT dateVal2 = PG_GETARG_DATEADT(1);
|
DateADT dateVal2 = PG_GETARG_DATEADT(1);
|
||||||
|
|
||||||
|
if (DATE_NOT_FINITE(dateVal1) || DATE_NOT_FINITE(dateVal2))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("cannot subtract infinite dates")));
|
||||||
|
|
||||||
PG_RETURN_INT32((int32) (dateVal1 - dateVal2));
|
PG_RETURN_INT32((int32) (dateVal1 - dateVal2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +358,9 @@ date_pli(PG_FUNCTION_ARGS)
|
|||||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||||
int32 days = PG_GETARG_INT32(1);
|
int32 days = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
|
if (DATE_NOT_FINITE(dateVal))
|
||||||
|
days = 0; /* can't change infinity */
|
||||||
|
|
||||||
PG_RETURN_DATEADT(dateVal + days);
|
PG_RETURN_DATEADT(dateVal + days);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +372,9 @@ date_mii(PG_FUNCTION_ARGS)
|
|||||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||||
int32 days = PG_GETARG_INT32(1);
|
int32 days = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
|
if (DATE_NOT_FINITE(dateVal))
|
||||||
|
days = 0; /* can't change infinity */
|
||||||
|
|
||||||
PG_RETURN_DATEADT(dateVal - days);
|
PG_RETURN_DATEADT(dateVal - days);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,18 +388,25 @@ date2timestamp(DateADT dateVal)
|
|||||||
{
|
{
|
||||||
Timestamp result;
|
Timestamp result;
|
||||||
|
|
||||||
|
if (DATE_IS_NOBEGIN(dateVal))
|
||||||
|
TIMESTAMP_NOBEGIN(result);
|
||||||
|
else if (DATE_IS_NOEND(dateVal))
|
||||||
|
TIMESTAMP_NOEND(result);
|
||||||
|
else
|
||||||
|
{
|
||||||
#ifdef HAVE_INT64_TIMESTAMP
|
#ifdef HAVE_INT64_TIMESTAMP
|
||||||
/* date is days since 2000, timestamp is microseconds since same... */
|
/* date is days since 2000, timestamp is microseconds since same... */
|
||||||
result = dateVal * USECS_PER_DAY;
|
result = dateVal * USECS_PER_DAY;
|
||||||
/* Date's range is wider than timestamp's, so must check for overflow */
|
/* Date's range is wider than timestamp's, so check for overflow */
|
||||||
if (result / USECS_PER_DAY != dateVal)
|
if (result / USECS_PER_DAY != dateVal)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("date out of range for timestamp")));
|
errmsg("date out of range for timestamp")));
|
||||||
#else
|
#else
|
||||||
/* date is days since 2000, timestamp is seconds since same... */
|
/* date is days since 2000, timestamp is seconds since same... */
|
||||||
result = dateVal * (double) SECS_PER_DAY;
|
result = dateVal * (double) SECS_PER_DAY;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -366,24 +419,30 @@ date2timestamptz(DateADT dateVal)
|
|||||||
*tm = &tt;
|
*tm = &tt;
|
||||||
int tz;
|
int tz;
|
||||||
|
|
||||||
j2date(dateVal + POSTGRES_EPOCH_JDATE,
|
if (DATE_IS_NOBEGIN(dateVal))
|
||||||
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
TIMESTAMP_NOBEGIN(result);
|
||||||
|
else if (DATE_IS_NOEND(dateVal))
|
||||||
tm->tm_hour = 0;
|
TIMESTAMP_NOEND(result);
|
||||||
tm->tm_min = 0;
|
else
|
||||||
tm->tm_sec = 0;
|
{
|
||||||
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
j2date(dateVal + POSTGRES_EPOCH_JDATE,
|
||||||
|
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
|
||||||
|
tm->tm_hour = 0;
|
||||||
|
tm->tm_min = 0;
|
||||||
|
tm->tm_sec = 0;
|
||||||
|
tz = DetermineTimeZoneOffset(tm, session_timezone);
|
||||||
|
|
||||||
#ifdef HAVE_INT64_TIMESTAMP
|
#ifdef HAVE_INT64_TIMESTAMP
|
||||||
result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
|
result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
|
||||||
/* Date's range is wider than timestamp's, so must check for overflow */
|
/* Date's range is wider than timestamp's, so check for overflow */
|
||||||
if ((result - tz * USECS_PER_SEC) / USECS_PER_DAY != dateVal)
|
if ((result - tz * USECS_PER_SEC) / USECS_PER_DAY != dateVal)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("date out of range for timestamp")));
|
errmsg("date out of range for timestamp")));
|
||||||
#else
|
#else
|
||||||
result = dateVal * (double) SECS_PER_DAY + tz;
|
result = dateVal * (double) SECS_PER_DAY + tz;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -797,15 +856,19 @@ timestamp_date(PG_FUNCTION_ARGS)
|
|||||||
*tm = &tt;
|
*tm = &tt;
|
||||||
fsec_t fsec;
|
fsec_t fsec;
|
||||||
|
|
||||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
if (TIMESTAMP_IS_NOBEGIN(timestamp))
|
||||||
PG_RETURN_NULL();
|
DATE_NOBEGIN(result);
|
||||||
|
else if (TIMESTAMP_IS_NOEND(timestamp))
|
||||||
|
DATE_NOEND(result);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
|
||||||
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
|
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
||||||
ereport(ERROR,
|
}
|
||||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
||||||
errmsg("timestamp out of range")));
|
|
||||||
|
|
||||||
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
|
||||||
|
|
||||||
PG_RETURN_DATEADT(result);
|
PG_RETURN_DATEADT(result);
|
||||||
}
|
}
|
||||||
@ -840,15 +903,19 @@ timestamptz_date(PG_FUNCTION_ARGS)
|
|||||||
int tz;
|
int tz;
|
||||||
char *tzn;
|
char *tzn;
|
||||||
|
|
||||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
if (TIMESTAMP_IS_NOBEGIN(timestamp))
|
||||||
PG_RETURN_NULL();
|
DATE_NOBEGIN(result);
|
||||||
|
else if (TIMESTAMP_IS_NOEND(timestamp))
|
||||||
|
DATE_NOEND(result);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
|
||||||
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
|
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
||||||
ereport(ERROR,
|
}
|
||||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
|
||||||
errmsg("timestamp out of range")));
|
|
||||||
|
|
||||||
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
|
||||||
|
|
||||||
PG_RETURN_DATEADT(result);
|
PG_RETURN_DATEADT(result);
|
||||||
}
|
}
|
||||||
@ -869,16 +936,19 @@ abstime_date(PG_FUNCTION_ARGS)
|
|||||||
switch (abstime)
|
switch (abstime)
|
||||||
{
|
{
|
||||||
case INVALID_ABSTIME:
|
case INVALID_ABSTIME:
|
||||||
case NOSTART_ABSTIME:
|
|
||||||
case NOEND_ABSTIME:
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("cannot convert reserved abstime value to date")));
|
errmsg("cannot convert reserved abstime value to date")));
|
||||||
|
result = 0; /* keep compiler quiet */
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
case NOSTART_ABSTIME:
|
||||||
* pretend to drop through to make compiler think that result will
|
DATE_NOBEGIN(result);
|
||||||
* be set
|
break;
|
||||||
*/
|
|
||||||
|
case NOEND_ABSTIME:
|
||||||
|
DATE_NOEND(result);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abstime2tm(abstime, &tz, tm, NULL);
|
abstime2tm(abstime, &tz, tm, NULL);
|
||||||
@ -1452,9 +1522,9 @@ datetime_timestamp(PG_FUNCTION_ARGS)
|
|||||||
TimeADT time = PG_GETARG_TIMEADT(1);
|
TimeADT time = PG_GETARG_TIMEADT(1);
|
||||||
Timestamp result;
|
Timestamp result;
|
||||||
|
|
||||||
result = DatumGetTimestamp(DirectFunctionCall1(date_timestamp,
|
result = date2timestamp(date);
|
||||||
DateADTGetDatum(date)));
|
if (!TIMESTAMP_NOT_FINITE(result))
|
||||||
result += time;
|
result += time;
|
||||||
|
|
||||||
PG_RETURN_TIMESTAMP(result);
|
PG_RETURN_TIMESTAMP(result);
|
||||||
}
|
}
|
||||||
@ -2304,11 +2374,18 @@ datetimetz_timestamptz(PG_FUNCTION_ARGS)
|
|||||||
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
|
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
|
||||||
TimestampTz result;
|
TimestampTz result;
|
||||||
|
|
||||||
|
if (DATE_IS_NOBEGIN(date))
|
||||||
|
TIMESTAMP_NOBEGIN(result);
|
||||||
|
else if (DATE_IS_NOEND(date))
|
||||||
|
TIMESTAMP_NOEND(result);
|
||||||
|
else
|
||||||
|
{
|
||||||
#ifdef HAVE_INT64_TIMESTAMP
|
#ifdef HAVE_INT64_TIMESTAMP
|
||||||
result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
|
result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
|
||||||
#else
|
#else
|
||||||
result = date * (double) SECS_PER_DAY + time->time + time->zone;
|
result = date * (double) SECS_PER_DAY + time->time + time->zone;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PG_RETURN_TIMESTAMP(result);
|
PG_RETURN_TIMESTAMP(result);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.78 2008/10/09 15:49:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.79 2008/10/14 17:12:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1632,6 +1632,11 @@ map_sql_value_to_xml_value(Datum value, Oid type)
|
|||||||
char buf[MAXDATELEN + 1];
|
char buf[MAXDATELEN + 1];
|
||||||
|
|
||||||
date = DatumGetDateADT(value);
|
date = DatumGetDateADT(value);
|
||||||
|
/* XSD doesn't support infinite values */
|
||||||
|
if (DATE_NOT_FINITE(date))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("date out of range")));
|
||||||
j2date(date + POSTGRES_EPOCH_JDATE,
|
j2date(date + POSTGRES_EPOCH_JDATE,
|
||||||
&(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
|
&(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
|
||||||
EncodeDateOnly(&tm, USE_XSD_DATES, buf);
|
EncodeDateOnly(&tm, USE_XSD_DATES, buf);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.497 2008/10/13 16:25:19 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.498 2008/10/14 17:12:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200810131
|
#define CATALOG_VERSION_NO 200810141
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.519 2008/10/13 16:25:20 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.520 2008/10/14 17:12:33 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -1772,6 +1772,8 @@ DESCR("date difference from today preserving months and years");
|
|||||||
DATA(insert OID = 1388 ( timetz PGNSP PGUID 12 1 0 0 f f t f s 1 1266 "1184" _null_ _null_ _null_ timestamptz_timetz _null_ _null_ _null_ ));
|
DATA(insert OID = 1388 ( timetz PGNSP PGUID 12 1 0 0 f f t f s 1 1266 "1184" _null_ _null_ _null_ timestamptz_timetz _null_ _null_ _null_ ));
|
||||||
DESCR("convert timestamptz to timetz");
|
DESCR("convert timestamptz to timetz");
|
||||||
|
|
||||||
|
DATA(insert OID = 1373 ( isfinite PGNSP PGUID 12 1 0 0 f f t f i 1 16 "1082" _null_ _null_ _null_ date_finite _null_ _null_ _null_ ));
|
||||||
|
DESCR("finite date?");
|
||||||
DATA(insert OID = 1389 ( isfinite PGNSP PGUID 12 1 0 0 f f t f i 1 16 "1184" _null_ _null_ _null_ timestamp_finite _null_ _null_ _null_ ));
|
DATA(insert OID = 1389 ( isfinite PGNSP PGUID 12 1 0 0 f f t f i 1 16 "1184" _null_ _null_ _null_ timestamp_finite _null_ _null_ _null_ ));
|
||||||
DESCR("finite timestamp?");
|
DESCR("finite timestamp?");
|
||||||
DATA(insert OID = 1390 ( isfinite PGNSP PGUID 12 1 0 0 f f t f i 1 16 "1186" _null_ _null_ _null_ interval_finite _null_ _null_ _null_ ));
|
DATA(insert OID = 1390 ( isfinite PGNSP PGUID 12 1 0 0 f f t f i 1 16 "1186" _null_ _null_ _null_ interval_finite _null_ _null_ _null_ ));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/date.h,v 1.40 2008/03/21 01:31:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/date.h,v 1.41 2008/10/14 17:12:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -33,6 +33,20 @@ typedef struct
|
|||||||
int32 zone; /* numeric time zone, in seconds */
|
int32 zone; /* numeric time zone, in seconds */
|
||||||
} TimeTzADT;
|
} TimeTzADT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Infinity and minus infinity must be the max and min values of DateADT.
|
||||||
|
* We could use INT_MIN and INT_MAX here, but seems better to not assume that
|
||||||
|
* int32 == int.
|
||||||
|
*/
|
||||||
|
#define DATEVAL_NOBEGIN ((DateADT) (-0x7fffffff - 1))
|
||||||
|
#define DATEVAL_NOEND ((DateADT) 0x7fffffff)
|
||||||
|
|
||||||
|
#define DATE_NOBEGIN(j) ((j) = DATEVAL_NOBEGIN)
|
||||||
|
#define DATE_IS_NOBEGIN(j) ((j) == DATEVAL_NOBEGIN)
|
||||||
|
#define DATE_NOEND(j) ((j) = DATEVAL_NOEND)
|
||||||
|
#define DATE_IS_NOEND(j) ((j) == DATEVAL_NOEND)
|
||||||
|
#define DATE_NOT_FINITE(j) (DATE_IS_NOBEGIN(j) || DATE_IS_NOEND(j))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros for fmgr-callable functions.
|
* Macros for fmgr-callable functions.
|
||||||
*
|
*
|
||||||
@ -90,6 +104,7 @@ extern Datum date_le(PG_FUNCTION_ARGS);
|
|||||||
extern Datum date_gt(PG_FUNCTION_ARGS);
|
extern Datum date_gt(PG_FUNCTION_ARGS);
|
||||||
extern Datum date_ge(PG_FUNCTION_ARGS);
|
extern Datum date_ge(PG_FUNCTION_ARGS);
|
||||||
extern Datum date_cmp(PG_FUNCTION_ARGS);
|
extern Datum date_cmp(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum date_finite(PG_FUNCTION_ARGS);
|
||||||
extern Datum date_larger(PG_FUNCTION_ARGS);
|
extern Datum date_larger(PG_FUNCTION_ARGS);
|
||||||
extern Datum date_smaller(PG_FUNCTION_ARGS);
|
extern Datum date_smaller(PG_FUNCTION_ARGS);
|
||||||
extern Datum date_mi(PG_FUNCTION_ARGS);
|
extern Datum date_mi(PG_FUNCTION_ARGS);
|
||||||
|
@ -1157,3 +1157,30 @@ SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC'); -- 0011-01-01 BC
|
|||||||
Mon Jan 01 00:00:00 0011 PST BC
|
Mon Jan 01 00:00:00 0011 PST BC
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- test infinity
|
||||||
|
--
|
||||||
|
select 'infinity'::date, '-infinity'::date;
|
||||||
|
date | date
|
||||||
|
----------+-----------
|
||||||
|
infinity | -infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select 'infinity'::date > 'today'::date as t;
|
||||||
|
t
|
||||||
|
---
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select '-infinity'::date < 'today'::date as t;
|
||||||
|
t
|
||||||
|
---
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date);
|
||||||
|
isfinite | isfinite | isfinite
|
||||||
|
----------+----------+----------
|
||||||
|
f | f | t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -269,3 +269,10 @@ SELECT DATE_TRUNC('CENTURY', DATE '0055-08-10 BC'); -- 0100-01-01 BC
|
|||||||
SELECT DATE_TRUNC('DECADE', DATE '1993-12-25'); -- 1990-01-01
|
SELECT DATE_TRUNC('DECADE', DATE '1993-12-25'); -- 1990-01-01
|
||||||
SELECT DATE_TRUNC('DECADE', DATE '0004-12-25'); -- 0001-01-01 BC
|
SELECT DATE_TRUNC('DECADE', DATE '0004-12-25'); -- 0001-01-01 BC
|
||||||
SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC'); -- 0011-01-01 BC
|
SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC'); -- 0011-01-01 BC
|
||||||
|
--
|
||||||
|
-- test infinity
|
||||||
|
--
|
||||||
|
select 'infinity'::date, '-infinity'::date;
|
||||||
|
select 'infinity'::date > 'today'::date as t;
|
||||||
|
select '-infinity'::date < 'today'::date as t;
|
||||||
|
select isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user