Commit 6f58115d authored by Thomas G. Lockhart's avatar Thomas G. Lockhart

Measure the current transaction time to milliseconds.

Define a new function, GetCurrentTransactionStartTimeUsec() to get the time
 to this precision.
Allow now() and timestamp 'now' to use this higher precision result so
 we now have fractional seconds in this "constant".
Add timestamp without time zone type.
Move previous timestamp type to timestamp with time zone.
Accept another ISO variant for date/time values: yyyy-mm-ddThh:mm:ss
 (note the "T" separating the day from hours information).
Remove 'current' from date/time types; convert to 'now' in input.
Separate time and timetz regression tests.
Separate timestamp and timestamptz regression test.
parent 1f075a32
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.109 2001/08/25 18:52:41 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.110 2001/09/28 08:08:57 thomas Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
......@@ -369,6 +369,21 @@ GetCurrentTransactionStartTime(void)
}
/* --------------------------------
* GetCurrentTransactionStartTimeUsec
* --------------------------------
*/
AbsoluteTime
GetCurrentTransactionStartTimeUsec(int *msec)
{
TransactionState s = CurrentTransactionState;
*msec = s->startTimeMsec;
return s->startTime;
}
/* --------------------------------
* TransactionIdIsCurrentTransactionId
* --------------------------------
......@@ -859,7 +874,10 @@ StartTransaction(void)
*/
s->commandId = FirstCommandId;
s->scanCommandId = FirstCommandId;
#if NOT_USED
s->startTime = GetCurrentAbsoluteTime();
#endif
s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeMsec));
/*
* initialize the various transaction subsystems
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.253 2001/09/23 03:39:01 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.254 2001/09/28 08:09:09 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -259,7 +259,7 @@ static void doNegateFloat(Value *v);
%type <str> opt_charset, opt_collate
%type <str> opt_float
%type <ival> opt_numeric, opt_decimal
%type <boolean> opt_varying, opt_timezone
%type <boolean> opt_varying, opt_timezone, opt_timezone_x
%type <ival> Iconst
%type <str> Sconst, comment_text
......@@ -4229,10 +4229,16 @@ ConstDatetime: datetime
$$->name = xlateSqlType($1);
$$->typmod = -1;
}
| TIMESTAMP opt_timezone
| TIMESTAMP opt_timezone_x
{
$$ = makeNode(TypeName);
if ($2)
$$->name = xlateSqlType("timestamptz");
else
$$->name = xlateSqlType("timestamp");
/* XXX the timezone field seems to be unused
* - thomas 2001-09-06
*/
$$->timezone = $2;
$$->typmod = -1;
}
......@@ -4263,6 +4269,16 @@ datetime: YEAR_P { $$ = "year"; }
| SECOND_P { $$ = "second"; }
;
/* XXX Make the default be WITH TIME ZONE for 7.2 to help with database upgrades
* but revert this back to WITHOUT TIME ZONE for 7.3.
* Do this by simply reverting opt_timezone_x to opt_timezone - thomas 2001-09-06
*/
opt_timezone_x: WITH TIME ZONE { $$ = TRUE; }
| WITHOUT TIME ZONE { $$ = FALSE; }
| /*EMPTY*/ { $$ = TRUE; }
;
opt_timezone: WITH TIME ZONE { $$ = TRUE; }
| WITHOUT TIME ZONE { $$ = FALSE; }
| /*EMPTY*/ { $$ = FALSE; }
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.60 2001/06/24 02:41:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.61 2001/09/28 08:09:09 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -498,6 +498,7 @@ TypeCategory(Oid inType)
case (TIMETZOID):
case (ABSTIMEOID):
case (TIMESTAMPOID):
case (TIMESTAMPTZOID):
result = DATETIME_TYPE;
break;
......@@ -577,7 +578,10 @@ PreferredType(CATEGORY category, Oid type)
break;
case (DATETIME_TYPE):
if (type == DATEOID)
result = TIMESTAMPOID;
else
result = TIMESTAMPTZOID;
break;
case (TIMESPAN_TYPE):
......@@ -634,10 +638,14 @@ PromoteTypeToNext(Oid inType)
break;
case (DATEOID):
case (ABSTIMEOID):
result = TIMESTAMPOID;
break;
case (ABSTIMEOID):
case (TIMESTAMPOID):
result = TIMESTAMPTZOID;
break;
case (TIMEOID):
case (RELTIMEOID):
result = INTERVALOID;
......@@ -646,7 +654,7 @@ PromoteTypeToNext(Oid inType)
case (BOOLOID):
case (TEXTOID):
case (FLOAT8OID):
case (TIMESTAMPOID):
case (TIMESTAMPTZOID):
case (INTERVALOID):
default:
result = inType;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.101 2001/09/20 23:31:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.102 2001/09/28 08:09:09 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.72 2001/09/17 01:06:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.73 2001/09/28 08:09:09 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -462,10 +462,13 @@ FigureColname(Node *node)
{
if (node == NULL)
return "?column?";
switch (nodeTag(node))
{
case T_Ident:
return ((Ident *) node)->name;
case T_A_Const:
return (FigureColname((Node *)((A_Const *) node)->typename));
case T_Attr:
{
List *attrs = ((Attr *) node)->attrs;
......@@ -481,7 +484,15 @@ FigureColname(Node *node)
case T_FuncCall:
return ((FuncCall *) node)->funcname;
case T_TypeCast:
return FigureColname(((TypeCast *) node)->arg);
{
char *name;
name = FigureColname(((TypeCast *) node)->arg);
if (strcmp(name, "?column?") == 0)
name = FigureColname((Node *)((TypeCast *) node)->typename);
return name;
}
break;
case T_CaseExpr:
{
char *name;
......@@ -492,6 +503,8 @@ FigureColname(Node *node)
return name;
}
break;
case T_TypeName:
return ((TypeName *) node)->name;
default:
break;
}
......
......@@ -8,21 +8,24 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.57 2001/05/03 19:00:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.58 2001/09/28 08:09:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <ctype.h>
#include <limits.h>
#include <time.h>
#include <float.h>
#include "access/hash.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/nabstime.h"
#include "utils/timestamp.h"
/*****************************************************************************
......@@ -58,13 +61,13 @@ date_in(PG_FUNCTION_ARGS)
break;
case DTK_CURRENT:
elog(ERROR, "Date CURRENT no longer supported"
"\n\tdate_in() internal coding error");
GetCurrentTime(tm);
break;
case DTK_EPOCH:
tm->tm_year = 1970;
tm->tm_mon = 1;
tm->tm_mday = 1;
GetEpochTime(tm);
break;
default:
......@@ -224,6 +227,46 @@ date_timestamp(PG_FUNCTION_ARGS)
{
DateADT dateVal = PG_GETARG_DATEADT(0);
Timestamp result;
/* date is days since 2000, timestamp is seconds since same... */
result = dateVal * 86400.0;
PG_RETURN_TIMESTAMP(result);
}
/* timestamp_date()
* Convert timestamp to date data type.
*/
Datum
timestamp_date(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
DateADT result;
struct tm tt,
*tm = &tt;
double fsec;
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_NULL();
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to convert timestamp to date");
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
PG_RETURN_DATEADT(result);
}
/* date_timestamptz()
* Convert date to timestamp with time zone data type.
*/
Datum
date_timestamptz(PG_FUNCTION_ARGS)
{
DateADT dateVal = PG_GETARG_DATEADT(0);
TimestampTz result;
struct tm tt,
*tm = &tt;
time_t utime;
......@@ -259,32 +302,25 @@ date_timestamp(PG_FUNCTION_ARGS)
}
/* timestamp_date()
* Convert timestamp to date data type.
/* timestamptz_date()
* Convert timestamp with time zone to date data type.
*/
Datum
timestamp_date(PG_FUNCTION_ARGS)
timestamptz_date(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
DateADT result;
struct tm tt,
*tm = &tt;
int tz;
double fsec;
int tz;
char *tzn;
if (TIMESTAMP_NOT_FINITE(timestamp))
elog(ERROR, "Unable to convert timestamp to date");
PG_RETURN_NULL();
if (TIMESTAMP_IS_EPOCH(timestamp))
timestamp2tm(SetTimestamp(timestamp), NULL, tm, &fsec, NULL);
else if (TIMESTAMP_IS_CURRENT(timestamp))
timestamp2tm(SetTimestamp(timestamp), &tz, tm, &fsec, &tzn);
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert timestamp to date");
}
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
......@@ -316,15 +352,6 @@ abstime_date(PG_FUNCTION_ARGS)
* will be set
*/
case EPOCH_ABSTIME:
result = date2j(1970, 1, 1) - date2j(2000, 1, 1);
break;
case CURRENT_ABSTIME:
GetCurrentTime(tm);
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
break;
default:
abstime2tm(abstime, &tz, tm, NULL);
result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
......@@ -664,22 +691,13 @@ timestamp_time(PG_FUNCTION_ARGS)
TimeADT result;
struct tm tt,
*tm = &tt;
int tz;
double fsec;
char *tzn;
if (TIMESTAMP_NOT_FINITE(timestamp))
elog(ERROR, "Unable to convert timestamp to date");
PG_RETURN_NULL();
if (TIMESTAMP_IS_EPOCH(timestamp))
timestamp2tm(SetTimestamp(timestamp), NULL, tm, &fsec, NULL);
else if (TIMESTAMP_IS_CURRENT(timestamp))
timestamp2tm(SetTimestamp(timestamp), &tz, tm, &fsec, &tzn);
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to convert timestamp to date");
}
result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
......@@ -736,6 +754,24 @@ interval_time(PG_FUNCTION_ARGS)
PG_RETURN_TIMEADT(result);
}
/* time_mi_time()
* Subtract two times to produce an interval.
*/
Datum
time_mi_time(PG_FUNCTION_ARGS)
{
TimeADT time1 = PG_GETARG_TIMEADT(0);
TimeADT time2 = PG_GETARG_TIMEADT(1);
Interval *result;
result = (Interval *) palloc(sizeof(Interval));
result->time = time2 - time1;
result->month = 0;
PG_RETURN_INTERVAL_P(result);
}
/* time_pl_interval()
* Add interval to time.
*/
......@@ -918,7 +954,12 @@ timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
* If same GMT time, sort by timezone; we only want to say that two
* timetz's are equal if both the time and zone parts are equal.
*/
return time1->zone - time2->zone;
if (time1->zone > time2->zone)
return 1;
if (time1->zone < time2->zone)
return -1;
return 0;
}
Datum
......@@ -1199,13 +1240,48 @@ overlaps_timetz(PG_FUNCTION_ARGS)
#undef TIMETZ_LT
}
/* timestamp_timetz()
Datum
timetz_time(PG_FUNCTION_ARGS)
{
TimeTzADT *timetz = PG_GETARG_TIMETZADT_P(0);
TimeADT result;
/* swallow the time zone and just return the time */
result = timetz->time;
PG_RETURN_TIMEADT(result);
}
Datum
time_timetz(PG_FUNCTION_ARGS)
{
TimeADT time = PG_GETARG_TIMEADT(0);
TimeTzADT *result;
struct tm tt,
*tm = &tt;
int tz;
GetCurrentTime(tm);
tz = DetermineLocalTimeZone(tm);
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
result->time = time;
result->zone = tz;
PG_RETURN_TIMETZADT_P(result);
}
/* timestamptz_timetz()
* Convert timestamp to timetz data type.
*/
Datum
timestamp_timetz(PG_FUNCTION_ARGS)
timestamptz_timetz(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
TimeTzADT *result;
struct tm tt,
*tm = &tt;
......@@ -1214,20 +1290,10 @@ timestamp_timetz(PG_FUNCTION_ARGS)
char *tzn;
if (TIMESTAMP_NOT_FINITE(timestamp))
elog(ERROR, "Unable to convert timestamp to date");
PG_RETURN_NULL();
if (TIMESTAMP_IS_EPOCH(timestamp))
{
timestamp2tm(SetTimestamp(timestamp), NULL, tm, &fsec, NULL);
tz = 0;
}
else if (TIMESTAMP_IS_CURRENT(timestamp))
timestamp2tm(SetTimestamp(timestamp), &tz, tm, &fsec, &tzn);
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert timestamp to date");
}
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
......@@ -1238,18 +1304,18 @@ timestamp_timetz(PG_FUNCTION_ARGS)
}
/* datetimetz_timestamp()
* Convert date and timetz to timestamp data type.
/* datetimetz_timestamptz()
* Convert date and timetz to timestamp with time zone data type.
* Timestamp is stored in GMT, so add the time zone
* stored with the timetz to the result.
* - thomas 2000-03-10
*/
Datum
datetimetz_timestamp(PG_FUNCTION_ARGS)
datetimetz_timestamptz(PG_FUNCTION_ARGS)
{
DateADT date = PG_GETARG_DATEADT(0);
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
Timestamp result;
TimestampTz result;
result = date * 86400.0 + time->time + time->zone;
......@@ -1310,3 +1376,83 @@ text_timetz(PG_FUNCTION_ARGS)
return DirectFunctionCall1(timetz_in,
CStringGetDatum(dstr));
}
/* timetz_zone()
* Encode time with time zone type with specified time zone.
*/
Datum
timetz_zone(PG_FUNCTION_ARGS)
{
text *zone = PG_GETARG_TEXT_P(0);
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
TimeTzADT *result;
TimeADT time1;
int tz;
int type,
val;
int i;
char *up,
*lp,
lowzone[MAXDATELEN + 1];
if (VARSIZE(zone) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Time zone '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(zone))));
up = VARDATA(zone);
lp = lowzone;
for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
*lp++ = tolower((unsigned char) *up++);
*lp = '\0';
type = DecodeSpecial(0, lowzone, &val);
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
if ((type == TZ) || (type == DTZ))
{
tz = val * 60;
time1 = time->time - time->zone + tz;
TMODULO(result->time, time1, 86400e0);
if (result->time < 0)
result->time += 86400;
result->zone = tz;
}
else
{
elog(ERROR, "Time zone '%s' not recognized", lowzone);
PG_RETURN_NULL();
}
PG_RETURN_TIMETZADT_P(result);
} /* timetz_zone() */
/* timetz_izone()
* Encode time with time zone type with specified time interval as time zone.
*/
Datum
timetz_izone(PG_FUNCTION_ARGS)
{
Interval *zone = PG_GETARG_INTERVAL_P(0);
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
TimeTzADT *result;
TimeADT time1;
int tz;
if (zone->month != 0)
elog(ERROR, "INTERVAL time zone '%s' not legal (month specified)",
DatumGetCString(DirectFunctionCall1(interval_out,
PointerGetDatum(zone))));
tz = -(zone->time);
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
time1 = time->time - time->zone + tz;
TMODULO(result->time, time1, 86400e0);
if (result->time < 0)
result->time += 86400;
result->zone = tz;
PG_RETURN_TIMETZADT_P(result);
} /* timetz_izone() */
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.66 2001/07/10 01:41:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.67 2001/09/28 08:09:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -47,10 +47,10 @@ int day_tab[2][13] = {
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", NULL};
"Thursday", "Friday", "Saturday", NULL};
/*****************************************************************************
......@@ -71,7 +71,7 @@ char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
* the text field is not guaranteed to be NULL-terminated.
*/
static datetkn datetktbl[] = {
/* text token lexval */
/* text, token, lexval */
{EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */
{"acsst", DTZ, 63}, /* Cent. Australia */
{"acst", TZ, 57}, /* Cent. Australia */
......@@ -104,6 +104,7 @@ static datetkn datetktbl[] = {
{"cetdst", DTZ, 12}, /* Central European Dayl.Time */
{"cst", TZ, NEG(36)}, /* Central Standard Time */
{DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */
{"d", UNITS, DAY}, /* "day of month" for ISO input */
{"dec", MONTH, 12},
{"december", MONTH, 12},
{"dnt", TZ, 6}, /* Dansk Normal Tid */
......@@ -124,6 +125,7 @@ static datetkn datetktbl[] = {
{"fwt", DTZ, 12}, /* French Winter Time */
{"gmt", TZ, 0}, /* Greenwish Mean Time */
{"gst", TZ, 60}, /* Guam Std Time, USSR Zone 9 */
{"h", UNITS, HOUR}, /* "hour" */
{"hdt", DTZ, NEG(54)}, /* Hawaii/Alaska */
{"hmt", DTZ, 18}, /* Hellas ? ? */
{"hst", TZ, NEG(60)}, /* Hawaii Std Time */
......@@ -134,16 +136,19 @@ static datetkn datetktbl[] = {
/* "invalid" reserved for invalid time */
{"ist", TZ, 12}, /* Israel */
{"it", TZ, 21}, /* Iran Time */
{"j", UNITS, JULIAN},
{"jan", MONTH, 1},
{"january", MONTH, 1},
{"jd", UNITS, JULIAN},
{"jst", TZ, 54}, /* Japan Std Time,USSR Zone 8 */
{"jt", TZ, 45}, /* Java Time */
{"jul", MONTH, 7},
{"july", MONTH, 7},
{"julian", UNITS, JULIAN},
{"jun", MONTH, 6},
{"june", MONTH, 6},
{"kst", TZ, 54}, /* Korea Standard Time */
{"ligt", TZ, 60}, /* From Melbourne, Australia */
{"m", UNITS, MONTH}, /* "month" for ISO input */
{"mar", MONTH, 3},
{"march", MONTH, 3},
{"may", MONTH, 5},
......@@ -153,6 +158,7 @@ static datetkn datetktbl[] = {
{"metdst", DTZ, 12}, /* Middle Europe Daylight Time */
{"mewt", TZ, 6}, /* Middle Europe Winter Time */
{"mez", TZ, 6}, /* Middle Europe Zone */
{"mm", UNITS, MINUTE}, /* "minute" for ISO input */
{"mon", DOW, 1},
{"monday", DOW, 1},
{"mst", TZ, NEG(42)}, /* Mountain Standard Time */
......@@ -174,6 +180,7 @@ static datetkn datetktbl[] = {
{"pdt", DTZ, NEG(42)}, /* Pacific Daylight Time */
{"pm", AMPM, PM},
{"pst", TZ, NEG(48)}, /* Pacific Standard Time */
{"s", UNITS, SECOND}, /* "seconds" for ISO input */
{"sadt", DTZ, 63}, /* S. Australian Dayl. Time */
{"sast", TZ, 57}, /* South Australian Std Time */
{"sat", DOW, 6},
......@@ -186,6 +193,7 @@ static datetkn datetktbl[] = {
{"sun", DOW, 0},
{"sunday", DOW, 0},
{"swt", TZ, 6}, /* Swedish Winter Time */
{"t", DTK_ISO_TIME, 0}, /* Filler for ISO time fields */
{"thu", DOW, 4},
{"thur", DOW, 4},
{"thurs", DOW, 4},
......@@ -208,6 +216,7 @@ static datetkn datetktbl[] = {
{"wet", TZ, 0}, /* Western Europe */
{"wetdst", DTZ, 6}, /* Western Europe */
{"wst", TZ, 48}, /* West Australian Std Time */
{"y", UNITS, YEAR}, /* "year" for ISO input */
{"ydt", DTZ, NEG(48)}, /* Yukon Daylight Time */
{YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */
{"yst", TZ, NEG(54)}, /* Yukon Standard Time */
......@@ -222,7 +231,7 @@ static unsigned int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
/* Used for SET australian_timezones to override North American ones */
static datetkn australian_datetktbl[] = {
{"cst", TZ, 63}, /* Australia Eastern Std Time */
{"cst", TZ, 63}, /* Australia Central Std Time */
{"est", TZ, 60}, /* Australia Eastern Std Time */
{"sat", TZ, 57},
};
......@@ -231,7 +240,7 @@ static unsigned int australian_szdatetktbl = sizeof australian_datetktbl /
sizeof australian_datetktbl[0];
static datetkn deltatktbl[] = {
/* text token lexval */
/* text, token, lexval */
{"@", IGNORE, 0}, /* postgres relative time prefix */
{DAGO, AGO, 0}, /* "ago" indicates negative time offset */
{"c", UNITS, DTK_CENTURY}, /* "century" relative time units */
......@@ -329,7 +338,8 @@ datetkn *deltacache[MAXDATEFIELDS] = {NULL};
* Use the algorithm by Henry Fliegel, a former NASA/JPL colleague
* now at Aerospace Corp. (hi, Henry!)
*
* These routines will be used by other date/time packages - tgl 97/02/25
* These routines will be used by other date/time packages
* - thomas 97/02/25
*/
int
......@@ -413,6 +423,7 @@ ParseDateTime(char *timestr, char *lowstr,
if (*cp == ':')
{
ftype[nf] = DTK_TIME;
*lp++ = *cp++;
while (isdigit((unsigned char) *cp) ||
(*cp == ':') || (*cp == '.'))
*lp++ = *cp++;
......@@ -422,10 +433,20 @@ ParseDateTime(char *timestr, char *lowstr,
else if ((*cp == '-') || (*cp == '/') || (*cp == '.'))
{
ftype[nf] = DTK_DATE;
*lp++ = *cp++;
/* second field is all digits? then no embedded text month */
if (isdigit((unsigned char) *cp))
{
while (isdigit((unsigned char) *cp) || (*cp == '-') ||
(*cp == '/') || (*cp == '.'))
*lp++ = *cp++;
}
else
{
while (isalnum((unsigned char) *cp) || (*cp == '-') ||
(*cp == '/') || (*cp == '.'))
*lp++ = tolower((unsigned char) *cp++);
}
}
/*
......@@ -539,7 +560,7 @@ ParseDateTime(char *timestr, char *lowstr,
* Use the system-provided functions to get the current time zone
* if not specified in the input string.
* If the date is outside the time_t system-supported time range,
* then assume GMT time zone. - tgl 97/05/27
* then assume GMT time zone. - thomas 1997/05/27
*/
int
DecodeDateTime(char **field, int *ftype, int nf,
......@@ -548,6 +569,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
int fmask = 0,
tmask,
type;
int ptype = 0; /* "prefix type" for ISO y2001m02d04 format */
int i;
int flen,
val;
......@@ -556,13 +578,16 @@ DecodeDateTime(char **field, int *ftype, int nf,
int is2digits = FALSE;
int bc = FALSE;
/* We'll insist on at least all of the date fields,
* but initialize the remaining fields in case they are not
* set later...
*/
*dtype = DTK_DATE;
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
*fsec = 0;
tm->tm_isdst = -1; /* don't know daylight savings time status
* apriori */
tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
if (tzp != NULL)
*tzp = 0;
......@@ -571,13 +596,32 @@ DecodeDateTime(char **field, int *ftype, int nf,
switch (ftype[i])
{
case DTK_DATE:
/* Previous field was a label for "julian date"?
* then this should be a julian date with fractional day...
*/
if (ptype == JULIAN)
{
char *cp;
double dt, date, time;
/*
* Already have a date? Then this might be a POSIX time
* zone with an embedded dash (e.g. "PST-3" == "EST") -
* thomas 2000-03-15
dt = strtod(field[i], &cp);
if (*cp != '\0')
return -1;
time = dt * 86400;
TMODULO(time, date, 86400e0);
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
dt2time(time, &tm->tm_hour, &tm->tm_min, fsec);
tmask = DTK_DATE_M | DTK_TIME_M;
*dtype = DTK_DATE;
}
/* Already have a date? Then this might be a POSIX time
* zone with an embedded dash (e.g. "PST-3" == "EST")
* - thomas 2000-03-15
*/
if ((fmask & DTK_DATE_M) == DTK_DATE_M)
else if ((fmask & DTK_DATE_M) == DTK_DATE_M)
{
if ((tzp == NULL)
|| (DecodePosixTimezone(field[i], tzp) != 0))
......@@ -587,15 +631,16 @@ DecodeDateTime(char **field, int *ftype, int nf,
tmask = DTK_M(TZ);
}
else if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
{
return -1;
}
break;
case DTK_TIME:
if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
return -1;
/*
* check upper limit on hours; other limits checked in
/* Check upper limit on hours; other limits checked in
* DecodeTime()
*/
if (tm->tm_hour > 23)
......@@ -618,7 +663,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
* PST)
*/
if ((i > 0) && ((fmask & DTK_M(TZ)) != 0)
&& (ftype[i - 1] == DTK_TZ) && (isalpha((unsigned char) *field[i - 1])))
&& (ftype[i - 1] == DTK_TZ)
&& (isalpha((unsigned char) *field[i - 1])))
{
*tzp -= tz;
tmask = 0;
......@@ -634,20 +680,80 @@ DecodeDateTime(char **field, int *ftype, int nf,
case DTK_NUMBER:
flen = strlen(field[i]);
/* Was this an "ISO date" with embedded field labels?
* An example is "y2001m02d04" - thomas 2001-02-04
*/
if (ptype != 0)
{
char *cp;
int val;
val = strtol(field[i], &cp, 10);
if (*cp != '\0')
return -1;
switch (ptype) {
case YEAR:
tm->tm_year = val;
tmask = DTK_M(ptype);
break;
case MONTH:
tm->tm_mon = val;
tmask = DTK_M(ptype);
break;
case DAY:
tm->tm_mday = val;
tmask = DTK_M(ptype);
break;
case HOUR:
tm->tm_hour = val;
tmask = DTK_M(ptype);
break;
case MINUTE:
tm->tm_min = val;
tmask = DTK_M(ptype);
break;
case SECOND:
tm->tm_sec = val;
tmask = DTK_M(ptype);
break;
case JULIAN:
/* previous field was a label for "julian date"?
* then this is a julian day with no fractional part
* (see DTK_DATE for cases involving fractional parts)
*/
j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
tmask = DTK_DATE_M;
break;
default:
return -1;
break;
}
ptype = 0;
*dtype = DTK_DATE;
}
/*
* long numeric string and either no date or no time read
* yet? then interpret as a concatenated date or time...
*/
if ((flen > 4) && !((fmask & DTK_DATE_M) && (fmask & DTK_TIME_M)))
else if ((flen > 4) && !((fmask & DTK_DATE_M) && (fmask & DTK_TIME_M)))
{
if (DecodeNumberField(flen, field[i], fmask, &tmask, tm, fsec, &is2digits) != 0)
return -1;
}
/* otherwise it is a single date/time field... */
else
else if (DecodeNumber(flen, field[i], fmask, &tmask, tm, fsec, &is2digits) != 0)
{
if (DecodeNumber(flen, field[i], fmask, &tmask, tm, fsec, &is2digits) != 0)
return -1;
}
break;
......@@ -664,10 +770,15 @@ DecodeDateTime(char **field, int *ftype, int nf,
case RESERV:
switch (val)
{
case DTK_CURRENT:
case DTK_NOW:
tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ));
*dtype = DTK_DATE;
#if NOT_USED
GetCurrentTime(tm);
#else
GetCurrentTimeUsec(tm, fsec);
#endif
if (tzp != NULL)
*tzp = CTimeZone;
break;
......@@ -786,6 +897,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
tm->tm_wday = val;
break;
case UNITS:
ptype = val;
tmask = 0;
break;
case DTK_ISO_TIME:
if ((i < 1) || (i >= (nf-1))
|| (ftype[i-1] != DTK_DATE)
|| (ftype[i+1] != DTK_TIME))
return -1;
break;
default:
return -1;
}
......@@ -1182,6 +1305,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
str++;
}
/* Just get rid of any non-digit, non-alpha characters... */
if (*str != '\0')
*str++ = '\0';
nf++;
......@@ -1362,8 +1486,9 @@ DecodeNumber(int flen, char *str, int fmask,
/*
* Enough digits to be unequivocal year? Used to test for 4 digits or
* more, but we now test first for a three-digit doy so anything
* bigger than two digits had better be an explicit year. - thomas
* 1999-01-09 Back to requiring a 4 digit year. We accept a two digit
* bigger than two digits had better be an explicit year.
* - thomas 1999-01-09
* Back to requiring a 4 digit year. We accept a two digit
* year farther down. - thomas 2000-03-28
*/
else if (flen >= 4)
......@@ -1613,7 +1738,7 @@ DecodeSpecial(int field, char *lowtoken, int *val)
datecache[field] = tp;
if (tp == NULL)
{
type = IGNORE;
type = UNKNOWN_FIELD;
*val = 0;
}
else
......@@ -1747,10 +1872,11 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
case DTK_NUMBER:
val = strtol(field[i], &cp, 10);
if (*cp == '.')
{
if (type == IGNORE)
type = DTK_SECOND;
if (*cp == '.')
{
fval = strtod(cp, &cp);
if (*cp != '\0')
return -1;
......@@ -1928,7 +2054,7 @@ DecodeUnits(int field, char *lowtoken, int *val)
deltacache[field] = tp;
if (tp == NULL)
{
type = IGNORE;
type = UNKNOWN_FIELD;
*val = 0;
}
else
......@@ -1985,8 +2111,8 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
switch (style)
{
/* compatible with ISO date formats */
case USE_ISO_DATES:
/* compatible with ISO date formats */
if (tm->tm_year > 0)
sprintf(str, "%04d-%02d-%02d",
tm->tm_year, tm->tm_mon, tm->tm_mday);
......@@ -1995,8 +2121,8 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
-(tm->tm_year - 1), tm->tm_mon, tm->tm_mday, "BC");
break;
/* compatible with Oracle/Ingres date formats */
case USE_SQL_DATES:
/* compatible with Oracle/Ingres date formats */
if (EuroDates)
sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon);
else
......@@ -2007,8 +2133,8 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
sprintf((str + 5), "/%04d %s", -(tm->tm_year - 1), "BC");
break;
/* German-style date format */
case USE_GERMAN_DATES:
/* German-style date format */
sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon);
if (tm->tm_year > 0)
sprintf((str + 5), ".%04d", tm->tm_year);
......@@ -2016,9 +2142,9 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
sprintf((str + 5), ".%04d %s", -(tm->tm_year - 1), "BC");
break;
/* traditional date-only style for Postgres */
case USE_POSTGRES_DATES:
default:
/* traditional date-only style for Postgres */
if (EuroDates)
sprintf(str, "%02d-%02d", tm->tm_mday, tm->tm_mon);
else
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.15 2001/09/21 15:27:38 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.16 2001/09/28 08:09:10 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -205,6 +205,10 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
break;
case TIMESTAMPOID:
buf = pstrdup("timestamp without time zone");
break;
case TIMESTAMPTZOID:
buf = pstrdup("timestamp with time zone");
break;
......
/* -----------------------------------------------------------------------
* formatting.c
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.40 2001/09/12 04:01:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.41 2001/09/28 08:09:11 thomas Exp $
*
*
* Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
......@@ -2753,6 +2753,30 @@ timestamp_to_char(PG_FUNCTION_ARGS)
Timestamp dt = PG_GETARG_TIMESTAMP(0);
text *fmt = PG_GETARG_TEXT_P(1), *res;
TmToChar tmtc;
int r = 0;
if ((VARSIZE(fmt) - VARHDRSZ) <=0 || TIMESTAMP_NOT_FINITE(dt))
PG_RETURN_NULL();
ZERO_tmtc(&tmtc);
r = timestamp2tm(dt, NULL, tmtcTm(&tmtc), &tmtcFsec(&tmtc), NULL);
if (r != 0)
elog(ERROR, "to_char(): Unable to convert timestamp to tm");
if (!(res=datetime_to_char_body(&tmtc, fmt)))
PG_RETURN_NULL();
PG_RETURN_TEXT_P(res);
}
Datum
timestamptz_to_char(PG_FUNCTION_ARGS)
{
TimestampTz dt = PG_GETARG_TIMESTAMP(0);
text *fmt = PG_GETARG_TEXT_P(1), *res;
TmToChar tmtc;
int tz, r = 0;
if ((VARSIZE(fmt) - VARHDRSZ) <=0 || TIMESTAMP_NOT_FINITE(dt))
......@@ -2760,11 +2784,6 @@ timestamp_to_char(PG_FUNCTION_ARGS)
ZERO_tmtc(&tmtc);
if (TIMESTAMP_IS_EPOCH(dt))
r = timestamp2tm(SetTimestamp(dt), NULL, tmtcTm(&tmtc), &tmtcFsec(&tmtc), NULL);
else if (TIMESTAMP_IS_CURRENT(dt))
r = timestamp2tm(SetTimestamp(dt), &tz, tmtcTm(&tmtc), &tmtcFsec(&tmtc), &tmtcTzn(&tmtc));
else
r = timestamp2tm(dt, &tz, tmtcTm(&tmtc), &tmtcFsec(&tmtc), &tmtcTzn(&tmtc));
if (r != 0)
......@@ -2805,7 +2824,7 @@ interval_to_char(PG_FUNCTION_ARGS)
/* ---------------------
* TO_TIMESTAMP()
*
* Make Timestamp from date_str which is formated at argument 'fmt'
* Make Timestamp from date_str which is formatted at argument 'fmt'
* ( to_timestamp is reverse to_char() )
* ---------------------
*/
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.85 2001/05/03 19:00:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.86 2001/09/28 08:09:11 thomas Exp $
*
* NOTES
*
......@@ -179,6 +179,84 @@ GetCurrentAbsoluteTime(void)
} /* GetCurrentAbsoluteTime() */
/* GetCurrentAbsoluteTime()
* Get the current system time. Set timezone parameters if not specified elsewhere.
* Define HasTZSet to allow clients to specify the default timezone.
*
* Returns the number of seconds since epoch (January 1 1970 GMT)
*/
AbsoluteTime
GetCurrentAbsoluteTimeUsec(int *usec)
{
time_t now;
struct timeval tp;
// struct timezone tpz;
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
struct tm *tm;
#else
struct timeb tb; /* the old V7-ism */
#endif
gettimeofday(&tp, NULL);
now = tp.tv_sec;
*usec = tp.tv_usec;
#ifdef NOT_USED
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
now = time(NULL);
#else
ftime(&tb);
now = tb.time;
#endif
#endif
if (!HasCTZSet)
{
#if defined(HAVE_TM_ZONE)
tm = localtime(&now);
CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
CDayLight = (tm->tm_isdst > 0);
#ifdef NOT_USED
/*
* XXX is there a better way to get local timezone string w/o
* tzname? - tgl 97/03/18
*/
strftime(CTZName, MAXTZLEN, "%Z", tm);
#endif
/*
* XXX FreeBSD man pages indicate that this should work - thomas
* 1998-12-12
*/
strcpy(CTZName, tm->tm_zone);
#elif defined(HAVE_INT_TIMEZONE)
tm = localtime(&now);
CDayLight = tm->tm_isdst;
CTimeZone = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL);
strcpy(CTZName, tzname[tm->tm_isdst]);
#else /* neither HAVE_TM_ZONE nor
* HAVE_INT_TIMEZONE */
CTimeZone = tb.timezone * 60;
CDayLight = (tb.dstflag != 0);
/*
* XXX does this work to get the local timezone string in V7? -
* tgl 97/03/18
*/
strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
};
return (AbsoluteTime) now;
} /* GetCurrentAbsoluteTime() */
void
GetCurrentTime(struct tm * tm)
{
......@@ -190,6 +268,19 @@ GetCurrentTime(struct tm * tm)
} /* GetCurrentTime() */
void
GetCurrentTimeUsec(struct tm *tm, double *fsec)
{
int tz;
int usec;
abstime2tm(GetCurrentTransactionStartTimeUsec(&usec), &tz, tm, NULL);
*fsec = usec * 1.0e-6;
return;
} /* GetCurrentTimeUsec() */
void
abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn)
{
......@@ -357,11 +448,9 @@ nabstimein(PG_FUNCTION_ARGS)
break;
case DTK_EPOCH:
result = EPOCH_ABSTIME;
break;
case DTK_CURRENT:
result = CURRENT_ABSTIME;
/* Don't bother retaining this as a reserved value,
* but instead just set to the actual epoch time (1970-01-01) */
result = 0;
break;
case DTK_LATE:
......@@ -404,15 +493,12 @@ nabstimeout(PG_FUNCTION_ARGS)
switch (time)
{
case EPOCH_ABSTIME:
strcpy(buf, EPOCH);
break;
/* Note that timestamp no longer supports 'invalid'.
* Retain 'invalid' for abstime for now, but dump it someday.
*/
case INVALID_ABSTIME:
strcpy(buf, INVALID);
break;
case CURRENT_ABSTIME:
strcpy(buf, DCURRENT);
break;
case NOEND_ABSTIME:
strcpy(buf, LATE);
break;
......@@ -449,7 +535,7 @@ abstime_finite(PG_FUNCTION_ARGS)
static int
abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
{
/*
/*
* We consider all INVALIDs to be equal and larger than any non-INVALID.
* This is somewhat arbitrary; the important thing is to have a
* consistent sort order.
......@@ -461,17 +547,18 @@ abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
else
return 1; /* INVALID > non-INVALID */
}
else if (b == INVALID_ABSTIME)
{
if (b == INVALID_ABSTIME)
return -1; /* non-INVALID < INVALID */
}
else
{
#if 0
/* CURRENT is no longer stored internally... */
/* XXX this is broken, should go away: */
if (a == CURRENT_ABSTIME)
a = GetCurrentTransactionStartTime();
if (b == CURRENT_ABSTIME)
b = GetCurrentTransactionStartTime();
#endif
if (a > b)
return 1;
......@@ -479,7 +566,6 @@ abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
return 0;
else
return -1;
}
}
Datum
......@@ -546,7 +632,7 @@ btabstimecmp(PG_FUNCTION_ARGS)
}
/* datetime_abstime()
/* timestamp_abstime()
* Convert timestamp to abstime.
*/
Datum
......@@ -555,25 +641,22 @@ timestamp_abstime(PG_FUNCTION_ARGS)
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
AbsoluteTime result;
double fsec;
int tz;
struct tm tt,
*tm = &tt;
if (TIMESTAMP_IS_INVALID(timestamp))
result = INVALID_ABSTIME;
else if (TIMESTAMP_IS_NOBEGIN(timestamp))
if (TIMESTAMP_IS_NOBEGIN(timestamp))
result = NOSTART_ABSTIME;
else if (TIMESTAMP_IS_NOEND(timestamp))
result = NOEND_ABSTIME;
else
{
if (TIMESTAMP_IS_RELATIVE(timestamp))
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)
{
timestamp2tm(SetTimestamp(timestamp), NULL, tm, &fsec, NULL);
result = tm2abstime(tm, 0);
tz = DetermineLocalTimeZone(tm);
result = tm2abstime(tm, tz);
}
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)
result = tm2abstime(tm, 0);
else
{
elog(ERROR, "Unable to convert timestamp to abstime");
result = INVALID_ABSTIME;
}
......@@ -588,11 +671,16 @@ abstime_timestamp(PG_FUNCTION_ARGS)
{
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
Timestamp result;
struct tm tt,
*tm = &tt;
int tz;
char tzn[MAXTZLEN];
switch (abstime)
{
case INVALID_ABSTIME:
TIMESTAMP_INVALID(result);
elog(ERROR, "Unable to convert abstime 'invalid' to timestamp");
TIMESTAMP_NOBEGIN(result);
break;
case NOSTART_ABSTIME:
......@@ -603,12 +691,65 @@ abstime_timestamp(PG_FUNCTION_ARGS)
TIMESTAMP_NOEND(result);
break;
case EPOCH_ABSTIME:
TIMESTAMP_EPOCH(result);
default:
abstime2tm(abstime, &tz, tm, tzn);
result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400) + tz;
break;
};
PG_RETURN_TIMESTAMP(result);
}
/* timestamptz_abstime()
* Convert timestamp with time zone to abstime.
*/
Datum
timestamptz_abstime(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
AbsoluteTime result;
double fsec;
struct tm tt,
*tm = &tt;
if (TIMESTAMP_IS_NOBEGIN(timestamp))
result = NOSTART_ABSTIME;
else if (TIMESTAMP_IS_NOEND(timestamp))
result = NOEND_ABSTIME;
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)
result = tm2abstime(tm, 0);
else
{
elog(ERROR, "Unable to convert timestamp to abstime");
result = INVALID_ABSTIME;
}
PG_RETURN_ABSOLUTETIME(result);
}
/* abstime_timestamptz()
* Convert abstime to timestamp.
*/
Datum
abstime_timestamptz(PG_FUNCTION_ARGS)
{
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
TimestampTz result;
switch (abstime)
{
case INVALID_ABSTIME:
elog(ERROR, "Unable to convert abstime 'invalid' to timestamptz");
TIMESTAMP_NOBEGIN(result);
break;
case NOSTART_ABSTIME:
TIMESTAMP_NOBEGIN(result);
break;
case CURRENT_ABSTIME:
TIMESTAMP_CURRENT(result);
case NOEND_ABSTIME:
TIMESTAMP_NOEND(result);
break;
default:
......@@ -653,14 +794,15 @@ reltimein(PG_FUNCTION_ARGS)
case DTK_DELTA:
result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
result += (((tm->tm_year * 365) + (tm->tm_mon * 30) + tm->tm_mday) * (24 * 60 * 60));
PG_RETURN_RELATIVETIME(result);
break;
default:
PG_RETURN_RELATIVETIME(INVALID_RELTIME);
elog(ERROR, "Bad reltime (internal coding error) '%s'", str);
result = INVALID_RELTIME;
break;
}
elog(ERROR, "Bad reltime (internal coding error) '%s'", str);
PG_RETURN_RELATIVETIME(INVALID_RELTIME);
PG_RETURN_RELATIVETIME(result);
}
......@@ -676,13 +818,8 @@ reltimeout(PG_FUNCTION_ARGS)
*tm = &tt;
char buf[MAXDATELEN + 1];
if (time == INVALID_RELTIME)
strcpy(buf, INVALID_RELTIME_STR);
else
{
reltime2tm(time, tm);
EncodeTimeSpan(tm, 0, DateStyle, buf);
}
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
......@@ -702,44 +839,6 @@ reltime2tm(RelativeTime time, struct tm * tm)
return;
} /* reltime2tm() */
#ifdef NOT_USED
int
dummyfunc()
{
char *timestring;
long quantity;
int i;
int unitnr;
timestring = (char *) palloc(Max(strlen(INVALID_RELTIME_STR),
UNITMAXLEN) + 1);
if (timevalue == INVALID_RELTIME)
{
strcpy(timestring, INVALID_RELTIME_STR);
return timestring;
}
if (timevalue == 0)
i = 1; /* unit = 'seconds' */
else
for (i = 12; i >= 0; i = i - 2)
if ((timevalue % sec_tab[i]) == 0)
break; /* appropriate unit found */
unitnr = i;
quantity = (timevalue / sec_tab[unitnr]);
if (quantity > 1 || quantity < -1)
unitnr++; /* adjust index for PLURAL of unit */
if (quantity >= 0)
sprintf(timestring, "%c %lu %s", RELTIME_LABEL,
quantity, unit_tab[unitnr]);
else
sprintf(timestring, "%c %lu %s %s", RELTIME_LABEL,
(quantity * -1), unit_tab[unitnr], RELTIME_PAST);
return timestring;
}
#endif
/*
* tintervalin - converts an interval string to internal format
......@@ -749,26 +848,25 @@ tintervalin(PG_FUNCTION_ARGS)
{
char *intervalstr = PG_GETARG_CSTRING(0);
TimeInterval interval;
int error;
AbsoluteTime i_start,
i_end,
t1,
t2;
interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
error = istinterval(intervalstr, &t1, &t2);
if (error == 0)
interval->status = T_INTERVAL_INVAL;
if (istinterval(intervalstr, &t1, &t2) == 0)
elog(ERROR, "Unable to decode tinterval '%s'", intervalstr);
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
interval->status = T_INTERVAL_INVAL; /* undefined */
else
{
interval->status = T_INTERVAL_VALID;
i_start = ABSTIMEMIN(t1, t2);
i_end = ABSTIMEMAX(t1, t2);
interval->data[0] = i_start;
interval->data[1] = i_end;
interval->status = T_INTERVAL_VALID;
}
PG_RETURN_TIMEINTERVAL(interval);
}
......@@ -818,10 +916,6 @@ interval_reltime(PG_FUNCTION_ARGS)
month;
double span;
if (INTERVAL_IS_INVALID(*interval))
time = INVALID_RELTIME;
else
{
if (interval->month == 0)
{
year = 0;
......@@ -840,8 +934,10 @@ interval_reltime(PG_FUNCTION_ARGS)
span = (((((double) 365 * year) + ((double) 30 * month)) * 86400) + interval->time);
time = (((span > INT_MIN) && (span < INT_MAX)) ? span : INVALID_RELTIME);
}
if ((span < INT_MIN) || (span > INT_MAX))
time = INVALID_RELTIME;
else
time = span;
PG_RETURN_RELATIVETIME(time);
}
......@@ -860,7 +956,9 @@ reltime_interval(PG_FUNCTION_ARGS)
switch (reltime)
{
case INVALID_RELTIME:
INTERVAL_INVALID(*result);
elog(ERROR, "Unable to convert reltime 'invalid' to interval");
result->time = 0;
result->month = 0;
break;
default:
......@@ -884,11 +982,12 @@ mktinterval(PG_FUNCTION_ARGS)
{
AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
AbsoluteTime tstart = ABSTIMEMIN(t1, t2),
tend = ABSTIMEMAX(t1, t2);
AbsoluteTime tstart = ABSTIMEMIN(t1, t2);
AbsoluteTime tend = ABSTIMEMAX(t1, t2);
TimeInterval interval;
interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
interval->status = T_INTERVAL_INVAL;
else
......@@ -909,7 +1008,7 @@ mktinterval(PG_FUNCTION_ARGS)
*/
/*
* timepl - returns the value of (abstime t1 + relime t2)
* timepl - returns the value of (abstime t1 + reltime t2)
*/
Datum
timepl(PG_FUNCTION_ARGS)
......@@ -917,8 +1016,10 @@ timepl(PG_FUNCTION_ARGS)
AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
#if 0
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
#endif
if (AbsoluteTimeIsReal(t1) &&
RelativeTimeIsValid(t2) &&
......@@ -939,8 +1040,10 @@ timemi(PG_FUNCTION_ARGS)
AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
#if 0
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
#endif
if (AbsoluteTimeIsReal(t1) &&
RelativeTimeIsValid(t2) &&
......@@ -952,27 +1055,6 @@ timemi(PG_FUNCTION_ARGS)
}
/*
* abstimemi - returns the value of (abstime t1 - abstime t2)
*
* This is not exported, so it's not been made fmgr-compatible.
*/
static RelativeTime
abstimemi(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
t2 = GetCurrentTransactionStartTime();
if (AbsoluteTimeIsReal(t1) &&
AbsoluteTimeIsReal(t2))
return t1 - t2;
return INVALID_RELTIME;
}
/*
* intinterval - returns true iff absolute date is in the interval
*/
......@@ -1002,13 +1084,20 @@ Datum
tintervalrel(PG_FUNCTION_ARGS)
{
TimeInterval interval = PG_GETARG_TIMEINTERVAL(0);
AbsoluteTime t1 = interval->data[0];
AbsoluteTime t2 = interval->data[1];
if (interval->status != T_INTERVAL_VALID)
PG_RETURN_RELATIVETIME(INVALID_RELTIME);
PG_RETURN_RELATIVETIME(abstimemi(interval->data[1], interval->data[0]));
if (AbsoluteTimeIsReal(t1) &&
AbsoluteTimeIsReal(t2))
PG_RETURN_RELATIVETIME(t2 - t1);
PG_RETURN_RELATIVETIME(INVALID_RELTIME);
}
/*
* timenow - returns time "now", internal format
*
......@@ -1021,6 +1110,7 @@ timenow(PG_FUNCTION_ARGS)
if (time(&sec) < 0)
PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
PG_RETURN_ABSOLUTETIME((AbsoluteTime) sec);
}
......@@ -1145,19 +1235,10 @@ tintervaleq(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) == (t21 - t20));
}
......@@ -1179,19 +1260,10 @@ tintervalne(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) != (t21 - t20));
}
......@@ -1213,19 +1285,10 @@ tintervallt(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) < (t21 - t20));
}
......@@ -1247,19 +1310,10 @@ tintervalle(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) <= (t21 - t20));
}
......@@ -1281,19 +1335,10 @@ tintervalgt(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) > (t21 - t20));
}
......@@ -1315,19 +1360,10 @@ tintervalge(PG_FUNCTION_ARGS)
t20 = i2->data[0];
t21 = i2->data[1];
if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
|| (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
PG_RETURN_BOOL(false);
if (t10 == CURRENT_ABSTIME)
t10 = GetCurrentTransactionStartTime();
if (t11 == CURRENT_ABSTIME)
t11 = GetCurrentTransactionStartTime();
if (t20 == CURRENT_ABSTIME)
t20 = GetCurrentTransactionStartTime();
if (t21 == CURRENT_ABSTIME)
t21 = GetCurrentTransactionStartTime();
PG_RETURN_BOOL((t11 - t10) >= (t21 - t20));
}
......@@ -1357,7 +1393,7 @@ tintervalleneq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt == t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt == t));
}
Datum
......@@ -1371,7 +1407,7 @@ tintervallenne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt != t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt != t));
}
Datum
......@@ -1385,7 +1421,7 @@ tintervallenlt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt < t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt < t));
}
Datum
......@@ -1399,7 +1435,7 @@ tintervallengt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt > t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt > t));
}
Datum
......@@ -1413,7 +1449,7 @@ tintervallenle(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt <= t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt <= t));
}
Datum
......@@ -1427,7 +1463,7 @@ tintervallenge(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
TimeIntervalGetDatum(i)));
PG_RETURN_BOOL(rt != INVALID_RELTIME && rt >= t);
PG_RETURN_BOOL((rt != INVALID_RELTIME) && (rt >= t));
}
/*
......@@ -1503,222 +1539,6 @@ tintervalend(PG_FUNCTION_ARGS)
* PRIVATE ROUTINES *
*****************************************************************************/
#ifdef NOT_USED
/*
* isreltime - returns 1, iff datestring is of type reltime
* 2, iff datestring is 'invalid time' identifier
* 0, iff datestring contains a syntax error
* VALID time less or equal +/- `@ 68 years'
*
*/
int
isreltime(char *str)
{
struct tm tt,
*tm = &tt;
double fsec;
int dtype;
char *field[MAXDATEFIELDS];
int nf,
ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + 1];
if (!PointerIsValid(str))
return 0;
if (strlen(str) > MAXDATELEN)
return 0;
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|| (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
return 0;
switch (dtype)
{
case (DTK_DELTA):
return (abs(tm->tm_year) <= 68) ? 1 : 0;
break;
case (DTK_INVALID):
return 2;
break;
default:
return 0;
break;
}
return 0;
} /* isreltime() */
#endif
#ifdef NOT_USED
int
dummyfunc()
{
char *p;
char c;
int i;
char unit[UNITMAXLEN];
char direction[DIRMAXLEN];
int localSign;
int localUnitNumber;
long localQuantity;
if (!PointerIsValid(sign))
sign = &localSign;
if (!PointerIsValid(unitnr))
unitnr = &localUnitNumber;
if (!PointerIsValid(quantity))
quantity = &localQuantity;
unit[0] = '\0';
direction[0] = '\0';
p = timestring;
/* skip leading blanks */
while ((c = *p) != '\0')
{
if (c != ' ')
break;
p++;
}
/* Test whether 'invalid time' identifier or not */
if (!strncmp(INVALID_RELTIME_STR, p, strlen(INVALID_RELTIME_STR) + 1))
return 2; /* correct 'invalid time' identifier found */
/* handle label of relative time */
if (c != RELTIME_LABEL)
return 0; /* syntax error */
c = *++p;
if (c != ' ')
return 0; /* syntax error */
p++;
/* handle the quantity */
*quantity = 0;
for (;;)
{
c = *p;
if (isdigit((unsigned char) c))
{
*quantity = *quantity * 10 + (c - '0');
p++;
}
else
{
if (c == ' ')
break; /* correct quantity found */
else
return 0; /* syntax error */
}
}
/* handle unit */
p++;
i = 0;
for (;;)
{
c = *p;
if (c >= 'a' && c <= 'z' && i <= (UNITMAXLEN - 1))
{
unit[i] = c;
p++;
i++;
}
else
{
if ((c == ' ' || c == '\0')
&& correct_unit(unit, unitnr))
break; /* correct unit found */
else
return 0; /* syntax error */
}
}
/* handle optional direction */
if (c == ' ')
p++;
i = 0;
*sign = 1;
for (;;)
{
c = *p;
if (c >= 'a' && c <= 'z' && i <= (DIRMAXLEN - 1))
{
direction[i] = c;
p++;
i++;
}
else
{
if ((c == ' ' || c == '\0') && i == 0)
{
*sign = 1;
break; /* no direction specified */
}
if ((c == ' ' || c == '\0') && i != 0)
{
direction[i] = '\0';
correct_dir(direction, sign);
break; /* correct direction found */
}
else
return 0; /* syntax error */
}
}
return 1;
}
/*
* correct_unit - returns 1, iff unit is a correct unit description
*
* output parameter:
* unptr: points to an integer which is the appropriate unit number
* (see function isreltime())
*/
static int
correct_unit(char *unit, int *unptr)
{
int j = 0;
while (j < NUNITS)
{
if (strncmp(unit, unit_tab[j], strlen(unit_tab[j])) == 0)
{
*unptr = j;
return 1;
}
j++;
}
return 0; /* invalid unit descriptor */
}
/*
* correct_dir - returns 1, iff direction is a correct identifier
*
* output parameter:
* signptr: points to -1 if dir corresponds to past tense
* else to 1
*/
static int
correct_dir(char *direction, int *signptr)
{
*signptr = 1;
if (strncmp(RELTIME_PAST, direction, strlen(RELTIME_PAST) + 1) == 0)
{
*signptr = -1;
return 1;
}
else
return 0; /* invalid direction descriptor */
}
#endif
/*
* istinterval - returns 1, iff i_string is a valid interval descr.
* 0, iff i_string is NOT a valid interval desc.
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.50 2001/09/06 03:22:42 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.51 2001/09/28 08:09:11 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -32,7 +32,7 @@
static double time2t(const int hour, const int min, const double sec);
static int EncodeSpecialTimestamp(Timestamp dt, char *str);
static Timestamp dt2local(Timestamp dt, int timezone);
static void dt2time(Timestamp dt, int *hour, int *min, double *sec);
/*****************************************************************************
* USER I/O ROUTINES *
......@@ -63,16 +63,12 @@ timestamp_in(PG_FUNCTION_ARGS)
switch (dtype)
{
case DTK_DATE:
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Timestamp out of range '%s'", str);
break;
case DTK_EPOCH:
TIMESTAMP_EPOCH(result);
break;
case DTK_CURRENT:
TIMESTAMP_CURRENT(result);
result = SetEpochTimestamp();
break;
case DTK_LATE:
......@@ -84,12 +80,13 @@ timestamp_in(PG_FUNCTION_ARGS)
break;
case DTK_INVALID:
TIMESTAMP_INVALID(result);
elog(ERROR, "Timestamp '%s' no longer supported", str);
TIMESTAMP_NOEND(result);
break;
default:
elog(ERROR, "Internal coding error, can't input timestamp '%s'", str);
TIMESTAMP_INVALID(result); /* keep compiler quiet */
elog(ERROR, "Timestamp '%s' not parsed; internal coding error", str);
TIMESTAMP_NOEND(result);
}
PG_RETURN_TIMESTAMP(result);
......@@ -103,6 +100,86 @@ timestamp_out(PG_FUNCTION_ARGS)
{
Timestamp dt = PG_GETARG_TIMESTAMP(0);
char *result;
struct tm tt,
*tm = &tt;
double fsec;
char *tzn = NULL;
char buf[MAXDATELEN + 1];
if (TIMESTAMP_NOT_FINITE(dt))
EncodeSpecialTimestamp(dt, buf);
else if (timestamp2tm(dt, NULL, tm, &fsec, NULL) == 0)
EncodeDateTime(tm, fsec, NULL, &tzn, DateStyle, buf);
else
elog(ERROR, "Unable to format timestamp; internal coding error");
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
}
/* timestamptz_in()
* Convert a string to internal form.
*/
Datum
timestamptz_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
TimestampTz result;
double fsec;
struct tm tt,
*tm = &tt;
int tz;
int dtype;
int nf;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
char lowstr[MAXDATELEN + 1];
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|| (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
elog(ERROR, "Bad timestamp external representation '%s'", str);
switch (dtype)
{
case DTK_DATE:
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Timestamp out of range '%s'", str);
break;
case DTK_EPOCH:
result = SetEpochTimestamp();
break;
case DTK_LATE:
TIMESTAMP_NOEND(result);
break;
case DTK_EARLY:
TIMESTAMP_NOBEGIN(result);
break;
case DTK_INVALID:
elog(ERROR, "Timestamp with time zone '%s' no longer supported", str);
TIMESTAMP_NOEND(result);
break;
default:
elog(ERROR, "Timestamp with time zone '%s' not parsed; internal coding error", str);
TIMESTAMP_NOEND(result);
}
PG_RETURN_TIMESTAMPTZ(result);
}
/* timestamptz_out()
* Convert a timestamp to external form.
*/
Datum
timestamptz_out(PG_FUNCTION_ARGS)
{
TimestampTz dt = PG_GETARG_TIMESTAMP(0);
char *result;
int tz;
struct tm tt,
*tm = &tt;
......@@ -110,12 +187,12 @@ timestamp_out(PG_FUNCTION_ARGS)
char *tzn;
char buf[MAXDATELEN + 1];
if (TIMESTAMP_IS_RESERVED(dt))
if (TIMESTAMP_NOT_FINITE(dt))
EncodeSpecialTimestamp(dt, buf);
else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn) == 0)
EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
else
EncodeSpecialTimestamp(DT_INVALID, buf);
elog(ERROR, "Unable to format timestamp with time zone; internal coding error");
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
......@@ -132,7 +209,7 @@ Datum
interval_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
Interval *span;
Interval *result;
double fsec;
struct tm tt,
*tm = &tt;
......@@ -154,25 +231,24 @@ interval_in(PG_FUNCTION_ARGS)
|| (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
elog(ERROR, "Bad interval external representation '%s'", str);
span = (Interval *) palloc(sizeof(Interval));
result = (Interval *) palloc(sizeof(Interval));
switch (dtype)
{
case DTK_DELTA:
if (tm2interval(tm, fsec, span) != 0)
{
#if NOT_USED
INTERVAL_INVALID(span);
#endif
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Bad interval external representation '%s'", str);
}
break;
case DTK_INVALID:
elog(ERROR, "Interval '%s' no longer supported", str);
break;
default:
elog(ERROR, "Internal coding error, can't input interval '%s'", str);
elog(ERROR, "Interval '%s' not parsed; internal coding error", str);
}
PG_RETURN_INTERVAL_P(span);
PG_RETURN_INTERVAL_P(result);
}
/* interval_out()
......@@ -189,10 +265,10 @@ interval_out(PG_FUNCTION_ARGS)
char buf[MAXDATELEN + 1];
if (interval2tm(*span, tm, &fsec) != 0)
PG_RETURN_NULL();
elog(ERROR, "Unable to encode interval; internal coding error");
if (EncodeTimeSpan(tm, fsec, DateStyle, buf) != 0)
elog(ERROR, "Unable to format interval");
elog(ERROR, "Unable to format interval; internal coding error");
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
......@@ -205,40 +281,31 @@ interval_out(PG_FUNCTION_ARGS)
static int
EncodeSpecialTimestamp(Timestamp dt, char *str)
{
if (TIMESTAMP_IS_RESERVED(dt))
{
if (TIMESTAMP_IS_INVALID(dt))
strcpy(str, INVALID);
else if (TIMESTAMP_IS_NOBEGIN(dt))
if (TIMESTAMP_IS_NOBEGIN(dt))
strcpy(str, EARLY);
else if (TIMESTAMP_IS_NOEND(dt))
strcpy(str, LATE);
else if (TIMESTAMP_IS_CURRENT(dt))
strcpy(str, DCURRENT);
else if (TIMESTAMP_IS_EPOCH(dt))
strcpy(str, EPOCH);
else
strcpy(str, INVALID);
return TRUE;
}
return FALSE;
return TRUE;
} /* EncodeSpecialTimestamp() */
Datum
now(PG_FUNCTION_ARGS)
{
Timestamp result;
TimestampTz result;
AbsoluteTime sec;
int usec;
sec = GetCurrentTransactionStartTime();
sec = GetCurrentTransactionStartTimeUsec(&usec);
result = (sec - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400));
result = (sec + (usec * 1.0e-6) - ((date2j(2000, 1, 1) - date2j(1970, 1, 1)) * 86400));
PG_RETURN_TIMESTAMP(result);
PG_RETURN_TIMESTAMPTZ(result);
}
static void
void
dt2time(Timestamp jd, int *hour, int *min, double *sec)
{
double time;
......@@ -485,9 +552,7 @@ timestamp_finite(PG_FUNCTION_ARGS)
Datum
interval_finite(PG_FUNCTION_ARGS)
{
Interval *interval = PG_GETARG_INTERVAL_P(0);
PG_RETURN_BOOL(!INTERVAL_NOT_FINITE(*interval));
PG_RETURN_BOOL(true);
}
......@@ -495,7 +560,7 @@ interval_finite(PG_FUNCTION_ARGS)
* Relational operators for timestamp.
*---------------------------------------------------------*/
static void
void
GetEpochTime(struct tm * tm)
{
struct tm *t0;
......@@ -518,24 +583,17 @@ GetEpochTime(struct tm * tm)
} /* GetEpochTime() */
Timestamp
SetTimestamp(Timestamp dt)
SetEpochTimestamp(void)
{
struct tm tt;
Timestamp dt;
struct tm tt,
*tm = &tt;
if (TIMESTAMP_IS_CURRENT(dt))
{
GetCurrentTime(&tt);
tm2timestamp(&tt, 0, NULL, &dt);
dt = dt2local(dt, -CTimeZone);
}
else
{ /* if (TIMESTAMP_IS_EPOCH(dt1)) */
GetEpochTime(&tt);
tm2timestamp(&tt, 0, NULL, &dt);
}
GetEpochTime(tm);
tm2timestamp(tm, 0, NULL, &dt);
return dt;
} /* SetTimestamp() */
} /* SetEpochTimestamp() */
/*
* timestamp_relop - is timestamp1 relop timestamp2
......@@ -545,19 +603,7 @@ SetTimestamp(Timestamp dt)
static int
timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
{
if (TIMESTAMP_IS_INVALID(dt1))
return (TIMESTAMP_IS_INVALID(dt2) ? 0 : 1);
else if (TIMESTAMP_IS_INVALID(dt2))
return -1;
else
{
if (TIMESTAMP_IS_RELATIVE(dt1))
dt1 = SetTimestamp(dt1);
if (TIMESTAMP_IS_RELATIVE(dt2))
dt2 = SetTimestamp(dt2);
return ((dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0));
}
}
Datum
......@@ -632,12 +678,6 @@ timestamp_cmp(PG_FUNCTION_ARGS)
static int
interval_cmp_internal(Interval *interval1, Interval *interval2)
{
if (INTERVAL_IS_INVALID(*interval1))
return (INTERVAL_IS_INVALID(*interval2) ? 0 : 1);
else if (INTERVAL_IS_INVALID(*interval2))
return -1;
else
{
double span1,
span2;
......@@ -649,7 +689,6 @@ interval_cmp_internal(Interval *interval1, Interval *interval2)
span2 += (interval2->month * (30.0 * 86400));
return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);
}
}
Datum
......@@ -866,6 +905,9 @@ overlaps_timestamp(PG_FUNCTION_ARGS)
* "Arithmetic" operators on date/times.
*---------------------------------------------------------*/
/* We are currently sharing some code between timestamp and timestamptz.
* The comparison functions are among them. - thomas 2001-09-25
*/
Datum
timestamp_smaller(PG_FUNCTION_ARGS)
{
......@@ -873,16 +915,6 @@ timestamp_smaller(PG_FUNCTION_ARGS)
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
Timestamp result;
if (TIMESTAMP_IS_RELATIVE(dt1))
dt1 = SetTimestamp(dt1);
if (TIMESTAMP_IS_RELATIVE(dt2))
dt2 = SetTimestamp(dt2);
if (TIMESTAMP_IS_INVALID(dt1))
result = dt2;
else if (TIMESTAMP_IS_INVALID(dt2))
result = dt1;
else
result = ((dt2 < dt1) ? dt2 : dt1);
PG_RETURN_TIMESTAMP(result);
......@@ -895,16 +927,6 @@ timestamp_larger(PG_FUNCTION_ARGS)
Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
Timestamp result;
if (TIMESTAMP_IS_RELATIVE(dt1))
dt1 = SetTimestamp(dt1);
if (TIMESTAMP_IS_RELATIVE(dt2))
dt2 = SetTimestamp(dt2);
if (TIMESTAMP_IS_INVALID(dt1))
result = dt2;
else if (TIMESTAMP_IS_INVALID(dt2))
result = dt1;
else
result = ((dt2 > dt1) ? dt2 : dt1);
PG_RETURN_TIMESTAMP(result);
......@@ -920,16 +942,14 @@ timestamp_mi(PG_FUNCTION_ARGS)
result = (Interval *) palloc(sizeof(Interval));
if (TIMESTAMP_IS_RELATIVE(dt1))
dt1 = SetTimestamp(dt1);
if (TIMESTAMP_IS_RELATIVE(dt2))
dt2 = SetTimestamp(dt2);
if (TIMESTAMP_IS_INVALID(dt1)
|| TIMESTAMP_IS_INVALID(dt2))
TIMESTAMP_INVALID(result->time);
if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2))
{
elog(ERROR, "Unable to subtract non-finite timestamps");
result->time = 0;
}
else
result->time = JROUND(dt1 - dt2);
result->month = 0;
PG_RETURN_INTERVAL_P(result);
......@@ -951,25 +971,111 @@ timestamp_pl_span(PG_FUNCTION_ARGS)
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
Interval *span = PG_GETARG_INTERVAL_P(1);
Timestamp result;
Timestamp dt;
if (TIMESTAMP_NOT_FINITE(timestamp))
{
result = timestamp;
}
else
{
if (span->month != 0)
{
struct tm tt,
*tm = &tt;
double fsec;
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)
{
tm->tm_mon += span->month;
if (tm->tm_mon > 12)
{
tm->tm_year += ((tm->tm_mon - 1) / 12);
tm->tm_mon = (((tm->tm_mon - 1) % 12) + 1);
}
else if (tm->tm_mon < 1)
{
tm->tm_year += ((tm->tm_mon / 12) - 1);
tm->tm_mon = ((tm->tm_mon % 12) + 12);
}
/* 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]);
if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
{
elog(ERROR, "Unable to add timestamp and interval"
"\n\ttimestamp_pl_span() internal error encoding timestamp");
PG_RETURN_NULL();
}
}
else
{
elog(ERROR, "Unable to add timestamp and interval"
"\n\ttimestamp_pl_span() internal error decoding timestamp");
PG_RETURN_NULL();
}
}
#ifdef ROUND_ALL
timestamp = JROUND(timestamp + span->time);
#else
timestamp += span->time;
#endif
result = timestamp;
}
PG_RETURN_TIMESTAMP(result);
}
Datum
timestamp_mi_span(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
Interval *span = PG_GETARG_INTERVAL_P(1);
Interval tspan;
tspan.month = -span->month;
tspan.time = -span->time;
return DirectFunctionCall2(timestamp_pl_span,
TimestampGetDatum(timestamp),
PointerGetDatum(&tspan));
}
/* timestamp_pl_span()
* 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
timestamptz_pl_span(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
Interval *span = PG_GETARG_INTERVAL_P(1);
TimestampTz result;
int tz;
char *tzn;
if (TIMESTAMP_NOT_FINITE(timestamp))
{
result = timestamp;
else if (INTERVAL_IS_INVALID(*span))
TIMESTAMP_INVALID(result);
}
else
{
dt = (TIMESTAMP_IS_RELATIVE(timestamp) ? SetTimestamp(timestamp) : timestamp);
if (span->month != 0)
{
struct tm tt,
*tm = &tt;
double fsec;
if (timestamp2tm(dt, &tz, tm, &fsec, &tzn) == 0)
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) == 0)
{
tm->tm_mon += span->month;
if (tm->tm_mon > 12)
......@@ -989,30 +1095,33 @@ timestamp_pl_span(PG_FUNCTION_ARGS)
tz = DetermineLocalTimeZone(tm);
if (tm2timestamp(tm, fsec, &tz, &dt) != 0)
elog(ERROR, "Unable to add timestamp and interval");
if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
elog(ERROR, "Unable to add timestamp and interval"
"\n\ttimestamptz_pl_span() internal error encoding timestamp");
}
else
TIMESTAMP_INVALID(dt);
{
elog(ERROR, "Unable to add timestamp and interval"
"\n\ttimestamptz_pl_span() internal error decoding timestamp");
}
}
#ifdef ROUND_ALL
dt = JROUND(dt + span->time);
timestamp = JROUND(timestamp + span->time);
#else
dt += span->time;
timestamp += span->time;
#endif
result = dt;
result = timestamp;
}
PG_RETURN_TIMESTAMP(result);
}
Datum
timestamp_mi_span(PG_FUNCTION_ARGS)
timestamptz_mi_span(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
Interval *span = PG_GETARG_INTERVAL_P(1);
Interval tspan;
......@@ -1051,18 +1160,6 @@ interval_smaller(PG_FUNCTION_ARGS)
result = (Interval *) palloc(sizeof(Interval));
if (INTERVAL_IS_INVALID(*interval1))
{
result->time = interval2->time;
result->month = interval2->month;
}
else if (INTERVAL_IS_INVALID(*interval2))
{
result->time = interval1->time;
result->month = interval1->month;
}
else
{
span1 = interval1->time;
if (interval1->month != 0)
span1 += (interval1->month * (30.0 * 86400));
......@@ -1080,7 +1177,6 @@ interval_smaller(PG_FUNCTION_ARGS)
result->time = interval1->time;
result->month = interval1->month;
}
}
PG_RETURN_INTERVAL_P(result);
}
......@@ -1096,18 +1192,6 @@ interval_larger(PG_FUNCTION_ARGS)
result = (Interval *) palloc(sizeof(Interval));
if (INTERVAL_IS_INVALID(*interval1))
{
result->time = interval2->time;
result->month = interval2->month;
}
else if (INTERVAL_IS_INVALID(*interval2))
{
result->time = interval1->time;
result->month = interval1->month;
}
else
{
span1 = interval1->time;
if (interval1->month != 0)
span1 += (interval1->month * (30.0 * 86400));
......@@ -1125,7 +1209,6 @@ interval_larger(PG_FUNCTION_ARGS)
result->time = interval1->time;
result->month = interval1->month;
}
}
PG_RETURN_INTERVAL_P(result);
}
......@@ -1321,15 +1404,7 @@ timestamp_age(PG_FUNCTION_ARGS)
result = (Interval *) palloc(sizeof(Interval));
if (TIMESTAMP_IS_RELATIVE(dt1))
dt1 = SetTimestamp(dt1);
if (TIMESTAMP_IS_RELATIVE(dt2))
dt2 = SetTimestamp(dt2);
if (TIMESTAMP_IS_INVALID(dt1)
|| TIMESTAMP_IS_INVALID(dt2))
TIMESTAMP_INVALID(result->time);
else if ((timestamp2tm(dt1, NULL, tm1, &fsec1, NULL) == 0)
if ((timestamp2tm(dt1, NULL, tm1, &fsec1, NULL) == 0)
&& (timestamp2tm(dt2, NULL, tm2, &fsec2, NULL) == 0))
{
fsec = (fsec1 - fsec2);
......@@ -1403,37 +1478,146 @@ timestamp_age(PG_FUNCTION_ARGS)
}
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Unable to decode timestamp");
elog(ERROR, "Unable to encode interval"
"\n\ttimestamp_age() internal coding error");
}
else
elog(ERROR, "Unable to decode timestamp");
elog(ERROR, "Unable to decode timestamp"
"\n\ttimestamp_age() internal coding error");
PG_RETURN_INTERVAL_P(result);
}
/*----------------------------------------------------------
* Conversion operators.
*---------------------------------------------------------*/
/* timestamp_text()
* Convert timestamp to text data type.
/* 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.
*/
Datum
timestamp_text(PG_FUNCTION_ARGS)
timestamptz_age(PG_FUNCTION_ARGS)
{
/* Input is a Timestamp, but may as well leave it in Datum form */
Datum timestamp = PG_GETARG_DATUM(0);
text *result;
char *str;
int len;
str = DatumGetCString(DirectFunctionCall1(timestamp_out, timestamp));
len = (strlen(str) + VARHDRSZ);
result = palloc(len);
TimestampTz dt1 = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMP(1);
Interval *result;
double fsec,
fsec1,
fsec2;
struct tm tt,
*tm = &tt;
struct tm tt1,
*tm1 = &tt1;
struct tm tt2,
*tm2 = &tt2;
result = (Interval *) palloc(sizeof(Interval));
if ((timestamp2tm(dt1, NULL, tm1, &fsec1, NULL) == 0)
&& (timestamp2tm(dt2, NULL, tm2, &fsec2, NULL) == 0))
{
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);
/* 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;
}
if (tm->tm_sec < 0)
{
tm->tm_sec += 60;
tm->tm_min--;
}
if (tm->tm_min < 0)
{
tm->tm_min += 60;
tm->tm_hour--;
}
if (tm->tm_hour < 0)
{
tm->tm_hour += 24;
tm->tm_mday--;
}
if (tm->tm_mday < 0)
{
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--;
}
}
if (tm->tm_mon < 0)
{
tm->tm_mon += 12;
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)
elog(ERROR, "Unable to decode timestamp");
}
else
elog(ERROR, "Unable to decode timestamp");
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 */
Datum timestamp = PG_GETARG_DATUM(0);
text *result;
char *str;
int len;
str = DatumGetCString(DirectFunctionCall1(timestamp_out, timestamp));
len = (strlen(str) + VARHDRSZ);
result = palloc(len);
VARATT_SIZEP(result) = len;
memmove(VARDATA(result), str, (len - VARHDRSZ));
......@@ -1472,6 +1656,60 @@ text_timestamp(PG_FUNCTION_ARGS)
}
/* 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 */
Datum timestamp = PG_GETARG_DATUM(0);
text *result;
char *str;
int len;
str = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp));
len = (strlen(str) + VARHDRSZ);
result = palloc(len);
VARATT_SIZEP(result) = len;
memmove(VARDATA(result), str, (len - VARHDRSZ));
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)
elog(ERROR, "Bad timestamp with time zone external representation (too long)");
sp = VARDATA(str);
dp = dstr;
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
*dp++ = *sp++;
*dp = '\0';
return DirectFunctionCall1(timestamptz_in,
CStringGetDatum(dstr));
}
/* interval_text()
* Convert interval to text data type.
*/
......@@ -1525,7 +1763,7 @@ text_interval(PG_FUNCTION_ARGS)
}
/* timestamp_trunc()
* Extract specified field from timestamp.
* Truncate timestamp to specified units.
*/
Datum
timestamp_trunc(PG_FUNCTION_ARGS)
......@@ -1533,8 +1771,6 @@ timestamp_trunc(PG_FUNCTION_ARGS)
text *units = PG_GETARG_TEXT_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
Timestamp result;
Timestamp dt;
int tz;
int type,
val;
int i;
......@@ -1542,7 +1778,6 @@ timestamp_trunc(PG_FUNCTION_ARGS)
*lp,
lowunits[MAXDATELEN + 1];
double fsec;
char *tzn;
struct tm tt,
*tm = &tt;
......@@ -1559,12 +1794,96 @@ timestamp_trunc(PG_FUNCTION_ARGS)
type = DecodeUnits(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_NULL();
PG_RETURN_TIMESTAMP(timestamp);
if ((type == UNITS) && (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0))
{
switch (val)
{
case DTK_MILLENNIUM:
tm->tm_year = (tm->tm_year / 1000) * 1000;
case DTK_CENTURY:
tm->tm_year = (tm->tm_year / 100) * 100;
case DTK_DECADE:
tm->tm_year = (tm->tm_year / 10) * 10;
case DTK_YEAR:
tm->tm_mon = 1;
case DTK_QUARTER:
tm->tm_mon = (3 * (tm->tm_mon / 4)) + 1;
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:
fsec = rint(fsec * 1000) / 1000;
break;
case DTK_MICROSEC:
fsec = rint(fsec * 1000000) / 1000000;
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
result = 0;
}
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits);
}
else
{
dt = (TIMESTAMP_IS_RELATIVE(timestamp) ? SetTimestamp(timestamp) : timestamp);
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
result = 0;
}
if ((type == UNITS) && (timestamp2tm(dt, &tz, tm, &fsec, &tzn) == 0))
PG_RETURN_TIMESTAMP(result);
}
/* timestamptz_trunc()
* Truncate timestamp to specified units.
*/
Datum
timestamptz_trunc(PG_FUNCTION_ARGS)
{
text *units = PG_GETARG_TEXT_P(0);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz result;
int tz;
int type,
val;
int i;
char *up,
*lp,
lowunits[MAXDATELEN + 1];
double fsec;
char *tzn;
struct tm tt,
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
lp = lowunits;
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
*lp++ = tolower((unsigned char) *up++);
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMPTZ(timestamp);
if ((type == UNITS) && (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) == 0))
{
switch (val)
{
......@@ -1608,21 +1927,13 @@ timestamp_trunc(PG_FUNCTION_ARGS)
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits);
}
#if NOT_USED
else if ((type == RESERV) && (val == DTK_EPOCH))
{
TIMESTAMP_EPOCH(result);
result = dt - SetTimestamp(result);
}
#endif
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
result = 0;
}
PG_RETURN_NULL();
}
PG_RETURN_TIMESTAMP(result);
PG_RETURN_TIMESTAMPTZ(result);
}
/* interval_trunc()
......@@ -1658,14 +1969,7 @@ interval_trunc(PG_FUNCTION_ARGS)
type = DecodeUnits(0, lowunits, &val);
if (INTERVAL_IS_INVALID(*interval))
{
#if NOT_USED
elog(ERROR, "Interval is not finite");
#endif
PG_RETURN_NULL();
}
else if (type == UNITS)
if (type == UNITS)
{
if (interval2tm(*interval, tm, &fsec) == 0)
{
......@@ -1703,7 +2007,6 @@ interval_trunc(PG_FUNCTION_ARGS)
default:
elog(ERROR, "Interval units '%s' not supported", lowunits);
PG_RETURN_NULL();
}
if (tm2interval(tm, fsec, result) != 0)
......@@ -1712,123 +2015,266 @@ interval_trunc(PG_FUNCTION_ARGS)
}
else
{
elog(NOTICE, "Interval out of range");
PG_RETURN_NULL();
}
}
#if NOT_USED
else if ((type == RESERV) && (val == DTK_EPOCH))
{
*result = interval->time;
if (interval->month != 0)
{
*result += ((365.25 * 86400) * (interval->month / 12));
*result += ((30 * 86400) * (interval->month % 12));
elog(NOTICE, "Unable to decode interval; internal coding error");
*result = *interval;
}
}
#endif
else
{
elog(ERROR, "Interval units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
PG_RETURN_NULL();
*result = *interval;
}
PG_RETURN_INTERVAL_P(result);
}
/* isoweek2date()
* Convert ISO week of year number to date.
* The year field must be specified!
* karel 2000/08/07
*/
void
isoweek2date(int woy, int *year, int *mon, int *mday)
{
int day0,
day4,
dayn;
/* isoweek2date()
* Convert ISO week of year number to date.
* The year field must be specified!
* karel 2000/08/07
*/
void
isoweek2date(int woy, int *year, int *mon, int *mday)
{
int day0,
day4,
dayn;
if (!*year)
elog(ERROR, "isoweek2date(): can't convert without year information");
/* fourth day of current year */
day4 = date2j(*year, 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
dayn = ((woy - 1) * 7) + (day4 - day0);
j2date(dayn, year, mon, mday);
}
/* date2isoweek()
*
* Returns ISO week number of year.
*/
int
date2isoweek(int year, int mon, int mday)
{
float8 result;
int day0,
day4,
dayn;
/* 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) % 7);
/*
* We need the first week containing a Thursday, otherwise this day
* falls into the previous year for purposes of counting weeks
*/
if (dayn < (day4 - day0))
{
day4 = date2j((year - 1), 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
}
result = (((dayn - (day4 - day0)) / 7) + 1);
/*
* Sometimes the last few days in a year will fall into the first week
* of the next year, so check for this.
*/
if (result >= 53)
{
day4 = date2j((year + 1), 1, 4);
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
if (dayn >= (day4 - day0))
result = (((dayn - (day4 - day0)) / 7) + 1);
}
return (int) result;
}
/* timestamp_part()
* Extract specified field from timestamp.
*/
Datum
timestamp_part(PG_FUNCTION_ARGS)
{
text *units = PG_GETARG_TEXT_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
float8 result;
int tz;
int type,
val;
int i;
char *up,
*lp,
lowunits[MAXDATELEN + 1];
double dummy;
double fsec;
char *tzn;
struct tm tt,
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
lp = lowunits;
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
*lp++ = tolower((unsigned char) *up++);
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (type == IGNORE)
type = DecodeSpecial(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
{
result = 0;
PG_RETURN_FLOAT8(result);
}
if ((type == UNITS) && (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) == 0))
{
switch (val)
{
case DTK_TZ:
result = tz;
break;
case DTK_TZ_MINUTE:
result = tz / 60;
TMODULO(result, dummy, 60e0);
break;
case DTK_TZ_HOUR:
dummy = tz;
TMODULO(dummy, result, 3600e0);
break;
case DTK_MICROSEC:
result = (fsec * 1000000);
break;
case DTK_MILLISEC:
result = (fsec * 1000);
break;
case DTK_SECOND:
result = (tm->tm_sec + fsec);
break;
case DTK_MINUTE:
result = tm->tm_min;
break;
case DTK_HOUR:
result = tm->tm_hour;
break;
if (!*year)
elog(ERROR, "isoweek2date(): can't convert without year information");
case DTK_DAY:
result = tm->tm_mday;
break;
/* fourth day of current year */
day4 = date2j(*year, 1, 4);
case DTK_MONTH:
result = tm->tm_mon;
break;
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
case DTK_QUARTER:
result = ((tm->tm_mon - 1) / 3) + 1;
break;
dayn = ((woy - 1) * 7) + (day4 - day0);
case DTK_WEEK:
result = (float8) date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
break;
j2date(dayn, year, mon, mday);
}
case DTK_YEAR:
result = tm->tm_year;
break;
/* date2isoweek()
*
* Returns ISO week number of year.
*/
int
date2isoweek(int year, int mon, int mday)
{
float8 result;
int day0,
day4,
dayn;
case DTK_DECADE:
result = (tm->tm_year / 10);
break;
/* current day */
dayn = date2j(year, mon, mday);
case DTK_CENTURY:
result = (tm->tm_year / 100);
break;
/* fourth day of current year */
day4 = date2j(year, 1, 4);
case DTK_MILLENNIUM:
result = (tm->tm_year / 1000);
break;
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
result = 0;
}
/*
* We need the first week containing a Thursday, otherwise this day
* falls into the previous year for purposes of counting weeks
*/
if (dayn < (day4 - day0))
}
else if (type == RESERV)
{
day4 = date2j((year - 1), 1, 4);
switch (val)
{
case DTK_EPOCH:
result = timestamp - SetEpochTimestamp();
break;
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
}
case DTK_DOW:
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp");
result = (((dayn - (day4 - day0)) / 7) + 1);
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
break;
/*
* Sometimes the last few days in a year will fall into the first week
* of the next year, so check for this.
*/
if (result >= 53)
{
day4 = date2j((year + 1), 1, 4);
case DTK_DOY:
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp");
/* day0 == offset to first day of week (Monday) */
day0 = (j2day(day4 - 1) % 7);
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1);
break;
if (dayn >= (day4 - day0))
result = (((dayn - (day4 - day0)) / 7) + 1);
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
result = 0;
}
return (int) result;
}
}
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
result = 0;
}
PG_RETURN_FLOAT8(result);
}
/* timestamp_part()
* Extract specified field from timestamp.
/* timestamptz_part()
* Extract specified field from timestamp with time zone.
*/
Datum
timestamp_part(PG_FUNCTION_ARGS)
timestamptz_part(PG_FUNCTION_ARGS)
{
text *units = PG_GETARG_TEXT_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(1);
float8 result;
Timestamp dt;
int tz;
int type,
val;
......@@ -1857,12 +2303,12 @@ timestamp_part(PG_FUNCTION_ARGS)
type = DecodeSpecial(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_NULL();
else
{
dt = (TIMESTAMP_IS_RELATIVE(timestamp) ? SetTimestamp(timestamp) : timestamp);
result = 0;
PG_RETURN_FLOAT8(result);
}
if ((type == UNITS) && (timestamp2tm(dt, &tz, tm, &fsec, &tzn) == 0))
if ((type == UNITS) && (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) == 0))
{
switch (val)
{
......@@ -1933,7 +2379,7 @@ timestamp_part(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits);
result = 0;
}
......@@ -1943,37 +2389,34 @@ timestamp_part(PG_FUNCTION_ARGS)
switch (val)
{
case DTK_EPOCH:
TIMESTAMP_EPOCH(result);
result = dt - SetTimestamp(result);
result = timestamp - SetEpochTimestamp();
break;
case DTK_DOW:
if (timestamp2tm(dt, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp");
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp with time zone");
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
break;
case DTK_DOY:
if (timestamp2tm(dt, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp");
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp with time zone");
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1);
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits);
result = 0;
}
}
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
elog(ERROR, "Timestamp with time zone units '%s' not recognized", lowunits);
result = 0;
}
}
PG_RETURN_FLOAT8(result);
}
......@@ -2012,14 +2455,7 @@ interval_part(PG_FUNCTION_ARGS)
if (type == IGNORE)
type = DecodeSpecial(0, lowunits, &val);
if (INTERVAL_IS_INVALID(*interval))
{
#if NOT_USED
elog(ERROR, "Interval is not finite");
#endif
result = 0;
}
else if (type == UNITS)
if (type == UNITS)
{
if (interval2tm(*interval, tm, &fsec) == 0)
{
......@@ -2074,7 +2510,7 @@ interval_part(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Interval units '%s' not yet supported",
elog(ERROR, "Interval units '%s' not supported",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
result = 0;
......@@ -2083,7 +2519,8 @@ interval_part(PG_FUNCTION_ARGS)
}
else
{
elog(NOTICE, "Interval out of range");
elog(NOTICE, "Unable to decode interval"
"\n\tinterval_part() internal coding error");
result = 0;
}
}
......@@ -2116,8 +2553,142 @@ timestamp_zone(PG_FUNCTION_ARGS)
{
text *zone = PG_GETARG_TEXT_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz result;
int tz;
int type,
val;
int i;
char *up,
*lp,
lowzone[MAXDATELEN + 1];
if (VARSIZE(zone) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Time zone '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(zone))));
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMPTZ(timestamp);
up = VARDATA(zone);
lp = lowzone;
for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
*lp++ = tolower((unsigned char) *up++);
*lp = '\0';
type = DecodeSpecial(0, lowzone, &val);
if ((type == TZ) || (type == DTZ))
{
tz = val * 60;
result = timestamp - tz;
}
else
{
elog(ERROR, "Time zone '%s' not recognized", lowzone);
PG_RETURN_NULL();
}
PG_RETURN_TIMESTAMPTZ(result);
} /* timestamp_zone() */
/* timestamp_izone()
* Encode timestamp type with specified time interval as time zone.
* Require ISO-formatted result, since character-string time zone is not available.
*/
Datum
timestamp_izone(PG_FUNCTION_ARGS)
{
Interval *zone = PG_GETARG_INTERVAL_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz result;
int tz;
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMPTZ(timestamp);
if (zone->month != 0)
elog(ERROR, "INTERVAL time zone '%s' not legal (month specified)",
DatumGetCString(DirectFunctionCall1(interval_out,
PointerGetDatum(zone))));
tz = -(zone->time);
result = timestamp - tz;
PG_RETURN_TIMESTAMPTZ(result);
} /* timestamp_izone() */
/* timestamp_timestamptz()
* Convert local timestamp to timestamp at GMT
*/
Datum
timestamp_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
TimestampTz result;
struct tm tt,
*tm = &tt;
double fsec;
int tz;
if (TIMESTAMP_NOT_FINITE(timestamp))
{
result = timestamp;
}
else
{
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to convert timestamp to timestamp with time zone (tm)");
tz = DetermineLocalTimeZone(tm);
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Unable to convert timestamp to timestamp with time zone");
}
PG_RETURN_TIMESTAMPTZ(result);
}
/* timestamptz_timestamp()
* Convert timestamp at GMT to local timestamp
*/
Datum
timestamptz_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
Timestamp result;
struct tm tt,
*tm = &tt;
double fsec;
char *tzn;
int tz;
if (TIMESTAMP_NOT_FINITE(timestamp))
{
result = timestamp;
}
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert timestamp with time zone to timestamp (tm)");
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Unable to convert timestamp with time zone to timestamp");
}
PG_RETURN_TIMESTAMP(result);
}
/* timestamptz_zone()
* Encode timestamp with time zone type with specified time zone.
*/
Datum
timestamptz_zone(PG_FUNCTION_ARGS)
{
text *zone = PG_GETARG_TEXT_P(0);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(1);
text *result;
Timestamp dt;
TimestampTz dt;
int tz;
int type,
val;
......@@ -2146,17 +2717,18 @@ timestamp_zone(PG_FUNCTION_ARGS)
type = DecodeSpecial(0, lowzone, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_NULL();
else if ((type == TZ) || (type == DTZ))
PG_RETURN_TEXT_P(pstrdup(""));
if ((type == TZ) || (type == DTZ))
{
tm->tm_isdst = ((type == DTZ) ? 1 : 0);
tz = val * 60;
dt = (TIMESTAMP_IS_RELATIVE(timestamp) ? SetTimestamp(timestamp) : timestamp);
dt = dt2local(dt, tz);
dt = dt2local(timestamp, tz);
if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Timestamp not legal");
elog(ERROR, "Unable to decode timestamp"
"\n\ttimestamp_zone() internal coding error");
up = upzone;
lp = lowzone;
......@@ -2177,23 +2749,23 @@ timestamp_zone(PG_FUNCTION_ARGS)
else
{
elog(ERROR, "Time zone '%s' not recognized", lowzone);
result = NULL;
PG_RETURN_TEXT_P(pstrdup(""));
}
PG_RETURN_TEXT_P(result);
} /* timestamp_zone() */
} /* timestamptz_zone() */
/* timestamp_izone()
* Encode timestamp type with specified time interval as time zone.
/* timestamptz_izone()
* Encode timestamp with time zone type with specified time interval as time zone.
* Require ISO-formatted result, since character-string time zone is not available.
*/
Datum
timestamp_izone(PG_FUNCTION_ARGS)
timestamptz_izone(PG_FUNCTION_ARGS)
{
Interval *zone = PG_GETARG_INTERVAL_P(0);
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
TimestampTz timestamp = PG_GETARG_TIMESTAMP(1);
text *result;
Timestamp dt;
TimestampTz dt;
int tz;
char *tzn = "";
double fsec;
......@@ -2203,19 +2775,21 @@ timestamp_izone(PG_FUNCTION_ARGS)
int len;
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_NULL();
PG_RETURN_TEXT_P(pstrdup(""));
if (zone->month != 0)
elog(ERROR, "INTERVAL time zone not legal (month specified)");
elog(ERROR, "INTERVAL time zone '%s' not legal (month specified)",
DatumGetCString(DirectFunctionCall1(interval_out,
PointerGetDatum(zone))));
tm->tm_isdst = -1;
tz = -(zone->time);
dt = (TIMESTAMP_IS_RELATIVE(timestamp) ? SetTimestamp(timestamp) : timestamp);
dt = dt2local(dt, tz);
dt = dt2local(timestamp, tz);
if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Timestamp not legal");
elog(ERROR, "Unable to decode timestamp"
"\n\ttimestamp_izone() internal coding error");
EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
len = (strlen(buf) + VARHDRSZ);
......@@ -2225,4 +2799,4 @@ timestamp_izone(PG_FUNCTION_ARGS)
memmove(VARDATA(result), buf, (len - VARHDRSZ));
PG_RETURN_TEXT_P(result);
} /* timestamp_izone() */
} /* timestamptz_izone() */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: xact.h,v 1.36 2001/08/26 16:56:00 tgl Exp $
* $Id: xact.h,v 1.37 2001/09/28 08:09:12 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,6 +17,7 @@
#include "access/transam.h"
#include "access/xlog.h"
#include "utils/nabstime.h"
#include "utils/timestamp.h"
/*
* Xact isolation levels
......@@ -39,6 +40,7 @@ typedef struct TransactionStateData
CommandId commandId;
CommandId scanCommandId;
AbsoluteTime startTime;
int startTimeMsec;
int state;
int blockState;
} TransactionStateData;
......@@ -104,6 +106,7 @@ extern CommandId GetCurrentCommandId(void);
extern CommandId GetScanCommandId(void);
extern void SetScanCommandId(CommandId);
extern AbsoluteTime GetCurrentTransactionStartTime(void);
extern AbsoluteTime GetCurrentTransactionStartTimeUsec(int *usec);
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
extern bool CommandIdIsCurrentCommandId(CommandId cid);
extern bool CommandIdGEScanCommandId(CommandId cid);
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.95 2001/09/14 17:46:40 momjian Exp $
* $Id: catversion.h,v 1.96 2001/09/28 08:09:13 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200109101
#define CATALOG_VERSION_NO 200109261
#endif
......@@ -8,10 +8,21 @@
# no multibytes files
FILES=`ls pg_*.h |grep -v '_mb.h'`
#
# The previous version did not use the -d option on uniq
# so check here that it is supported.
# Otherwise, use the old algorithm
#
if [ `uniq -d < /dev/null > /dev/null 2>&1` ]; then
echo "uniq -d is not supported on your platform."
echo "Please report this to pgsql-hackers@postgresql.org"
egrep '^DATA' $FILES | \
sed -e 's/^.*OID[^=]*=[^0-9]*//' -e 's/[^0-9].*$//' | \
sort -n >/tmp/alloids.$$
uniq /tmp/alloids.$$ >/tmp/uniqoids.$$
diff -u /tmp/alloids.$$ /tmp/uniqoids.$$ | \
grep -v '/tmp/' | \
grep '^-' | \
......@@ -21,3 +32,16 @@ diff -u /tmp/alloids.$$ /tmp/uniqoids.$$ | \
rm /tmp/alloids.$$
rm /tmp/uniqoids.$$
else
# echo "uniq -d is supported on this platform."
# echo "Will omit the use of temporary files."
egrep '^DATA' $FILES | \
sed -e 's/^.*OID[^=]*=[^0-9]*//' -e 's/[^0-9].*$//' | \
sort -n | uniq -d | \
egrep -v '^[0]*$'
fi
exit
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_aggregate.h,v 1.31 2001/08/14 22:21:58 tgl Exp $
* $Id: pg_aggregate.h,v 1.32 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -109,7 +109,8 @@ DATA(insert OID = 0 ( max PGUID date_larger - 1082 1082 1082 _null_ ));
DATA(insert OID = 0 ( max PGUID time_larger - 1083 1083 1083 _null_ ));
DATA(insert OID = 0 ( max PGUID timetz_larger - 1266 1266 1266 _null_ ));
DATA(insert OID = 0 ( max PGUID cashlarger - 790 790 790 _null_ ));
DATA(insert OID = 0 ( max PGUID timestamp_larger - 1184 1184 1184 _null_ ));
DATA(insert OID = 0 ( max PGUID timestamp_larger - 1114 1114 1114 _null_ ));
DATA(insert OID = 0 ( max PGUID timestamptz_larger - 1184 1184 1184 _null_ ));
DATA(insert OID = 0 ( max PGUID interval_larger - 1186 1186 1186 _null_ ));
DATA(insert OID = 0 ( max PGUID text_larger - 25 25 25 _null_ ));
DATA(insert OID = 0 ( max PGUID numeric_larger - 1700 1700 1700 _null_ ));
......@@ -125,7 +126,8 @@ DATA(insert OID = 0 ( min PGUID date_smaller - 1082 1082 1082 _null_ ));
DATA(insert OID = 0 ( min PGUID time_smaller - 1083 1083 1083 _null_ ));
DATA(insert OID = 0 ( min PGUID timetz_smaller - 1266 1266 1266 _null_ ));
DATA(insert OID = 0 ( min PGUID cashsmaller - 790 790 790 _null_ ));
DATA(insert OID = 0 ( min PGUID timestamp_smaller - 1184 1184 1184 _null_ ));
DATA(insert OID = 0 ( min PGUID timestamp_smaller - 1114 1114 1114 _null_ ));
DATA(insert OID = 0 ( min PGUID timestamptz_smaller - 1184 1184 1184 _null_ ));
DATA(insert OID = 0 ( min PGUID interval_smaller - 1186 1186 1186 _null_ ));
DATA(insert OID = 0 ( min PGUID text_smaller - 25 25 25 _null_ ));
DATA(insert OID = 0 ( min PGUID numeric_smaller - 1700 1700 1700 _null_ ));
......
......@@ -16,7 +16,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_amop.h,v 1.41 2001/08/21 16:36:05 tgl Exp $
* $Id: pg_amop.h,v 1.42 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -282,6 +282,16 @@ DATA(insert ( 2000 5 f 1554 ));
* btree timestamp_ops
*/
DATA(insert ( 2039 1 f 2062 ));
DATA(insert ( 2039 2 f 2063 ));
DATA(insert ( 2039 3 f 2060 ));
DATA(insert ( 2039 4 f 2065 ));
DATA(insert ( 2039 5 f 2064 ));
/*
* btree timestamptz_ops
*/
DATA(insert ( 1998 1 f 1322 ));
DATA(insert ( 1998 2 f 1323 ));
DATA(insert ( 1998 3 f 1320 ));
......@@ -407,11 +417,13 @@ DATA(insert ( 1992 1 f 649 ));
DATA(insert ( 1995 1 f 98 ));
/* time_ops */
DATA(insert ( 1997 1 f 1108 ));
/* timestamp_ops */
/* timestamptz_ops */
DATA(insert ( 1999 1 f 1320 ));
/* timetz_ops */
DATA(insert ( 2001 1 f 1550 ));
/* varchar_ops */
DATA(insert ( 2004 1 f 1062 ));
/* timestamp_ops */
DATA(insert ( 2040 1 f 2060 ));
#endif /* PG_AMOP_H */
......@@ -14,7 +14,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_amproc.h,v 1.30 2001/08/21 16:36:05 tgl Exp $
* $Id: pg_amproc.h,v 1.31 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -104,6 +104,7 @@ DATA(insert ( 1998 1 1314 ));
DATA(insert ( 2000 1 1358 ));
DATA(insert ( 2002 1 1672 ));
DATA(insert ( 2003 1 1079 ));
DATA(insert ( 2039 1 1314 ));
/* hash */
......@@ -127,5 +128,6 @@ DATA(insert ( 1997 1 452 ));
DATA(insert ( 1999 1 452 ));
DATA(insert ( 2001 1 1696 ));
DATA(insert ( 2004 1 456 ));
DATA(insert ( 2040 1 452 ));
#endif /* PG_AMPROC_H */
......@@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_opclass.h,v 1.39 2001/08/21 16:36:05 tgl Exp $
* $Id: pg_opclass.h,v 1.40 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -127,12 +127,14 @@ DATA(insert OID = 1994 ( 403 text_ops 25 t 0 ));
DATA(insert OID = 1995 ( 405 text_ops 25 t 0 ));
DATA(insert OID = 1996 ( 403 time_ops 1083 t 0 ));
DATA(insert OID = 1997 ( 405 time_ops 1083 t 0 ));
DATA(insert OID = 1998 ( 403 timestamp_ops 1184 t 0 ));
DATA(insert OID = 1999 ( 405 timestamp_ops 1184 t 0 ));
DATA(insert OID = 1998 ( 403 timestamptz_ops 1184 t 0 ));
DATA(insert OID = 1999 ( 405 timestamptz_ops 1184 t 0 ));
DATA(insert OID = 2000 ( 403 timetz_ops 1266 t 0 ));
DATA(insert OID = 2001 ( 405 timetz_ops 1266 t 0 ));
DATA(insert OID = 2002 ( 403 varbit_ops 1562 t 0 ));
DATA(insert OID = 2003 ( 403 varchar_ops 1043 t 0 ));
DATA(insert OID = 2004 ( 405 varchar_ops 1043 t 0 ));
DATA(insert OID = 2039 ( 403 timestamp_ops 1114 t 0 ));
DATA(insert OID = 2040 ( 405 timestamp_ops 1114 t 0 ));
#endif /* PG_OPCLASS_H */
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.93 2001/09/14 17:46:40 momjian Exp $
* $Id: pg_operator.h,v 1.94 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -483,8 +483,10 @@ DATA(insert OID = 1110 ( "<" PGUID 0 b t f 1083 1083 16 1112 1113 0 0 time_
DATA(insert OID = 1111 ( "<=" PGUID 0 b t f 1083 1083 16 1113 1112 0 0 time_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 1112 ( ">" PGUID 0 b t f 1083 1083 16 1110 1111 0 0 time_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 1113 ( ">=" PGUID 0 b t f 1083 1083 16 1111 1110 0 0 time_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 1269 ( "-" PGUID 0 b t f 1186 1083 1083 0 0 0 0 interval_mi_time - - ));
/* timetz operators */
DATA(insert OID = 1295 ( "-" PGUID 0 b t f 1186 1266 1266 0 0 0 0 interval_mi_timetz - - ));
DATA(insert OID = 1550 ( "=" PGUID 0 b t f 1266 1266 16 1550 1551 1552 1552 timetz_eq eqsel eqjoinsel ));
DATA(insert OID = 1551 ( "<>" PGUID 0 b t f 1266 1266 16 1551 1550 0 0 timetz_ne neqsel neqjoinsel ));
DATA(insert OID = 1552 ( "<" PGUID 0 b t f 1266 1266 16 1554 1555 0 0 timetz_lt scalarltsel scalarltjoinsel ));
......@@ -551,7 +553,7 @@ DATA(insert OID = 1234 ( "~*" PGUID 0 b t f 1042 25 16 0 1235 0 0 texticreg
#define OID_BPCHAR_ICREGEXEQ_OP 1234
DATA(insert OID = 1235 ( "!~*" PGUID 0 b t f 1042 25 16 0 1234 0 0 texticregexne icregexnesel icregexnejoinsel ));
/* timestamp operators */
/* timestamptz operators */
/* name, owner, prec, kind, isleft, canhash, left, right, result, com, negate, lsortop, rsortop, oprcode, operrest, oprjoin */
DATA(insert OID = 1320 ( "=" PGUID 0 b t f 1184 1184 16 1320 1321 1322 1322 timestamp_eq eqsel eqjoinsel ));
DATA(insert OID = 1321 ( "<>" PGUID 0 b t f 1184 1184 16 1321 1320 0 0 timestamp_ne neqsel neqjoinsel ));
......@@ -559,9 +561,9 @@ DATA(insert OID = 1322 ( "<" PGUID 0 b t f 1184 1184 16 1324 1325 0 0 times
DATA(insert OID = 1323 ( "<=" PGUID 0 b t f 1184 1184 16 1325 1324 0 0 timestamp_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 1324 ( ">" PGUID 0 b t f 1184 1184 16 1322 1323 0 0 timestamp_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 1325 ( ">=" PGUID 0 b t f 1184 1184 16 1323 1322 0 0 timestamp_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 1327 ( "+" PGUID 0 b t f 1184 1186 1184 0 0 0 0 timestamp_pl_span - - ));
DATA(insert OID = 1328 ( "-" PGUID 0 b t f 1184 1184 1186 0 0 0 0 timestamp_mi - - ));
DATA(insert OID = 1329 ( "-" PGUID 0 b t f 1184 1186 1184 0 0 0 0 timestamp_mi_span - - ));
DATA(insert OID = 1327 ( "+" PGUID 0 b t f 1184 1186 1184 0 0 0 0 timestamptz_pl_span - - ));
DATA(insert OID = 1328 ( "-" PGUID 0 b t f 1184 1184 1186 0 0 0 0 timestamptz_mi - - ));
DATA(insert OID = 1329 ( "-" PGUID 0 b t f 1184 1186 1184 0 0 0 0 timestamptz_mi_span - - ));
/* interval operators */
DATA(insert OID = 1330 ( "=" PGUID 0 b t f 1186 1186 16 1330 1331 1332 1332 interval_eq eqsel eqjoinsel ));
......@@ -575,11 +577,13 @@ DATA(insert OID = 1336 ( "-" PGUID 0 l t f 0 1186 1186 0 0 0 0 interval_u
DATA(insert OID = 1337 ( "+" PGUID 0 b t f 1186 1186 1186 1337 0 0 0 interval_pl - - ));
DATA(insert OID = 1338 ( "-" PGUID 0 b t f 1186 1186 1186 0 0 0 0 interval_mi - - ));
DATA(insert OID = 1360 ( "+" PGUID 0 b t f 1082 1083 1184 0 0 0 0 datetime_pl - - ));
DATA(insert OID = 1360 ( "+" PGUID 0 b t f 1082 1083 1114 0 0 0 0 datetime_pl - - ));
DATA(insert OID = 1361 ( "+" PGUID 0 b t f 1082 1266 1184 0 0 0 0 datetimetz_pl - - ));
DATA(insert OID = 1363 ( "+" PGUID 0 b t f 1083 1082 1184 0 0 0 0 timedate_pl - - ));
DATA(insert OID = 1363 ( "+" PGUID 0 b t f 1083 1082 1114 0 0 0 0 timedate_pl - - ));
DATA(insert OID = 1366 ( "+" PGUID 0 b t f 1266 1082 1184 0 0 0 0 timetzdate_pl - - ));
DATA(insert OID = 1399 ( "-" PGUID 0 b t f 1083 1083 1186 0 0 0 0 time_mi_time - - ));
/* additional geometric operators - thomas 97/04/18 */
DATA(insert OID = 1420 ( "@@" PGUID 0 l t f 0 718 600 0 0 0 0 circle_center - - ));
DATA(insert OID = 1500 ( "=" PGUID 0 b t f 718 718 16 1500 1501 1502 1502 circle_eq eqsel eqjoinsel ));
......@@ -821,6 +825,19 @@ DATA(insert OID = 2016 ( "~~" PGUID 0 b t f 17 17 16 0 2017 0 0 bytea
DATA(insert OID = 2017 ( "!~~" PGUID 0 b t f 17 17 16 0 2016 0 0 byteanlike nlikesel nlikejoinsel ));
DATA(insert OID = 2018 ( "||" PGUID 0 b t f 17 17 17 0 0 0 0 byteacat - - ));
/* timestamp operators */
/* name, owner, prec, kind, isleft, canhash, left, right, result, com, negate, lsortop, rsortop, oprcode, operrest, oprjoin */
DATA(insert OID = 2060 ( "=" PGUID 0 b t f 1114 1114 16 2060 2061 2062 2062 timestamp_eq eqsel eqjoinsel ));
DATA(insert OID = 2061 ( "<>" PGUID 0 b t f 1114 1114 16 2061 2060 0 0 timestamp_ne neqsel neqjoinsel ));
DATA(insert OID = 2062 ( "<" PGUID 0 b t f 1114 1114 16 2064 2065 0 0 timestamp_lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 2063 ( "<=" PGUID 0 b t f 1114 1114 16 2065 2064 0 0 timestamp_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 2064 ( ">" PGUID 0 b t f 1114 1114 16 2062 2063 0 0 timestamp_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 2065 ( ">=" PGUID 0 b t f 1114 1114 16 2063 2062 0 0 timestamp_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 2066 ( "+" PGUID 0 b t f 1114 1186 1114 0 0 0 0 timestamp_pl_span - - ));
DATA(insert OID = 2067 ( "-" PGUID 0 b t f 1114 1114 1186 0 0 0 0 timestamp_mi - - ));
DATA(insert OID = 2068 ( "-" PGUID 0 b t f 1114 1186 1114 0 0 0 0 timestamp_mi_span - - ));
/*
* function prototypes
*/
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.211 2001/09/14 17:46:40 momjian Exp $
* $Id: pg_proc.h,v 1.212 2001/09/28 08:09:13 thomas Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -501,9 +501,9 @@ DATA(insert OID = 242 ( reltimein PGUID 12 f t f t 1 f 703 "0" 100 0 0 100
DESCR("(internal)");
DATA(insert OID = 243 ( reltimeout PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 reltimeout - ));
DESCR("(internal)");
DATA(insert OID = 244 ( timepl PGUID 12 f t f t 2 f 702 "702 703" 100 0 0 100 timepl - ));
DATA(insert OID = 244 ( timepl PGUID 12 f t t t 2 f 702 "702 703" 100 0 0 100 timepl - ));
DESCR("add");
DATA(insert OID = 245 ( timemi PGUID 12 f t f t 2 f 702 "702 703" 100 0 0 100 timemi - ));
DATA(insert OID = 245 ( timemi PGUID 12 f t t t 2 f 702 "702 703" 100 0 0 100 timemi - ));
DESCR("subtract");
DATA(insert OID = 246 ( tintervalin PGUID 12 f t f t 1 f 704 "0" 100 0 0 100 tintervalin - ));
DESCR("(internal)");
......@@ -1119,8 +1119,6 @@ DATA(insert OID = 886 ( cash_in PGUID 12 f t t t 1 f 790 "0" 100 0 0 100
DESCR("(internal)");
DATA(insert OID = 887 ( cash_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 cash_out - ));
DESCR("(internal)");
DATA(insert OID = 1273 ( cash_words PGUID 12 f t t t 1 f 25 "790" 100 0 0 100 cash_words - ));
DESCR("output amount as words");
DATA(insert OID = 888 ( cash_eq PGUID 12 f t t t 2 f 16 "790 790" 100 0 0 100 cash_eq - ));
DESCR("equal");
DATA(insert OID = 889 ( cash_ne PGUID 12 f t t t 2 f 16 "790 790" 100 0 0 100 cash_ne - ));
......@@ -1145,9 +1143,10 @@ DATA(insert OID = 898 ( cashlarger PGUID 12 f t t t 2 f 790 "790 790" 100 0
DESCR("larger of two");
DATA(insert OID = 899 ( cashsmaller PGUID 12 f t t t 2 f 790 "790 790" 100 0 0 100 cashsmaller - ));
DESCR("smaller of two");
DATA(insert OID = 919 ( flt8_mul_cash PGUID 12 f t t t 2 f 790 "701 790" 100 0 0 100 flt8_mul_cash - ));
DESCR("multiply");
DATA(insert OID = 935 ( cash_words PGUID 12 f t t t 1 f 25 "790" 100 0 0 100 cash_words - ));
DESCR("output amount as words");
/* OIDS 900 - 999 */
......@@ -1257,22 +1256,22 @@ DESCR("horizontal?");
DATA(insert OID = 999 ( lseg_eq PGUID 12 f t t t 2 f 16 "601 601" 100 0 0 100 lseg_eq - ));
DESCR("equal");
DATA(insert OID = 748 ( date PGUID 12 f t f t 1 f 1082 "25" 100 0 0 100 text_date - ));
DATA(insert OID = 748 ( date PGUID 12 f t t t 1 f 1082 "25" 100 0 0 100 text_date - ));
DESCR("convert text to date");
DATA(insert OID = 749 ( text PGUID 12 f t f t 1 f 25 "1082" 100 0 0 100 date_text - ));
DATA(insert OID = 749 ( text PGUID 12 f t t t 1 f 25 "1082" 100 0 0 100 date_text - ));
DESCR("convert date to text");
DATA(insert OID = 837 ( time PGUID 12 f t f t 1 f 1083 "25" 100 0 0 100 text_time - ));
DATA(insert OID = 837 ( time PGUID 12 f t t t 1 f 1083 "25" 100 0 0 100 text_time - ));
DESCR("convert text to time");
DATA(insert OID = 948 ( text PGUID 12 f t f t 1 f 25 "1083" 100 0 0 100 time_text - ));
DATA(insert OID = 948 ( text PGUID 12 f t t t 1 f 25 "1083" 100 0 0 100 time_text - ));
DESCR("convert time to text");
DATA(insert OID = 938 ( timetz PGUID 12 f t f t 1 f 1266 "25" 100 0 0 100 text_timetz - ));
DATA(insert OID = 938 ( timetz PGUID 12 f t t t 1 f 1266 "25" 100 0 0 100 text_timetz - ));
DESCR("convert text to timetz");
DATA(insert OID = 939 ( text PGUID 12 f t f t 1 f 25 "1266" 100 0 0 100 timetz_text - ));
DATA(insert OID = 939 ( text PGUID 12 f t t t 1 f 25 "1266" 100 0 0 100 timetz_text - ));
DESCR("convert timetz to text");
/* OIDS 1000 - 1999 */
DATA(insert OID = 1026 ( timezone PGUID 12 f t f t 2 f 25 "1186 1184" 100 0 0 100 timestamp_izone - ));
DATA(insert OID = 1026 ( timezone PGUID 12 f t t t 2 f 25 "1186 1184" 100 0 0 100 timestamptz_izone - ));
DESCR("time zone");
DATA(insert OID = 1029 ( nullvalue PGUID 12 f t t f 1 f 16 "0" 100 0 0 100 nullvalue - ));
......@@ -1333,7 +1332,7 @@ DATA(insert OID = 1081 ( format_type PGUID 12 f t t f 2 f 25 "26 23" 100 0 0
DESCR("format a type oid and atttypmod to canonical SQL");
DATA(insert OID = 1084 ( date_in PGUID 12 f t f t 1 f 1082 "0" 100 0 0 100 date_in - ));
DESCR("(internal)");
DATA(insert OID = 1085 ( date_out PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 date_out - ));
DATA(insert OID = 1085 ( date_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 date_out - ));
DESCR("(internal)");
DATA(insert OID = 1086 ( date_eq PGUID 12 f t t t 2 f 16 "1082 1082" 100 0 0 100 date_eq - ));
DESCR("equal");
......@@ -1376,7 +1375,7 @@ DATA(insert OID = 1142 ( date_mii PGUID 12 f t t t 2 f 1082 "1082 23" 100 0
DESCR("subtract");
DATA(insert OID = 1143 ( time_in PGUID 12 f t f t 1 f 1083 "0" 100 0 0 100 time_in - ));
DESCR("(internal)");
DATA(insert OID = 1144 ( time_out PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 time_out - ));
DATA(insert OID = 1144 ( time_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 time_out - ));
DESCR("(internal)");
DATA(insert OID = 1145 ( time_eq PGUID 12 f t t t 2 f 16 "1083 1083" 100 0 0 100 time_eq - ));
DESCR("equal");
......@@ -1390,92 +1389,92 @@ DESCR("multiply");
DATA(insert OID = 1149 ( circle_div_pt PGUID 12 f t t t 2 f 718 "718 600" 100 0 0 100 circle_div_pt - ));
DESCR("divide");
DATA(insert OID = 1150 ( timestamp_in PGUID 12 f t f t 1 f 1184 "0" 100 0 0 100 timestamp_in - ));
DATA(insert OID = 1150 ( timestamptz_in PGUID 12 f t f t 1 f 1184 "0" 100 0 0 100 timestamptz_in - ));
DESCR("(internal)");
DATA(insert OID = 1151 ( timestamp_out PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 timestamp_out - ));
DATA(insert OID = 1151 ( timestamptz_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 timestamptz_out - ));
DESCR("(internal)");
DATA(insert OID = 1152 ( timestamp_eq PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_eq - ));
DATA(insert OID = 1152 ( timestamptz_eq PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_eq - ));
DESCR("equal");
DATA(insert OID = 1153 ( timestamp_ne PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_ne - ));
DATA(insert OID = 1153 ( timestamptz_ne PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_ne - ));
DESCR("not equal");
DATA(insert OID = 1154 ( timestamp_lt PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_lt - ));
DATA(insert OID = 1154 ( timestamptz_lt PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_lt - ));
DESCR("less-than");
DATA(insert OID = 1155 ( timestamp_le PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_le - ));
DATA(insert OID = 1155 ( timestamptz_le PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_le - ));
DESCR("less-than-or-equal");
DATA(insert OID = 1156 ( timestamp_ge PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_ge - ));
DATA(insert OID = 1156 ( timestamptz_ge PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_ge - ));
DESCR("greater-than-or-equal");
DATA(insert OID = 1157 ( timestamp_gt PGUID 12 f t f t 2 f 16 "1184 1184" 100 0 0 100 timestamp_gt - ));
DATA(insert OID = 1157 ( timestamptz_gt PGUID 12 f t t t 2 f 16 "1184 1184" 100 0 0 100 timestamp_gt - ));
DESCR("greater-than");
DATA(insert OID = 1159 ( timezone PGUID 12 f t f t 2 f 25 "25 1184" 100 0 0 100 timestamp_zone - ));
DATA(insert OID = 1159 ( timezone PGUID 12 f t f t 2 f 25 "25 1184" 100 0 0 100 timestamptz_zone - ));
DESCR("time zone");
DATA(insert OID = 1160 ( interval_in PGUID 12 f t f t 1 f 1186 "0" 100 0 0 100 interval_in - ));
DESCR("(internal)");
DATA(insert OID = 1161 ( interval_out PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 interval_out - ));
DATA(insert OID = 1161 ( interval_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 interval_out - ));
DESCR("(internal)");
DATA(insert OID = 1162 ( interval_eq PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_eq - ));
DATA(insert OID = 1162 ( interval_eq PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_eq - ));
DESCR("equal");
DATA(insert OID = 1163 ( interval_ne PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_ne - ));
DATA(insert OID = 1163 ( interval_ne PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_ne - ));
DESCR("not equal");
DATA(insert OID = 1164 ( interval_lt PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_lt - ));
DATA(insert OID = 1164 ( interval_lt PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_lt - ));
DESCR("less-than");
DATA(insert OID = 1165 ( interval_le PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_le - ));
DATA(insert OID = 1165 ( interval_le PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_le - ));
DESCR("less-than-or-equal");
DATA(insert OID = 1166 ( interval_ge PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_ge - ));
DATA(insert OID = 1166 ( interval_ge PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_ge - ));
DESCR("greater-than-or-equal");
DATA(insert OID = 1167 ( interval_gt PGUID 12 f t f t 2 f 16 "1186 1186" 100 0 0 100 interval_gt - ));
DATA(insert OID = 1167 ( interval_gt PGUID 12 f t t t 2 f 16 "1186 1186" 100 0 0 100 interval_gt - ));
DESCR("greater-than");
DATA(insert OID = 1168 ( interval_um PGUID 12 f t f t 1 f 1186 "1186" 100 0 0 100 interval_um - ));
DATA(insert OID = 1168 ( interval_um PGUID 12 f t t t 1 f 1186 "1186" 100 0 0 100 interval_um - ));
DESCR("subtract");
DATA(insert OID = 1169 ( interval_pl PGUID 12 f t f t 2 f 1186 "1186 1186" 100 0 0 100 interval_pl - ));
DATA(insert OID = 1169 ( interval_pl PGUID 12 f t t t 2 f 1186 "1186 1186" 100 0 0 100 interval_pl - ));
DESCR("add");
DATA(insert OID = 1170 ( interval_mi PGUID 12 f t f t 2 f 1186 "1186 1186" 100 0 0 100 interval_mi - ));
DATA(insert OID = 1170 ( interval_mi PGUID 12 f t t t 2 f 1186 "1186 1186" 100 0 0 100 interval_mi - ));
DESCR("subtract");
DATA(insert OID = 1171 ( date_part PGUID 12 f t f t 2 f 701 "25 1184" 100 0 0 100 timestamp_part - ));
DESCR("extract field from timestamp");
DATA(insert OID = 1172 ( date_part PGUID 12 f t f t 2 f 701 "25 1186" 100 0 0 100 interval_part - ));
DATA(insert OID = 1171 ( date_part PGUID 12 f t t t 2 f 701 "25 1184" 100 0 0 100 timestamptz_part - ));
DESCR("extract field from timestamp with time zone");
DATA(insert OID = 1172 ( date_part PGUID 12 f t t t 2 f 701 "25 1186" 100 0 0 100 interval_part - ));
DESCR("extract field from interval");
DATA(insert OID = 1173 ( timestamp PGUID 12 f t f t 1 f 1184 "702" 100 0 0 100 abstime_timestamp - ));
DESCR("convert abstime to timestamp");
DATA(insert OID = 1174 ( timestamp PGUID 12 f t f t 1 f 1184 "1082" 100 0 0 100 date_timestamp - ));
DESCR("convert date to timestamp");
DATA(insert OID = 1176 ( timestamp PGUID 12 f t f t 2 f 1184 "1082 1083" 100 0 0 100 datetime_timestamp - ));
DESCR("convert date and time to timestamp");
DATA(insert OID = 1177 ( interval PGUID 12 f t f t 1 f 1186 "703" 100 0 0 100 reltime_interval - ));
DATA(insert OID = 1173 ( timestamptz PGUID 12 f t f t 1 f 1184 "702" 100 0 0 100 abstime_timestamptz - ));
DESCR("convert abstime to timestamp with time zone");
DATA(insert OID = 1174 ( timestamptz PGUID 12 f t f t 1 f 1184 "1082" 100 0 0 100 date_timestamptz - ));
DESCR("convert date to timestamp with time zone");
DATA(insert OID = 1176 ( timestamptz PGUID 14 f t f t 2 f 1184 "1082 1083" 100 0 0 100 "select timestamptz($1 + $2)" - ));
DESCR("convert date and time to timestamp with time zone");
DATA(insert OID = 1177 ( interval PGUID 12 f t t t 1 f 1186 "703" 100 0 0 100 reltime_interval - ));
DESCR("convert reltime to interval");
DATA(insert OID = 1178 ( date PGUID 12 f t f t 1 f 1082 "1184" 100 0 0 100 timestamp_date - ));
DESCR("convert timestamp to date");
DATA(insert OID = 1178 ( date PGUID 12 f t f t 1 f 1082 "1184" 100 0 0 100 timestamptz_date - ));
DESCR("convert timestamp with time zone to date");
DATA(insert OID = 1179 ( date PGUID 12 f t f t 1 f 1082 "702" 100 0 0 100 abstime_date - ));
DESCR("convert abstime to date");
DATA(insert OID = 1180 ( abstime PGUID 12 f t f t 1 f 702 "1184" 100 0 0 100 timestamp_abstime - ));
DESCR("convert timestamp to abstime");
DATA(insert OID = 1180 ( abstime PGUID 12 f t f t 1 f 702 "1184" 100 0 0 100 timestamptz_abstime - ));
DESCR("convert timestamp with time zone to abstime");
DATA(insert OID = 1181 ( age PGUID 12 f t f t 1 f 23 "28" 100 0 0 100 xid_age - ));
DESCR("age of a transaction ID, in transactions before current transaction");
DATA(insert OID = 1188 ( timestamp_mi PGUID 12 f t f t 2 f 1186 "1184 1184" 100 0 0 100 timestamp_mi - ));
DATA(insert OID = 1188 ( timestamptz_mi PGUID 12 f t t t 2 f 1186 "1184 1184" 100 0 0 100 timestamp_mi - ));
DESCR("subtract");
DATA(insert OID = 1189 ( timestamp_pl_span PGUID 12 f t f t 2 f 1184 "1184 1186" 100 0 0 100 timestamp_pl_span - ));
DATA(insert OID = 1189 ( timestamptz_pl_span PGUID 12 f t t t 2 f 1184 "1184 1186" 100 0 0 100 timestamp_pl_span - ));
DESCR("plus");
DATA(insert OID = 1190 ( timestamp_mi_span PGUID 12 f t f t 2 f 1184 "1184 1186" 100 0 0 100 timestamp_mi_span - ));
DATA(insert OID = 1190 ( timestamptz_mi_span PGUID 12 f t t t 2 f 1184 "1184 1186" 100 0 0 100 timestamp_mi_span - ));
DESCR("minus");
DATA(insert OID = 1191 ( timestamp PGUID 12 f t f t 1 f 1184 "25" 100 0 0 100 text_timestamp - ));
DESCR("convert text to timestamp");
DATA(insert OID = 1192 ( text PGUID 12 f t f t 1 f 25 "1184" 100 0 0 100 timestamp_text - ));
DATA(insert OID = 1191 ( timestamptz PGUID 12 f t t t 1 f 1184 "25" 100 0 0 100 text_timestamptz - ));
DESCR("convert text to timestamp with time zone");
DATA(insert OID = 1192 ( text PGUID 12 f t t t 1 f 25 "1184" 100 0 0 100 timestamptz_text - ));
DESCR("convert timestamp to text");
DATA(insert OID = 1193 ( text PGUID 12 f t f t 1 f 25 "1186" 100 0 0 100 interval_text - ));
DATA(insert OID = 1193 ( text PGUID 12 f t t t 1 f 25 "1186" 100 0 0 100 interval_text - ));
DESCR("convert interval to text");
DATA(insert OID = 1194 ( reltime PGUID 12 f t f t 1 f 703 "1186" 100 0 0 100 interval_reltime - ));
DATA(insert OID = 1194 ( reltime PGUID 12 f t t t 1 f 703 "1186" 100 0 0 100 interval_reltime - ));
DESCR("convert interval to reltime");
DATA(insert OID = 1195 ( timestamp_smaller PGUID 12 f t f t 2 f 1184 "1184 1184" 100 0 0 100 timestamp_smaller - ));
DATA(insert OID = 1195 ( timestamptz_smaller PGUID 12 f t t t 2 f 1184 "1184 1184" 100 0 0 100 timestamp_smaller - ));
DESCR("smaller of two");
DATA(insert OID = 1196 ( timestamp_larger PGUID 12 f t f t 2 f 1184 "1184 1184" 100 0 0 100 timestamp_larger - ));
DATA(insert OID = 1196 ( timestamptz_larger PGUID 12 f t t t 2 f 1184 "1184 1184" 100 0 0 100 timestamp_larger - ));
DESCR("larger of two");
DATA(insert OID = 1197 ( interval_smaller PGUID 12 f t f t 2 f 1186 "1186 1186" 100 0 0 100 interval_smaller - ));
DATA(insert OID = 1197 ( interval_smaller PGUID 12 f t t t 2 f 1186 "1186 1186" 100 0 0 100 interval_smaller - ));
DESCR("smaller of two");
DATA(insert OID = 1198 ( interval_larger PGUID 12 f t f t 2 f 1186 "1186 1186" 100 0 0 100 interval_larger - ));
DATA(insert OID = 1198 ( interval_larger PGUID 12 f t t t 2 f 1186 "1186 1186" 100 0 0 100 interval_larger - ));
DESCR("larger of two");
DATA(insert OID = 1199 ( age PGUID 12 f t f t 2 f 1186 "1184 1184" 100 0 0 100 timestamp_age - ));
DATA(insert OID = 1199 ( age PGUID 12 f t t t 2 f 1186 "1184 1184" 100 0 0 100 timestamptz_age - ));
DESCR("date difference preserving months and years");
/* OIDS 1200 - 1299 */
......@@ -1488,9 +1487,9 @@ DESCR("get description for object id and catalog name");
DATA(insert OID = 1216 ( col_description PGUID 14 f t f t 2 f 25 "26 23" 100 0 0 100 "select description from pg_description where objoid = $1 and classoid = (select oid from pg_class where relname = \'pg_class\') and objsubid = $2" - ));
DESCR("get description for table column");
DATA(insert OID = 1217 ( date_trunc PGUID 12 f t f t 2 f 1184 "25 1184" 100 0 0 100 timestamp_trunc - ));
DESCR("truncate timestamp to specified units");
DATA(insert OID = 1218 ( date_trunc PGUID 12 f t f t 2 f 1186 "25 1186" 100 0 0 100 interval_trunc - ));
DATA(insert OID = 1217 ( date_trunc PGUID 12 f t t t 2 f 1184 "25 1184" 100 0 0 100 timestamptz_trunc - ));
DESCR("truncate timestamp with time zone to specified units");
DATA(insert OID = 1218 ( date_trunc PGUID 12 f t t t 2 f 1186 "25 1186" 100 0 0 100 interval_trunc - ));
DESCR("truncate interval to specified units");
DATA(insert OID = 1219 ( int8inc PGUID 12 f t t t 1 f 20 "20" 100 0 0 100 int8inc - ));
......@@ -1517,12 +1516,12 @@ DESCR("absolute value");
DATA(insert OID = 1253 ( int2abs PGUID 12 f t t t 1 f 21 "21" 100 0 0 100 int2abs - ));
DESCR("absolute value");
DATA(insert OID = 1263 ( interval PGUID 12 f t f t 1 f 1186 "25" 100 0 0 100 text_interval - ));
DATA(insert OID = 1263 ( interval PGUID 12 f t t t 1 f 1186 "25" 100 0 0 100 text_interval - ));
DESCR("convert text to interval");
DATA(insert OID = 1271 ( overlaps PGUID 12 f t t f 4 f 16 "1266 1266 1266 1266" 100 0 0 100 overlaps_timetz - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 1272 ( datetime_pl PGUID 12 f t f t 2 f 1184 "1082 1083" 100 0 0 100 datetime_timestamp - ));
DATA(insert OID = 1272 ( datetime_pl PGUID 12 f t t t 2 f 1114 "1082 1083" 100 0 0 100 datetime_timestamp - ));
DESCR("convert date and time to timestamp");
DATA(insert OID = 1274 ( int84pl PGUID 12 f t t t 2 f 20 "20 23" 100 0 0 100 int84pl - ));
......@@ -1559,11 +1558,11 @@ DESCR("latest tid of a tuple");
DATA(insert OID = 1294 ( currtid2 PGUID 12 f t f t 2 f 27 "25 27" 100 0 0 100 currtid_byrelname - ));
DESCR("latest tid of a tuple");
DATA(insert OID = 1296 ( timedate_pl PGUID 14 f t f t 2 f 1184 "1083 1082" 100 0 0 100 "select datetime_pl($2, $1)" - ));
DATA(insert OID = 1296 ( timedate_pl PGUID 14 f t t t 2 f 1114 "1083 1082" 100 0 0 100 "select datetime_pl($2, $1)" - ));
DESCR("convert time and date to timestamp");
DATA(insert OID = 1297 ( datetimetz_pl PGUID 12 f t f t 2 f 1184 "1082 1266" 100 0 0 100 datetimetz_timestamp - ));
DESCR("convert date and time with time zone to timestamp");
DATA(insert OID = 1298 ( timetzdate_pl PGUID 14 f t f t 2 f 1184 "1266 1082" 100 0 0 100 "select datetimetz_pl($2, $1)" - ));
DATA(insert OID = 1297 ( datetimetz_pl PGUID 12 f t t t 2 f 1184 "1082 1266" 100 0 0 100 datetimetz_timestamptz - ));
DESCR("convert date and time with time zone to timestamp with time zone");
DATA(insert OID = 1298 ( timetzdate_pl PGUID 14 f t t t 2 f 1184 "1266 1082" 100 0 0 100 "select datetimetz_pl($2, $1)" - ));
DESCR("convert time with time zone and date to timestamp");
DATA(insert OID = 1299 ( now PGUID 12 f t f t 0 f 1184 "0" 100 0 0 100 now - ));
DESCR("current transaction time");
......@@ -1597,11 +1596,15 @@ DESCR("SQL92 interval comparison");
DATA(insert OID = 1311 ( overlaps PGUID 14 f t t f 4 f 16 "1083 1186 1083 1083" 100 0 0 100 "select ($1, ($1 + $2)) overlaps ($3, $4)" - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 1314 ( timestamp_cmp PGUID 12 f t f t 2 f 23 "1184 1184" 100 0 0 100 timestamp_cmp - ));
DATA(insert OID = 1312 ( timestamp_in PGUID 12 f t f t 1 f 1114 "0" 100 0 0 100 timestamp_in - ));
DESCR("(internal)");
DATA(insert OID = 1313 ( timestamp_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 timestamp_out - ));
DESCR("(internal)");
DATA(insert OID = 1314 ( timestamptz_cmp PGUID 12 f t t t 2 f 23 "1184 1184" 100 0 0 100 timestamp_cmp - ));
DESCR("less-equal-greater");
DATA(insert OID = 1315 ( interval_cmp PGUID 12 f t f t 2 f 23 "1186 1186" 100 0 0 100 interval_cmp - ));
DATA(insert OID = 1315 ( interval_cmp PGUID 12 f t t t 2 f 23 "1186 1186" 100 0 0 100 interval_cmp - ));
DESCR("less-equal-greater");
DATA(insert OID = 1316 ( time PGUID 12 f t f t 1 f 1083 "1184" 100 0 0 100 timestamp_time - ));
DATA(insert OID = 1316 ( time PGUID 12 f t t t 1 f 1083 "1114" 100 0 0 100 timestamp_time - ));
DESCR("convert timestamp to time");
DATA(insert OID = 1317 ( length PGUID 12 f t t t 1 f 23 "25" 100 0 0 100 textlen - ));
......@@ -1611,7 +1614,7 @@ DESCR("character length");
DATA(insert OID = 1319 ( length PGUID 12 f t t t 1 f 23 "1043" 100 0 0 100 varcharlen - ));
DESCR("character length");
DATA(insert OID = 1326 ( interval_div PGUID 12 f t f t 2 f 1186 "1186 701" 100 0 0 100 interval_div - ));
DATA(insert OID = 1326 ( interval_div PGUID 12 f t t t 2 f 1186 "1186 701" 100 0 0 100 interval_div - ));
DESCR("divide");
DATA(insert OID = 1339 ( dlog10 PGUID 12 f t t t 1 f 701 "701" 100 0 0 100 dlog10 - ));
......@@ -1645,7 +1648,7 @@ DESCR("print type names of oidvector field");
DATA(insert OID = 1350 ( timetz_in PGUID 12 f t f t 1 f 1266 "0" 100 0 0 100 timetz_in - ));
DESCR("(internal)");
DATA(insert OID = 1351 ( timetz_out PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 timetz_out - ));
DATA(insert OID = 1351 ( timetz_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 timetz_out - ));
DESCR("(internal)");
DATA(insert OID = 1352 ( timetz_eq PGUID 12 f t t t 2 f 16 "1266 1266" 100 0 0 100 timetz_eq - ));
DESCR("equal");
......@@ -1661,22 +1664,22 @@ DATA(insert OID = 1357 ( timetz_gt PGUID 12 f t t t 2 f 16 "1266 1266" 100
DESCR("greater-than");
DATA(insert OID = 1358 ( timetz_cmp PGUID 12 f t t t 2 f 23 "1266 1266" 100 0 0 100 timetz_cmp - ));
DESCR("less-equal-greater");
DATA(insert OID = 1359 ( timestamp PGUID 12 f t f t 2 f 1184 "1082 1266" 100 0 0 100 datetimetz_timestamp - ));
DESCR("convert date and time with time zone to timestamp");
DATA(insert OID = 1359 ( timestamptz PGUID 12 f t t t 2 f 1184 "1082 1266" 100 0 0 100 datetimetz_timestamptz - ));
DESCR("convert date and time with time zone to timestamp with time zone");
DATA(insert OID = 1362 ( time PGUID 14 f t t t 1 f 1083 "1083" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 1364 ( time PGUID 14 f t f t 1 f 1083 "702" 100 0 0 100 "select time(timestamp($1))" - ));
DATA(insert OID = 1364 ( time PGUID 14 f t t t 1 f 1083 "702" 100 0 0 100 "select time(timestamp($1))" - ));
DESCR("convert abstime to time");
DATA(insert OID = 1365 ( abstime PGUID 14 f t f t 1 f 702 "702" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 1367 ( reltime PGUID 14 f t t t 1 f 703 "703" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 1368 ( timestamp PGUID 14 f t f t 1 f 1184 "1184" 100 0 0 100 "select $1" - ));
DATA(insert OID = 1368 ( timestamptz PGUID 14 f t t t 1 f 1184 "1184" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 1369 ( interval PGUID 14 f t t t 1 f 1186 "1186" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 1370 ( interval PGUID 12 f t f t 1 f 1186 "1083" 100 0 0 100 time_interval - ));
DATA(insert OID = 1370 ( interval PGUID 12 f t t t 1 f 1186 "1083" 100 0 0 100 time_interval - ));
DESCR("convert time to interval");
DATA(insert OID = 1371 ( date PGUID 14 f t t t 1 f 1082 "1082" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
......@@ -1704,25 +1707,25 @@ DESCR("smaller of two");
DATA(insert OID = 1381 ( char_length PGUID 12 f t t t 1 f 23 "25" 100 0 0 100 textlen - ));
DESCR("length");
DATA(insert OID = 1382 ( date_part PGUID 14 f t f t 2 f 701 "25 702" 100 0 0 100 "select date_part($1, timestamp($2))" - ));
DATA(insert OID = 1382 ( date_part PGUID 14 f t f t 2 f 701 "25 702" 100 0 0 100 "select date_part($1, timestamptz($2))" - ));
DESCR("extract field from abstime");
DATA(insert OID = 1383 ( date_part PGUID 14 f t f t 2 f 701 "25 703" 100 0 0 100 "select date_part($1, interval($2))" - ));
DESCR("extract field from reltime");
DATA(insert OID = 1384 ( date_part PGUID 14 f t f t 2 f 701 "25 1082" 100 0 0 100 "select date_part($1, timestamp($2))" - ));
DATA(insert OID = 1384 ( date_part PGUID 14 f t t t 2 f 701 "25 1082" 100 0 0 100 "select date_part($1, timestamptz($2))" - ));
DESCR("extract field from date");
DATA(insert OID = 1385 ( date_part PGUID 14 f t f t 2 f 701 "25 1083" 100 0 0 100 "select date_part($1, interval($2))" - ));
DATA(insert OID = 1385 ( date_part PGUID 14 f t t t 2 f 701 "25 1083" 100 0 0 100 "select date_part($1, interval($2))" - ));
DESCR("extract field from time");
DATA(insert OID = 1386 ( age PGUID 14 f t f t 1 f 1186 "1184" 100 0 0 100 "select age(\'today\', $1)" - ));
DATA(insert OID = 1386 ( age PGUID 14 f t t t 1 f 1186 "1184" 100 0 0 100 "select age(\'today\', $1)" - ));
DESCR("date difference from today preserving months and years");
DATA(insert OID = 1387 ( timetz PGUID 14 f t f t 1 f 1266 "1266" 100 0 0 100 "select $1" - ));
DATA(insert OID = 1387 ( timetz PGUID 14 f t t t 1 f 1266 "1266" 100 0 0 100 "select $1" - ));
DESCR("noop conversion");
DATA(insert OID = 1388 ( timetz PGUID 12 f t f t 1 f 1266 "1184" 100 0 0 100 timestamp_timetz - ));
DATA(insert OID = 1388 ( timetz PGUID 12 f t t t 1 f 1266 "1184" 100 0 0 100 timestamptz_timetz - ));
DESCR("convert timestamp to timetz");
DATA(insert OID = 1389 ( isfinite PGUID 12 f t f t 1 f 16 "1184" 100 0 0 100 timestamp_finite - ));
DATA(insert OID = 1389 ( isfinite PGUID 12 f t t t 1 f 16 "1184" 100 0 0 100 timestamp_finite - ));
DESCR("boolean test");
DATA(insert OID = 1390 ( isfinite PGUID 12 f t f t 1 f 16 "1186" 100 0 0 100 interval_finite - ));
DATA(insert OID = 1390 ( isfinite PGUID 12 f t t t 1 f 16 "1186" 100 0 0 100 interval_finite - ));
DESCR("boolean test");
......@@ -1787,7 +1790,7 @@ DESCR("bool is not true (ie, false or unknown)");
DATA(insert OID = 1418 ( isnotfalse PGUID 12 f t t f 1 f 16 "16" 100 0 0 100 isnotfalse - ));
DESCR("bool is not false (ie, true or unknown)");
DATA(insert OID = 1419 ( time PGUID 12 f t f t 1 f 1083 "1186" 100 0 0 100 interval_time - ));
DATA(insert OID = 1419 ( time PGUID 12 f t t t 1 f 1083 "1186" 100 0 0 100 interval_time - ));
DESCR("convert interval to time");
DATA(insert OID = 1421 ( box PGUID 12 f t t t 2 f 603 "600 600" 100 0 0 100 points_box - ));
......@@ -2338,6 +2341,9 @@ DESCR("text to cidr");
DATA(insert OID = 1715 ( set_masklen PGUID 12 f t t t 2 f 869 "869 23" 100 0 0 100 inet_set_masklen - ));
DESCR("change the netmask of an inet");
DATA(insert OID = 1690 ( time_mi_time PGUID 12 f t t t 2 f 1186 "1083 1083" 100 0 0 100 time_mi_time - ));
DESCR("minus");
DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - ));
DESCR("less-than-or-equal");
DATA(insert OID = 1692 ( boolge PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolge - ));
......@@ -2464,7 +2470,7 @@ DATA(insert OID = 1783 ( int2 PGUID 12 f t t t 1 f 21 "1700" 100 0 0 100 num
DESCR("(internal)");
/* formatting */
DATA(insert OID = 1770 ( to_char PGUID 12 f t f t 2 f 25 "1184 25" 100 0 0 100 timestamp_to_char - ));
DATA(insert OID = 1770 ( to_char PGUID 12 f t f t 2 f 25 "1184 25" 100 0 0 100 timestamptz_to_char - ));
DESCR("format timestamp to text");
DATA(insert OID = 1772 ( to_char PGUID 12 f t f t 2 f 25 "1700 25" 100 0 0 100 numeric_to_char - ));
DESCR("format numeric to text");
......@@ -2763,6 +2769,87 @@ DESCR("return position of substring");
DATA(insert OID = 2015 ( btrim PGUID 12 f t t t 2 f 17 "17 17" 100 0 0 100 byteatrim - ));
DESCR("trim both ends of string");
DATA(insert OID = 2020 ( date_trunc PGUID 12 f t t t 2 f 1114 "25 1114" 100 0 0 100 timestamp_trunc - ));
DESCR("truncate timestamp to specified units");
DATA(insert OID = 2021 ( date_part PGUID 12 f t t t 2 f 701 "25 1114" 100 0 0 100 timestamp_part - ));
DESCR("extract field from timestamp");
DATA(insert OID = 2022 ( timestamp PGUID 12 f t f t 1 f 1114 "25" 100 0 0 100 text_timestamp - ));
DESCR("convert text to timestamp");
DATA(insert OID = 2023 ( timestamp PGUID 12 f t f t 1 f 1114 "702" 100 0 0 100 abstime_timestamp - ));
DESCR("convert abstime to timestamp");
DATA(insert OID = 2024 ( timestamp PGUID 12 f t t t 1 f 1114 "1082" 100 0 0 100 date_timestamp - ));
DESCR("convert date to timestamp");
DATA(insert OID = 2025 ( timestamp PGUID 12 f t t t 2 f 1114 "1082 1083" 100 0 0 100 datetime_timestamp - ));
DESCR("convert date and time to timestamp");
DATA(insert OID = 2026 ( timestamp PGUID 14 f t t t 1 f 1114 "1114" 100 0 0 100 "select $1" - ));
DESCR("convert (noop)");
DATA(insert OID = 2027 ( timestamp PGUID 12 f t f t 1 f 1114 "1184" 100 0 0 100 timestamptz_timestamp - ));
DESCR("convert date and time with time zone to timestamp");
DATA(insert OID = 2028 ( timestamptz PGUID 12 f t f t 1 f 1184 "1114" 100 0 0 100 timestamp_timestamptz - ));
DESCR("convert date and time with time zone to timestamp");
DATA(insert OID = 2029 ( date PGUID 12 f t t t 1 f 1082 "1114" 100 0 0 100 timestamp_date - ));
DESCR("convert timestamp to date");
DATA(insert OID = 2030 ( abstime PGUID 12 f t f t 1 f 702 "1114" 100 0 0 100 timestamp_abstime - ));
DESCR("convert timestamp to abstime");
DATA(insert OID = 2031 ( timestamp_mi PGUID 12 f t t t 2 f 1186 "1114 1114" 100 0 0 100 timestamp_mi - ));
DESCR("subtract");
DATA(insert OID = 2032 ( timestamp_pl_span PGUID 12 f t t t 2 f 1114 "1114 1186" 100 0 0 100 timestamp_pl_span - ));
DESCR("plus");
DATA(insert OID = 2033 ( timestamp_mi_span PGUID 12 f t t t 2 f 1114 "1114 1186" 100 0 0 100 timestamp_mi_span - ));
DESCR("minus");
DATA(insert OID = 2034 ( text PGUID 12 f t t t 1 f 25 "1114" 100 0 0 100 timestamp_text - ));
DESCR("convert timestamp to text");
DATA(insert OID = 2035 ( timestamp_smaller PGUID 12 f t t t 2 f 1114 "1114 1114" 100 0 0 100 timestamp_smaller - ));
DESCR("smaller of two");
DATA(insert OID = 2036 ( timestamp_larger PGUID 12 f t t t 2 f 1114 "1114 1114" 100 0 0 100 timestamp_larger - ));
DESCR("larger of two");
DATA(insert OID = 2037 ( timetz PGUID 12 f t f t 2 f 1266 "25 1266" 100 0 0 100 timetz_zone - ));
DESCR("time with time zone");
DATA(insert OID = 2038 ( timetz PGUID 12 f t t t 2 f 1266 "1186 1266" 100 0 0 100 timetz_izone - ));
DESCR("time with time zone");
DATA(insert OID = 2041 ( overlaps PGUID 12 f t t f 4 f 16 "1114 1114 1114 1114" 100 0 0 100 overlaps_timestamp - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 2042 ( overlaps PGUID 14 f t t f 4 f 16 "1114 1186 1114 1186" 100 0 0 100 "select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))" - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 2043 ( overlaps PGUID 14 f t t f 4 f 16 "1114 1114 1114 1186" 100 0 0 100 "select ($1, $2) overlaps ($3, ($3 + $4))" - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 2044 ( overlaps PGUID 14 f t t f 4 f 16 "1114 1186 1114 1114" 100 0 0 100 "select ($1, ($1 + $2)) overlaps ($3, $4)" - ));
DESCR("SQL92 interval comparison");
DATA(insert OID = 2045 ( timestamp_cmp PGUID 12 f t t t 2 f 23 "1114 1114" 100 0 0 100 timestamp_cmp - ));
DESCR("less-equal-greater");
DATA(insert OID = 2046 ( time PGUID 12 f t t t 1 f 1083 "1266" 100 0 0 100 timetz_time - ));
DESCR("convert time with time zone to time");
DATA(insert OID = 2047 ( timetz PGUID 12 f t f t 1 f 1266 "1083" 100 0 0 100 time_timetz - ));
DESCR("convert time to timetz");
DATA(insert OID = 2048 ( isfinite PGUID 12 f t t t 1 f 16 "1114" 100 0 0 100 timestamp_finite - ));
DESCR("boolean test");
DATA(insert OID = 2050 ( interval_mi_time PGUID 14 f t t t 2 f 1083 "1186 1083" 100 0 0 100 "select $2 - $1 + (interval \'24 hours\')" - ));
DESCR("minus");
DATA(insert OID = 2051 ( interval_mi_timetz PGUID 14 f t t t 2 f 1266 "1186 1266" 100 0 0 100 "select $2 - $1 + (interval \'24 hours\')" - ));
DESCR("minus");
DATA(insert OID = 2052 ( timestamp_eq PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_eq - ));
DESCR("equal");
DATA(insert OID = 2053 ( timestamp_ne PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_ne - ));
DESCR("not equal");
DATA(insert OID = 2054 ( timestamp_lt PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_lt - ));
DESCR("less-than");
DATA(insert OID = 2055 ( timestamp_le PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_le - ));
DESCR("less-than-or-equal");
DATA(insert OID = 2056 ( timestamp_ge PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_ge - ));
DESCR("greater-than-or-equal");
DATA(insert OID = 2057 ( timestamp_gt PGUID 12 f t t t 2 f 16 "1114 1114" 100 0 0 100 timestamp_gt - ));
DESCR("greater-than");
DATA(insert OID = 2058 ( age PGUID 12 f t t t 2 f 1186 "1114 1114" 100 0 0 100 timestamp_age - ));
DESCR("date difference preserving months and years");
DATA(insert OID = 2059 ( age PGUID 14 f t t t 1 f 1186 "1114" 100 0 0 100 "select age(\'today\', $1)" - ));
DESCR("date difference from today preserving months and years");
DATA(insert OID = 2069 ( timezone PGUID 12 f t t t 2 f 1184 "25 1114" 100 0 0 100 timestamp_zone - ));
DESCR("time zone");
DATA(insert OID = 2070 ( timezone PGUID 12 f t t t 2 f 1184 "1186 1114" 100 0 0 100 timestamp_izone - ));
DESCR("time zone");
/*
* prototypes for functions pg_proc.c
*/
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.111 2001/09/06 02:07:42 tgl Exp $
* $Id: pg_type.h,v 1.112 2001/09/28 08:09:14 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -395,12 +395,16 @@ DESCR("hh:mm:ss, ANSI SQL time");
#define TIMEOID 1083
/* OIDS 1100 - 1199 */
DATA(insert OID = 1114 ( timestamp PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p _null_ ));
DESCR("date and time");
#define TIMESTAMPOID 1114
DATA(insert OID = 1115 ( _timestamp PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x _null_ ));
DATA(insert OID = 1182 ( _date PGUID -1 -1 f b t \054 0 1082 array_in array_out array_in array_out i x _null_ ));
DATA(insert OID = 1183 ( _time PGUID -1 -1 f b t \054 0 1083 array_in array_out array_in array_out d x _null_ ));
DATA(insert OID = 1184 ( timestamp PGUID 8 47 f b t \054 0 0 timestamp_in timestamp_out timestamp_in timestamp_out d p _null_ ));
DESCR("date and time");
#define TIMESTAMPOID 1184
DATA(insert OID = 1185 ( _timestamp PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x _null_ ));
DATA(insert OID = 1184 ( timestamptz PGUID 8 47 f b t \054 0 0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p _null_ ));
DESCR("date and time with time zone");
#define TIMESTAMPTZOID 1184
DATA(insert OID = 1185 ( _timestamptz PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x _null_ ));
DATA(insert OID = 1186 ( interval PGUID 12 47 f b t \054 0 0 interval_in interval_out interval_in interval_out d p _null_ ));
DESCR("@ <number> <units>, time interval");
#define INTERVALOID 1186
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.164 2001/09/14 17:46:40 momjian Exp $
* $Id: builtins.h,v 1.165 2001/09/28 08:09:14 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,7 +16,7 @@
#include "fmgr.h"
#include "nodes/primnodes.h"
#include "storage/itemptr.h" /* for setLastTid() */
/*
* Defined in adt/
......@@ -345,6 +345,7 @@ extern char *deparse_expression(Node *expr, List *dpcontext,
extern List *deparse_context_for(char *relname, Oid relid);
/* tid.c */
extern void setLastTid(const ItemPointer tid);
extern Datum tidin(PG_FUNCTION_ARGS);
extern Datum tidout(PG_FUNCTION_ARGS);
extern Datum tideq(PG_FUNCTION_ARGS);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: date.h,v 1.11 2001/03/22 04:01:11 momjian Exp $
* $Id: date.h,v 1.12 2001/09/28 08:09:14 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -68,6 +68,8 @@ extern Datum date_pli(PG_FUNCTION_ARGS);
extern Datum date_mii(PG_FUNCTION_ARGS);
extern Datum date_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamp_date(PG_FUNCTION_ARGS);
extern Datum date_timestamptz(PG_FUNCTION_ARGS);
extern Datum timestamptz_date(PG_FUNCTION_ARGS);
extern Datum datetime_timestamp(PG_FUNCTION_ARGS);
extern Datum abstime_date(PG_FUNCTION_ARGS);
extern Datum text_date(PG_FUNCTION_ARGS);
......@@ -85,6 +87,7 @@ extern Datum time_cmp(PG_FUNCTION_ARGS);
extern Datum overlaps_time(PG_FUNCTION_ARGS);
extern Datum time_larger(PG_FUNCTION_ARGS);
extern Datum time_smaller(PG_FUNCTION_ARGS);
extern Datum time_mi_time(PG_FUNCTION_ARGS);
extern Datum timestamp_time(PG_FUNCTION_ARGS);
extern Datum time_interval(PG_FUNCTION_ARGS);
extern Datum interval_time(PG_FUNCTION_ARGS);
......@@ -107,10 +110,14 @@ extern Datum timetz_hash(PG_FUNCTION_ARGS);
extern Datum overlaps_timetz(PG_FUNCTION_ARGS);
extern Datum timetz_larger(PG_FUNCTION_ARGS);
extern Datum timetz_smaller(PG_FUNCTION_ARGS);
extern Datum timestamp_timetz(PG_FUNCTION_ARGS);
extern Datum datetimetz_timestamp(PG_FUNCTION_ARGS);
extern Datum timetz_time(PG_FUNCTION_ARGS);
extern Datum time_timetz(PG_FUNCTION_ARGS);
extern Datum timestamptz_timetz(PG_FUNCTION_ARGS);
extern Datum datetimetz_timestamptz(PG_FUNCTION_ARGS);
extern Datum text_timetz(PG_FUNCTION_ARGS);
extern Datum timetz_text(PG_FUNCTION_ARGS);
extern Datum timetz_zone(PG_FUNCTION_ARGS);
extern Datum timetz_izone(PG_FUNCTION_ARGS);
extern Datum timetz_pl_interval(PG_FUNCTION_ARGS);
extern Datum timetz_mi_interval(PG_FUNCTION_ARGS);
......
......@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: datetime.h,v 1.21 2001/08/27 20:02:10 tgl Exp $
* $Id: datetime.h,v 1.22 2001/09/28 08:09:14 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -86,7 +86,7 @@
#define MONTH 1
#define YEAR 2
#define DAY 3
#define TIMES 4 /* not used - thomas 1997-07-14 */
#define JULIAN 4
#define TZ 5
#define DTZ 6
#define DTZMOD 7
......@@ -103,6 +103,8 @@
#define AGO 17
#define ABS_BEFORE 18
#define ABS_AFTER 19
/* reserved for unrecognized string values */
#define UNKNOWN_FIELD 31
/*
* Token field definitions for time parsing and decoding.
......@@ -149,12 +151,17 @@
#define DTK_MILLENNIUM 28
#define DTK_MILLISEC 29
#define DTK_MICROSEC 30
#define DTK_JULIAN 31
#define DTK_DOW 32
#define DTK_DOY 33
#define DTK_TZ_HOUR 34
#define DTK_TZ_MINUTE 35
#define DTK_ISO_DATE 36
#define DTK_ISO_TIME 37
/*
* Bit mask definitions for time parsing.
*/
......@@ -238,6 +245,7 @@ extern int day_tab[2][13];
extern void GetCurrentTime(struct tm * tm);
extern void GetCurrentTimeUsec(struct tm * tm, double *fsec);
extern void j2date(int jd, int *year, int *month, int *day);
extern int date2j(int year, int month, int day);
......
......@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------
* formatting.h
*
* $Id: formatting.h,v 1.8 2001/09/06 03:22:42 momjian Exp $
* $Id: formatting.h,v 1.9 2001/09/28 08:09:14 thomas Exp $
*
*
* Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
......@@ -22,6 +22,7 @@
extern Datum timestamp_to_char(PG_FUNCTION_ARGS);
extern Datum timestamptz_to_char(PG_FUNCTION_ARGS);
extern Datum interval_to_char(PG_FUNCTION_ARGS);
extern Datum to_timestamp(PG_FUNCTION_ARGS);
extern Datum to_date(PG_FUNCTION_ARGS);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: nabstime.h,v 1.30 2001/05/03 19:00:37 tgl Exp $
* $Id: nabstime.h,v 1.31 2001/09/28 08:09:14 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -74,11 +74,8 @@ typedef TimeIntervalData *TimeInterval;
* These were chosen as special 32-bit bit patterns,
* so redefine them explicitly using these bit patterns. - tgl 97/02/24
*/
#define EPOCH_ABSTIME ((AbsoluteTime) 0)
#define INVALID_ABSTIME ((AbsoluteTime) 0x7FFFFFFE) /* 2147483647 (2^31 - 1) */
#define CURRENT_ABSTIME ((AbsoluteTime) 0x7FFFFFFD) /* 2147483646 (2^31 - 2) */
#define NOEND_ABSTIME ((AbsoluteTime) 0x7FFFFFFC) /* 2147483645 (2^31 - 3) */
#define BIG_ABSTIME ((AbsoluteTime) 0x7FFFFFFB) /* 2147483644 (2^31 - 4) */
#define NOSTART_ABSTIME ((AbsoluteTime) INT_MIN) /* -2147483648 */
#define INVALID_RELTIME ((RelativeTime) 0x7FFFFFFE) /* 2147483647 (2^31 - 1) */
......@@ -116,6 +113,8 @@ extern Datum abstime_finite(PG_FUNCTION_ARGS);
extern Datum timestamp_abstime(PG_FUNCTION_ARGS);
extern Datum abstime_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamptz_abstime(PG_FUNCTION_ARGS);
extern Datum abstime_timestamptz(PG_FUNCTION_ARGS);
extern Datum reltimein(PG_FUNCTION_ARGS);
extern Datum reltimeout(PG_FUNCTION_ARGS);
......@@ -158,6 +157,7 @@ extern Datum timeofday(PG_FUNCTION_ARGS);
/* non-fmgr-callable support routines */
extern AbsoluteTime GetCurrentAbsoluteTime(void);
extern AbsoluteTime GetCurrentAbsoluteTimeUsec(int *usec);
extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn);
#endif /* NABSTIME_H */
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: timestamp.h,v 1.17 2001/09/06 03:22:42 momjian Exp $
* $Id: timestamp.h,v 1.18 2001/09/28 08:09:14 thomas Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -33,12 +33,12 @@
typedef double Timestamp;
typedef double TimestampTz;
typedef struct
{
double time; /* all time units other than months and
* years */
int32 month; /* months and years, after time for
* alignment */
double time; /* all time units other than months and years */
int32 month; /* months and years, after time for alignment */
} Interval;
......@@ -49,23 +49,22 @@ typedef struct
* Therefore Timestamp is pass-by-reference if and only if float8 is!
*/
#define DatumGetTimestamp(X) ((Timestamp) DatumGetFloat8(X))
#define DatumGetTimestampTz(X) ((Timestamp) DatumGetFloat8(X))
#define DatumGetIntervalP(X) ((Interval *) DatumGetPointer(X))
#define TimestampGetDatum(X) Float8GetDatum(X)
#define TimestampTzGetDatum(X) Float8GetDatum(X)
#define IntervalPGetDatum(X) PointerGetDatum(X)
#define PG_GETARG_TIMESTAMP(n) DatumGetTimestamp(PG_GETARG_DATUM(n))
#define PG_GETARG_TIMESTAMPTZ(n) DatumGetTimestampTz(PG_GETARG_DATUM(n))
#define PG_GETARG_INTERVAL_P(n) DatumGetIntervalP(PG_GETARG_DATUM(n))
#define PG_RETURN_TIMESTAMP(x) return TimestampGetDatum(x)
#define PG_RETURN_TIMESTAMPTZ(x) return TimestampTzGetDatum(x)
#define PG_RETURN_INTERVAL_P(x) return IntervalPGetDatum(x)
#ifdef NAN
#define DT_INVALID (NAN)
#else
#define DT_INVALID (DBL_MIN+DBL_MIN)
#endif
#ifdef HUGE_VAL
#define DT_NOBEGIN (-HUGE_VAL)
#define DT_NOEND (HUGE_VAL)
......@@ -73,15 +72,6 @@ typedef struct
#define DT_NOBEGIN (-DBL_MAX)
#define DT_NOEND (DBL_MAX)
#endif
#define DT_CURRENT (DBL_MIN)
#define DT_EPOCH (-DBL_MIN)
#define TIMESTAMP_INVALID(j) do {j = DT_INVALID;} while (0)
#ifdef NAN
#define TIMESTAMP_IS_INVALID(j) (isnan(j))
#else
#define TIMESTAMP_IS_INVALID(j) ((j) == DT_INVALID)
#endif
#define TIMESTAMP_NOBEGIN(j) do {j = DT_NOBEGIN;} while (0)
#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
......@@ -89,24 +79,7 @@ typedef struct
#define TIMESTAMP_NOEND(j) do {j = DT_NOEND;} while (0)
#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
#define TIMESTAMP_CURRENT(j) do {j = DT_CURRENT;} while (0)
#define TIMESTAMP_IS_CURRENT(j) ((j) == DT_CURRENT)
#define TIMESTAMP_EPOCH(j) do {j = DT_EPOCH;} while (0)
#define TIMESTAMP_IS_EPOCH(j) ((j) == DT_EPOCH)
#define TIMESTAMP_IS_RELATIVE(j) (TIMESTAMP_IS_CURRENT(j) || TIMESTAMP_IS_EPOCH(j))
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_INVALID(j) \
|| TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
#define TIMESTAMP_IS_RESERVED(j) (TIMESTAMP_IS_RELATIVE(j) || TIMESTAMP_NOT_FINITE(j))
#define INTERVAL_INVALID(j) do {(j).time = DT_INVALID;} while (0)
#ifdef NAN
#define INTERVAL_IS_INVALID(j) (isnan((j).time))
#else
#define INTERVAL_IS_INVALID(j) ((j).time == DT_INVALID)
#endif
#define INTERVAL_NOT_FINITE(j) INTERVAL_IS_INVALID(j)
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
#define TIME_PREC_INV 1000000.0
#define JROUND(j) (rint(((double) (j))*TIME_PREC_INV)/TIME_PREC_INV)
......@@ -153,6 +126,14 @@ extern Datum timestamp_part(PG_FUNCTION_ARGS);
extern Datum interval_part(PG_FUNCTION_ARGS);
extern Datum timestamp_zone(PG_FUNCTION_ARGS);
extern Datum timestamp_izone(PG_FUNCTION_ARGS);
extern Datum timestamp_timestamptz(PG_FUNCTION_ARGS);
extern Datum timestamptz_in(PG_FUNCTION_ARGS);
extern Datum timestamptz_out(PG_FUNCTION_ARGS);
extern Datum timestamptz_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamptz_zone(PG_FUNCTION_ARGS);
extern Datum timestamptz_izone(PG_FUNCTION_ARGS);
extern Datum timestamptz_timestamptz(PG_FUNCTION_ARGS);
extern Datum interval_um(PG_FUNCTION_ARGS);
extern Datum interval_pl(PG_FUNCTION_ARGS);
......@@ -169,6 +150,14 @@ extern Datum timestamp_mi_span(PG_FUNCTION_ARGS);
extern Datum timestamp_age(PG_FUNCTION_ARGS);
extern Datum overlaps_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamptz_text(PG_FUNCTION_ARGS);
extern Datum text_timestamptz(PG_FUNCTION_ARGS);
extern Datum timestamptz_pl_span(PG_FUNCTION_ARGS);
extern Datum timestamptz_mi_span(PG_FUNCTION_ARGS);
extern Datum timestamptz_age(PG_FUNCTION_ARGS);
extern Datum timestamptz_trunc(PG_FUNCTION_ARGS);
extern Datum timestamptz_part(PG_FUNCTION_ARGS);
extern Datum now(PG_FUNCTION_ARGS);
/* Internal routines (not fmgr-callable) */
......@@ -176,11 +165,13 @@ extern Datum now(PG_FUNCTION_ARGS);
extern int tm2timestamp(struct tm * tm, double fsec, int *tzp, Timestamp *dt);
extern int timestamp2tm(Timestamp dt, int *tzp, struct tm * tm,
double *fsec, char **tzn);
extern void dt2time(Timestamp dt, int *hour, int *min, double *sec);
extern int interval2tm(Interval span, struct tm * tm, float8 *fsec);
extern int tm2interval(struct tm * tm, double fsec, Interval *span);
extern Timestamp SetTimestamp(Timestamp timestamp);
extern Timestamp SetEpochTimestamp(void);
extern void GetEpochTime(struct tm * tm);
extern void isoweek2date(int woy, int *year, int *mon, int *mday);
extern int date2isoweek(int year, int mon, int mday);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment