*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.6 1997/03/14 23:19:57 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.7 1997/04/02 18:33:09 scrappy Exp $
*
* NOTES
* This code is actually (almost) unused.
#include "postgres.h"
#include "miscadmin.h"
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
#include "access/xact.h"
#include "utils/builtins.h" /* where function declarations go */
#include "utils/palloc.h"
#include "utils/dt.h"
-#ifndef USE_NEW_TIME_CODE
-#define USE_NEW_TIME_CODE 1
-#endif
-
#define INVALID_RELTIME_STR "Undefined RelTime"
#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
#define RELTIME_LABEL '@'
* PUBLIC ROUTINES *
*****************************************************************************/
+RelativeTime
+timespan_reltime(TimeSpan *timespan)
+{
+ RelativeTime time;
+ double span;
+
+ if (!PointerIsValid(timespan))
+ time = INVALID_RELTIME;
+
+ if (TIMESPAN_IS_INVALID(*timespan)) {
+ time = INVALID_RELTIME;
+
+ } else {
+ span = ((((double) 30*86400)*timespan->month) + timespan->time);
+
+#ifdef DATEDEBUG
+printf( "timespan_reltime- convert m%d s%f to %f [%d %d]\n",
+ timespan->month, timespan->time, span, INT_MIN, INT_MAX);
+#endif
+
+ time = (((span > INT_MIN) && (span < INT_MAX))? span: INVALID_RELTIME);
+ };
+
+ return(time);
+} /* timespan_reltime() */
+
+
+TimeSpan *
+reltime_timespan(RelativeTime reltime)
+{
+ TimeSpan *result;
+
+ if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
+ elog(WARN,"Memory allocation failed, can't convert reltime to timespan",NULL);
+
+ switch(reltime) {
+ case INVALID_RELTIME:
+ TIMESPAN_INVALID(*result);
+ break;
+
+ default:
+ result->time = reltime;
+ result->month = 0;
+ };
+
+ return(result);
+} /* reltime_timespan() */
+
+
/*
* mktinterval - creates a time interval with endpoints t1 and t2
*/
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.1 1997/03/14 23:20:01 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.2 1997/04/02 18:33:22 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdio.h> /* for sprintf() */
#include <string.h>
-#include <postgres.h>
-#include <miscadmin.h>
-#include <utils/builtins.h>
-#include <utils/nabstime.h>
-#include <utils/datetime.h>
+#include "postgres.h"
+#include "miscadmin.h"
+#include "utils/builtins.h"
+#include "utils/nabstime.h"
+#include "utils/datetime.h"
+#include "access/xact.h"
static int day_tab[2][12] = {
{31,28,31,30,31,30,31,31,30,31,30,31},
elog(WARN,"Bad date external representation %s",str);
switch (dtype) {
-#if FALSE
case DTK_DATE:
- date = date2j(tm->tm_year,tm->tm_mon,tm->tm_mday);
- time = time2j(tm->tm_hour,tm->tm_min,(double)tm->tm_sec);
- if (tzp != 0) {
- j2local(&date, &time, -(tzp*60));
- } else {
- j2local(&date, &time, -timezone);
- };
break;
-#endif
+
+ case DTK_CURRENT:
+ GetCurrentTime(tm);
+ break;
case DTK_EPOCH:
tm->tm_year = 1970;
tm->tm_mon = 1;
tm->tm_mday = 1;
- case DTK_DATE:
break;
default:
elog(WARN,"Unrecognized date external representation %s",str);
};
-#if FALSE
- if (tm->tm_year < 70)
- tm->tm_year += 2000;
- else if (tm->tm_year < 100)
- tm->tm_year += 1900;
-#endif
-
if (tm->tm_year < 0 || tm->tm_year > 32767)
elog(WARN, "date_in: year must be limited to values 0 through 32767 in '%s'", str);
if (tm->tm_mon < 1 || tm->tm_mon > 12)
return(date_pli(dateVal, -days));
} /* date_mii() */
+
+/* date_datetime()
+ * Convert date to datetime data type.
+ */
+DateTime *
+date_datetime(int4 dateVal)
+{
+ DateTime *result;
+
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Memory allocation failed, can't convert date to datetime",NULL);
+
+ *result = (dateVal - date2j( 2000, 1, 1));
+ *result *= 86400;
+
+ return(result);
+} /* date_datetime() */
+
+
+/* datetime_date()
+ * Convert datetime to date data type.
+ */
+DateADT
+datetime_date(DateTime *datetime)
+{
+ DateADT result;
+
+ if (!PointerIsValid(datetime))
+ elog(WARN,"Unable to convert null datetime to date",NULL);
+
+ result = (*datetime / 86400);
+
+ return(result);
+} /* datetime_date() */
+
+
+/* abstime_date()
+ * Convert abstime to date data type.
+ */
+DateADT
+abstime_date(AbsoluteTime abstime)
+{
+ DateADT result;
+ struct tt, *tm = &tt;
+
+ switch (abstime) {
+ case INVALID_ABSTIME:
+ case NOSTART_ABSTIME:
+ case NOEND_ABSTIME:
+ elog(WARN,"Unable to convert reserved abstime value to date",NULL);
+ break;
+
+ 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:
+#if FALSE
+ tm = localtime((time_t *) &abstime);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
+ /* XXX must shift to local time before converting - tgl 97/04/01 */
+#endif
+ abstime2tm(abstime, &CTimeZone, tm);
+ result = date2j(tm->tm_year,tm->tm_mon,tm->tm_mday) - date2j(2000,1,1);
+ break;
+ };
+
+ return(result);
+} /* abstime_date() */
+
#else
bool
int32
date_mi(int4 dateVal1, int4 dateVal2)
{
-#if USE_NEW_TIME_CODE
-
DateADT *date1, *date2;
int days;
+
date1 = (DateADT *) &dateVal1;
date2 = (DateADT *) &dateVal2;
days = (date2j(date1->year, date1->month, date1->day)
- date2j(date2->year, date2->month, date2->day));
-#else
-
- DateADT dv1, dv2;
- DateADT *date1, *date2;
- int32 days = 0;
- int i;
-
- /* This circumlocution allows us to assume that date1 is always
- before date2. */
- dv1 = date_smaller (dateVal1, dateVal2);
- dv2 = date_larger (dateVal1, dateVal2);
- date1 = (DateADT *) &dv1;
- date2 = (DateADT *) &dv2;
-
- /* Sum number of days in each full year between date1 and date2. */
- for (i = date1->year + 1; i < date2->year; ++i)
- days += isleap(i) ? 366 : 365;
-
- if (days)
- {
- /* We need to wrap around the year. Add in number of days in each
- full month from date1 to end of year. */
- for (i = date1->month + 1; i <= 12; ++i)
- days += day_tab[isleap(date1->year)][i - 1];
-
- /* Add in number of days in each full month from start of year to
- date2. */
- for (i = 1; i < date2->month; ++i)
- days += day_tab[isleap(date2->year)][i - 1];
- }
- else
- {
- /* Add in number of days in each full month from date1 to date2. */
- for (i = date1->month + 1; i < date2->month; ++i)
- days += day_tab[isleap(date1->year)][i - 1];
- }
-
- if (days || date1->month != date2->month)
- {
- /* Add in number of days left in month for date1. */
- days += day_tab[isleap(date1->year)][date1->month - 1] - date1->day;
-
- /* Add in day of month of date2. */
- days += date2->day;
- }
- else
- {
- /* Everything's in the same month, so just subtract the days! */
- days = date2->day - date1->day;
- }
-
-#endif
-
return (days);
}
int4
date_pli(int4 dateVal, int32 days)
{
-#if USE_NEW_TIME_CODE
-
DateADT *date1 = (DateADT *) &dateVal;
int date, year, month, day;
date1->month = month;
date1->day = day;
-#else
-
- DateADT *date1 = (DateADT *) &dateVal;
- /* Use separate day variable because date1->day is a narrow type. */
- int32 day = date1->day + days;
-
- if (days > 0) {
- /* Loop as long as day has wrapped around end of month. */
- while (day > day_tab[isleap(date1->year)][date1->month - 1]) {
- day -= day_tab[isleap(date1->year)][date1->month - 1];
- if (++date1->month > 12) {
- /* Month wrapped around. */
- date1->month = 1;
- ++date1->year;
- }
- }
-
- } else {
- /* Loop as long as day has wrapped around beginning of month. */
- while (day < 1) {
- /* Decrement month first, because a negative day number
- should be held as relative to the previous month's end. */
- if (--date1->month < 1) {
- /* Month wrapped around. */
- date1->month = 12;
- --date1->year;
- }
-
- day += day_tab[isleap(date1->year)][date1->month - 1];
- }
- }
- date1->day = day;
-
-#endif
-
return (dateVal);
} /* date_pli() */
return (date_pli(dateVal, -days));
}
+DateTime *
+date_datetime(int4 dateVal)
+{
+ DateTime *result;
+ DateADT *date = (DateADT *) &dateVal;
+
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Memory allocation failed, can't convert date to datetime",NULL);
+
+ *result = (date2j(date->year, date->month, date->day) - date2j( 2000, 1, 1));
+ *result *= 86400;
+
+#ifdef DATEDEBUG
+printf( "date_datetime- convert %04d-%02d-%02d to %f\n",
+ date->year, date->month, date->day, *result);
+#endif
+
+ return(result);
+} /* date_datetime() */
+
+int4
+datetime_date(DateTime *datetime)
+{
+ int4 result;
+ int year, month, day;
+ DateADT *date = (DateADT *) &result;
+
+ if (!PointerIsValid(datetime))
+ elog(WARN,"Unable to convert null datetime to date",NULL);
+
+ j2date( ((*datetime / 86400) + date2j( 2000, 1, 1)), &year, &month, &day);
+ date->year = year;
+ date->month = month;
+ date->day = day;
+
+ return(result);
+} /* datetime_date() */
+
+int4
+abstime_date(AbsoluteTime abstime)
+{
+ int4 result;
+ DateADT *date = (DateADT *) &result;
+ struct tm tt, *tm = &tt;
+
+ switch (abstime) {
+ case INVALID_ABSTIME:
+ case NOSTART_ABSTIME:
+ case NOEND_ABSTIME:
+ elog(WARN,"Unable to convert reserved abstime value to date",NULL);
+ break;
+
+ case EPOCH_ABSTIME:
+ date->year = 1970;
+ date->month = 1;
+ date->day = 1;
+ break;
+
+ case CURRENT_ABSTIME:
+#if FALSE
+ GetCurrentTime(tm);
+#endif
+ abstime = GetCurrentTransactionStartTime() + CTimeZone;
+ date->year = tm->tm_year;
+ date->month = tm->tm_mon;
+ date->day = tm->tm_mday;
+ break;
+
+ default:
+#if FALSE
+ tm = localtime((time_t *) &abstime);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
+#endif
+ abstime2tm(abstime, &CTimeZone, tm);
+ date->year = tm->tm_year;
+ date->month = tm->tm_mon;
+ date->day = tm->tm_mday;
+ break;
+ };
+
+ return(result);
+} /* abstime_date() */
+
#endif
+
/*****************************************************************************
* Time ADT
*****************************************************************************/
return NULL;
if (time->sec == 0.0) {
- sprintf(buf, "%02d:%02d",
- (int)time->hr, (int)time->min);
+ sprintf(buf, "%02d:%02d", (int)time->hr, (int)time->min);
} else {
if (((int) time->sec) == time->sec) {
sprintf(buf, "%02d:%02d:%02d",
- (int)time->hr, (int)time->min, (int)time->sec);
+ (int)time->hr, (int)time->min, (int)time->sec);
} else {
sprintf(buf, "%02d:%02d:%09.6f",
- (int)time->hr, (int)time->min, time->sec);
+ (int)time->hr, (int)time->min, time->sec);
};
};
return((*time1 < *time2)? -1: (((*time1 < *time2)? 1: 0)));
} /* time_cmp() */
+
+/* datetime_datetime()
+ * Convert date and time to datetime data type.
+ */
+DateTime *
+datetime_datetime(DateADT date, TimeADT *time)
+{
+ DateTime *result;
+
+ if (!PointerIsValid(time)) {
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Memory allocation failed, can't convert to datetime",NULL);
+
+ DATETIME_INVALID(*result);
+
+ } else {
+ result = date_datetime(date);
+ *result += *time;
+ };
+
+ return(result);
+} /* datetime_datetime() */
+
#else
bool
return 0;
}
+DateTime *
+datetime_datetime(int4 dateVal, TimeADT *time)
+{
+ DateTime *result;
+#ifdef DATEDEBUG
+ DateADT *date = (DateADT *) &dateVal;
+#endif
+
+ if (!PointerIsValid(time)) {
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Memory allocation failed, can't convert to datetime",NULL);
+
+ DATETIME_INVALID(*result);
+
+ } else {
+
+#ifdef DATEDEBUG
+printf( "datetime_datetime- convert %04d-%02d-%02d %02d:%02d:%05.2f\n",
+ date->year, date->month, date->day, time->hr, time->min, time->sec);
+#endif
+
+ result = date_datetime(dateVal);
+ *result += (((time->hr*60)+time->min)*60+time->sec);
+ };
+
+ return(result);
+} /* datetime_datetime() */
+
#endif
int32 /* RelativeTime */
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.13 1997/03/28 07:16:59 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.14 1997/04/02 18:33:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <errno.h>
#include "postgres.h"
-#include <miscadmin.h>
+#include "miscadmin.h"
#ifdef HAVE_FLOAT_H
# include <float.h>
#endif
#define USE_DATE_CACHE 1
+#define isleap(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
+
+int mdays[] = {31, 28, 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};
double fsec;
struct tm tt, *tm = &tt;
- int tzp;
+ int tz;
int dtype;
int nf;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN];
+ char lowstr[MAXDATELEN+1];
if (!PointerIsValid(str))
- elog(WARN, "Bad (null) datetime external representation", NULL);
+ elog(WARN,"Bad (null) datetime external representation",NULL);
if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
+ || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
elog(WARN,"Bad datetime external representation %s",str);
if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN, "Memory allocation failed, can't input datetime '%s'",str);
+ elog(WARN,"Memory allocation failed, can't input datetime '%s'",str);
switch (dtype) {
case DTK_DATE:
- *result = tm2datetime( tm, fsec, tzp);
+ *result = tm2datetime( tm, fsec, &tz);
#ifdef DATEDEBUG
printf( "datetime_in- date is %f\n", *result);
break;
default:
- elog(WARN, "Internal coding error, can't input datetime '%s'",str);
+ elog(WARN,"Internal coding error, can't input datetime '%s'",str);
};
return(result);
char *result;
struct tm tt, *tm = &tt;
double fsec;
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
if (!PointerIsValid(dt))
return(NULL);
if (DATETIME_IS_RESERVED(*dt)) {
EncodeSpecialDateTime(*dt, buf);
- } else if (datetime2tm( *dt, tm, &fsec) == 0) {
+ } else if (datetime2tm( *dt, &CTimeZone, tm, &fsec) == 0) {
EncodeDateTime(tm, fsec, DateStyle, buf);
} else {
};
if (!PointerIsValid(result = PALLOC(strlen(buf)+1)))
- elog(WARN, "Memory allocation failed, can't output datetime", NULL);
+ elog(WARN,"Memory allocation failed, can't output datetime",NULL);
strcpy( result, buf);
int nf;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN];
+ char lowstr[MAXDATELEN+1];
tm->tm_year = 0;
tm->tm_mon = 0;
fsec = 0;
if (!PointerIsValid(str))
- elog(WARN, "Bad (null) timespan external representation", NULL);
+ elog(WARN,"Bad (null) timespan external representation",NULL);
if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|| (DecodeDateDelta( field, ftype, nf, &dtype, tm, &fsec) != 0))
elog(WARN,"Bad timespan external representation %s",str);
if (!PointerIsValid(span = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't input timespan '%s'",str);
+ elog(WARN,"Memory allocation failed, can't input timespan '%s'",str);
switch (dtype) {
case DTK_DELTA:
break;
default:
- elog(WARN, "Internal coding error, can't input timespan '%s'",str);
+ elog(WARN,"Internal coding error, can't input timespan '%s'",str);
};
return(span);
struct tm tt, *tm = &tt;
double fsec;
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
if (!PointerIsValid(span))
return(NULL);
*****************************************************************************/
+bool
+datetime_finite(DateTime *datetime)
+{
+ if (!PointerIsValid(datetime))
+ return FALSE;
+
+ return(! DATETIME_NOT_FINITE(*datetime));
+} /* datetime_finite() */
+
+
+bool
+timespan_finite(TimeSpan *timespan)
+{
+ if (!PointerIsValid(timespan))
+ return FALSE;
+
+ return(! TIMESPAN_NOT_FINITE(*timespan));
+} /* timespan_finite() */
+
+
/*----------------------------------------------------------
* Relational operators for datetime.
*---------------------------------------------------------*/
if (DATETIME_IS_CURRENT(dt)) {
GetCurrentTime(&tt);
- dt = tm2datetime( &tt, 0, 0);
+ dt = tm2datetime( &tt, 0, NULL);
#ifdef DATEDEBUG
printf( "SetDateTime- current time is %f\n", dt);
#endif
} else { /* if (DATETIME_IS_EPOCH(dt1)) */
GetEpochTime(&tt);
- dt = tm2datetime( &tt, 0, 0);
+ dt = tm2datetime( &tt, 0, NULL);
#ifdef DATEDEBUG
printf( "SetDateTime- epoch time is %f\n", dt);
#endif
dt2 = *datetime2;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract dates",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract dates",NULL);
if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
} /* datetime_sub() */
+/* datetime_add_span()
+ * Add a timespan to a datetime data type.
+ * Note that timespan 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.
+ */
DateTime *datetime_add_span(DateTime *datetime, TimeSpan *span)
{
DateTime *result;
+#if FALSE
double date, time;
int year, mon, mday;
+#endif
if ((!PointerIsValid(datetime)) || (!PointerIsValid(span)))
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN, "Memory allocation failed, can't add dates",NULL);
+ elog(WARN,"Memory allocation failed, can't add dates",NULL);
#ifdef DATEDEBUG
-printf( "date_add- add %f to %d %f\n", *datetime, span->month, span->time);
-#endif
-
- *result = *datetime;
- if (DATETIME_IS_RELATIVE(*result)) *result = SetDateTime(*result);
-
- if (span->month != 0) {
- time = JROUND(modf( (*result/86400), &date)*86400);
- date += date2j(2000,1,1);
-
- j2date( ((int) date), &year, &mon, &mday);
- mon += span->month;
- if (mon > 12) {
- year += mon / 12;
- mon %= 12;
- } else if (mon < 0) {
- year += mon / 12;
- mon %= 12;
- year -= 1;
- mon += 12;
+printf( "datetime_add_span- add %f to %d %f\n", *datetime, span->month, span->time);
+#endif
+
+ if (DATETIME_NOT_FINITE(*datetime)) {
+ *result = *datetime;
+
+ } else if (TIMESPAN_IS_INVALID(*span)) {
+ DATETIME_INVALID(*result);
+
+ } else {
+ *result = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
+
+ if (span->month != 0) {
+ struct tm tt, *tm = &tt;
+ double fsec;
+
+ if (datetime2tm( *result, NULL, tm, &fsec) == 0) {
+#ifdef DATEDEBUG
+printf( "datetime_add_span- date was %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+#endif
+ tm->tm_mon += span->month;
+ if (tm->tm_mon > 12) {
+ tm->tm_year += (tm->tm_mon / 12);
+ tm->tm_mon = (tm->tm_mon % 12);
+ } 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 > mdays[ tm->tm_mon-1]) {
+ if ((tm->tm_mon == 2) && isleap( tm->tm_year)) {
+ tm->tm_mday = (mdays[ tm->tm_mon-1]+1);
+ } else {
+ tm->tm_mday = mdays[ tm->tm_mon-1];
+ };
+ };
+
+#ifdef DATEDEBUG
+printf( "datetime_add_span- date becomes %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+#endif
+ *result = tm2datetime( tm, fsec, NULL);
+
+ } else {
+ DATETIME_INVALID(*result);
+ };
};
- *result += ((date2j( year, mon, mday)-date2j(2000,1,1))*86400);
- *result += time;
- };
- *result = JROUND(*result + span->time);
+#if FALSE
+ *result = JROUND(*result + span->time);
+#endif
+ *result += span->time;
+ };
return(result);
} /* datetime_add_span() */
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract dates",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract dates",NULL);
result->time = -(timespan->time);
result->month = -(timespan->month);
return(result);
-} /* datetime_sub() */
+} /* timespan_um() */
TimeSpan *timespan_add(TimeSpan *span1, TimeSpan *span2)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't add timespans",NULL);
+ elog(WARN,"Memory allocation failed, can't add timespans",NULL);
result->month = (span1->month + span2->month);
result->time = JROUND(span1->time + span2->time);
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract timespans",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract timespans",NULL);
result->month = (span1->month - span2->month);
result->time = JROUND(span1->time - span2->time);
*---------------------------------------------------------*/
+/* datetime_text()
+ * Convert datetime to text data type.
+ */
+text *
+datetime_text(DateTime *datetime)
+{
+ text *result;
+ char *str;
+ int len;
+
+ if (!PointerIsValid(datetime))
+ return NULL;
+
+ str = datetime_out(datetime);
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ len = (strlen(str)+VARHDRSZ);
+
+ if (!PointerIsValid(result = PALLOC(len)))
+ elog(WARN,"Memory allocation failed, can't convert datetime to text",NULL);
+
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len-VARHDRSZ));
+
+ PFREE(str);
+
+ return(result);
+} /* datetime_text() */
+
+
+/* text_datetime()
+ * Convert text string to datetime.
+ * Text type is not null terminated, so use temporary string
+ * then call the standard input routine.
+ */
+DateTime *
+text_datetime(text *str)
+{
+ DateTime *result;
+ int i;
+ char *sp, *dp, dstr[MAXDATELEN+1];
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
+ *dp = '\0';
+
+ result = datetime_in(dstr);
+
+ return(result);
+} /* text_datetime() */
+
+
+/* timespan_text()
+ * Convert timespan to text data type.
+ */
+text *
+timespan_text(TimeSpan *timespan)
+{
+ text *result;
+ char *str;
+ int len;
+
+ if (!PointerIsValid(timespan))
+ return NULL;
+
+ str = timespan_out(timespan);
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ len = (strlen(str)+VARHDRSZ);
+
+ if (!PointerIsValid(result = PALLOC(len)))
+ elog(WARN,"Memory allocation failed, can't convert timespan to text",NULL);
+
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len-VARHDRSZ));
+
+ PFREE(str);
+
+ return(result);
+} /* timespan_text() */
+
+
+/* text_timespan()
+ * Convert text string to timespan.
+ * Text type may not be null terminated, so copy to temporary string
+ * then call the standard input routine.
+ */
+TimeSpan *
+text_timespan(text *str)
+{
+ TimeSpan *result;
+ int i;
+ char *sp, *dp, dstr[MAXDATELEN+1];
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
+ *dp = '\0';
+
+ result = timespan_in(dstr);
+
+ return(result);
+} /* text_timespan() */
+
+
+/* datetime_part()
+ * Extract specified field from datetime.
+ */
float64
datetime_part(text *units, DateTime *datetime)
{
DateTime dt;
int type, val;
int i;
- char *up, *lp, lowunits[MAXDATELEN];
+ char *up, *lp, lowunits[MAXDATELEN+1];
double fsec;
struct tm tt, *tm = &tt;
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(float64data)))
- elog(WARN, "Memory allocation failed, can't get date part",NULL);
+ elog(WARN,"Memory allocation failed, can't get date part",NULL);
up = VARDATA(units);
lp = lowunits;
dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
- if (datetime2tm( dt, tm, &fsec) == 0) {
+ if (datetime2tm( dt, &CTimeZone, tm, &fsec) == 0) {
switch (val) {
case DTK_TZ:
*result = CTimeZone;
} /* datetime_part() */
+/* timespan_part()
+ * Extract specified field from timespan.
+ */
float64
timespan_part(text *units, TimeSpan *timespan)
{
int type, val;
int i;
- char *up, *lp, lowunits[MAXDATELEN];
+ char *up, *lp, lowunits[MAXDATELEN+1];
double fsec;
struct tm tt, *tm = &tt;
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(float64data)))
- elog(WARN, "Memory allocation failed, can't get date part",NULL);
+ elog(WARN,"Memory allocation failed, can't get date part",NULL);
up = VARDATA(units);
lp = lowunits;
* PRIVATE ROUTINES *
*****************************************************************************/
-#if USE_NEW_TIME_CODE
-#define DATE_MAXLEN 47
-#endif
-
/* definitions for squeezing values into "value" */
#define ABS_SIGNBIT 0200
#define VALMASK 0177
* Also, month is one-based, _not_ zero-based.
*/
int
-datetime2tm( DateTime dt, struct tm *tm, double *fsec)
+datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec)
{
double date, time, sec;
- time = (modf( dt2local( dt, CTimeZone)/86400, &date)*86400);
+ if (tzp != NULL) dt = dt2local( dt, *tzp);
+ time = (modf( dt/86400, &date)*86400);
date += date2j(2000,1,1);
if (time < 0) {
time += 86400;
if (date < 0) return -1;
#ifdef DATEDEBUG
-printf( "datetime2tm- date is %f (%f %f)\n", dt, date, time);
+printf( "datetime2tm- date is %f (%f %f)\n",
+ ((tzp != NULL)? dt2local(dt, -(*tzp)): dt), date, time);
#endif
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
tm->tm_isdst = -1;
#ifdef DATEDEBUG
-printf( "datetime2tm- timezone is %s; offset is %d; daylight is %d\n",
- CTZName, CTimeZone, CDayLight);
+printf( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
+ CTZName, ((tzp != NULL)? *tzp: 0), CTimeZone, CDayLight);
#endif
return 0;
* Also, month is one-based, _not_ zero-based.
*/
DateTime
-tm2datetime( struct tm *tm, double fsec, int tzp) {
+tm2datetime( struct tm *tm, double fsec, int *tzp) {
DateTime result;
double date, time;
printf( "tm2datetime- date is %f (%f %f %d)\n", result, date, time, (((tm->tm_hour*60)+tm->tm_min)*60+tm->tm_sec));
printf( "tm2datetime- time is %f %02d:%02d:%02d %f\n", time, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#endif
- if (tzp != 0) result = dt2local(result, -tzp);
+ if (tzp != NULL) result = dt2local(result, -(*tzp));
return(result);
} /* tm2datetime() */
*tmask = 0;
+ /* look first for text fields, since that will be unambiguous month */
for (i = 0; i < nf; i++) {
- str = field[i];
- len = strlen(str);
-
- if (len <= 0)
- return -1;
-
- if (isdigit(*str)) {
- if (DecodeNumber( len, str, fmask, &dmask, tm, &fsec) != 0)
- return -1;
-
- } else if (isalpha(*str)) {
+ if (isalpha(*field[i])) {
type = DecodeSpecial( i, field[i], &val);
if (type == IGNORE) continue;
dmask = DTK_M(type);
switch (type) {
- case YEAR:
-#ifdef DATEDEBUG
-printf( "DecodeDate- year field %s value is %d\n", field[i], val);
-#endif
- tm->tm_mon = val;
- break;
-
case MONTH:
#ifdef DATEDEBUG
printf( "DecodeDate- month field %s value is %d\n", field[i], val);
-#endif
- tm->tm_mon = val;
- break;
-
- case DAY:
-#ifdef DATEDEBUG
-printf( "DecodeDate- month field %s value is %d\n", field[i], val);
#endif
tm->tm_mon = val;
break;
#endif
return -1;
};
+ if (fmask & dmask) return -1;
+
+ fmask |= dmask;
+ *tmask |= dmask;
+
+ /* mark this field as being completed */
+ field[i] = NULL;
};
+ };
+
+ /* now pick up remaining numeric fields */
+ for (i = 0; i < nf; i++) {
+ if (field[i] == NULL) continue;
+
+ if ((len = strlen(field[i])) <= 0)
+ return -1;
+
+ if (DecodeNumber( len, field[i], fmask, &dmask, tm, &fsec) != 0)
+ return -1;
if (fmask & dmask) return -1;
printf( "DecodeNumber- match %d (%s) as year\n", val, str);
#endif
*tmask = DTK_M(YEAR);
+
+ /* already have a year? then see if we can substitute... */
+ if (fmask & DTK_M(YEAR)) {
+ if ((!(fmask & DTK_M(DAY)))
+ && ((tm->tm_year >= 1) && (tm->tm_year <= 31))) {
+#ifdef DATEDEBUG
+printf( "DecodeNumber- misidentified year previously; swap with day %d\n", tm->tm_mday);
+#endif
+ tm->tm_mday = tm->tm_year;
+ *tmask = DTK_M(DAY);
+ };
+ };
+
tm->tm_year = val;
/* special case day of year? */
&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
/* already have year? then could be month */
- } else if ((fmask && DTK_M(YEAR)) && (! (fmask & DTK_M(MONTH)))
+ } else if ((fmask & DTK_M(YEAR)) && (! (fmask & DTK_M(MONTH)))
&& ((val >= 1) && (val <= 12))) {
#ifdef DATEDEBUG
printf( "DecodeNumber- match %d (%s) as month\n", val, str);
tm->tm_mon = val;
/* no year and EuroDates enabled? then could be day */
-#if USE_EURODATES
} else if ((EuroDates || (fmask & DTK_M(MONTH)))
-#else
- } else if ((fmask & DTK_M(MONTH))
-#endif
&& (! ((fmask & DTK_M(YEAR)) && (fmask & DTK_M(DAY))))
&& ((val >= 1) && (val <= 31))) {
#ifdef DATEDEBUG
*tmask = DTK_M(MONTH);
tm->tm_mon = val;
+ } else if ((! (fmask & DTK_M(DAY)))
+ && ((val >= 1) && (val <= 31))) {
+#ifdef DATEDEBUG
+printf( "DecodeNumber- (2) match %d (%s) as day\n", val, str);
+#endif
+ *tmask = DTK_M(DAY);
+ tm->tm_mday = val;
+
} else if (! (fmask & DTK_M(YEAR))) {
#ifdef DATEDEBUG
printf( "DecodeNumber- (2) match %d (%s) as year\n", val, str);
int day, hour, min;
double sec;
#ifdef DATEDEBUG
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
#endif
sec = (tm->tm_sec + fsec);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.21 1997/03/28 07:12:53 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.22 1997/04/02 18:33:50 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef USE_POSIX_TIME
#include <sys/timeb.h>
#endif
+#include "utils/builtins.h"
#include "access/xact.h"
void
GetCurrentTime(struct tm *tm)
{
- time_t now;
+ abstime2tm( GetCurrentTransactionStartTime(), &CTimeZone, tm);
+
+ return;
+} /* GetCurrentTime() */
+
+
+void
+abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm)
+{
struct tm *tt;
- now = GetCurrentTransactionStartTime()-CTimeZone;
- tt = gmtime( &now);
+ if (tzp != NULL) time -= *tzp;
+ tt = gmtime((time_t *) &time);
tm->tm_year = tt->tm_year+1900;
tm->tm_mon = tt->tm_mon+1;
tm->tm_isdst = tt->tm_isdst;
return;
-} /* GetCurrentTime() */
+} /* abstime2tm() */
-AbsoluteTime tm2abstime( struct tm *tm, int tz);
-
+/* tm2abstime()
+ * Convert a tm structure to abstime.
+ * Note that tm has full year (not 1900-based) and 1-based month.
+ */
AbsoluteTime
tm2abstime( struct tm *tm, int tz)
{
|| tm->tm_hour < 0 || tm->tm_hour >= 24
|| tm->tm_min < 0 || tm->tm_min > 59
|| tm->tm_sec < 0 || tm->tm_sec > 59)
- return INVALID_ABSTIME;
+ return(INVALID_ABSTIME);
day = (date2j( tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j( 1970, 1, 1));
/* check for time out of range */
if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM))
- return INVALID_ABSTIME;
+ return(INVALID_ABSTIME);
/* convert to seconds */
sec = tm->tm_sec + tz + (tm->tm_min +(day*24 + tm->tm_hour)*60)*60;
/* check for overflow */
if ((day == MAX_DAYNUM && sec < 0) ||
(day == MIN_DAYNUM && sec > 0))
- return INVALID_ABSTIME;
+ return(INVALID_ABSTIME);
/* daylight correction */
if (tm->tm_isdst < 0) { /* unknown; find out */
/* check for reserved values (e.g. "current" on edge of usual range */
if (!AbsoluteTimeIsReal(sec))
- return INVALID_ABSTIME;
+ return(INVALID_ABSTIME);
return sec;
} /* tm2abstime() */
}
+/* abstime_finite()
+ */
+bool
+abstime_finite(AbsoluteTime abstime)
+{
+ return((abstime != INVALID_ABSTIME)
+ && (abstime != NOSTART_ABSTIME) && (abstime != NOEND_ABSTIME));
+} /* abstime_datetime() */
+
+
/*
* abstimeeq - returns 1, iff arguments are equal
* abstimene - returns 1, iff arguments are not equal
abstimeeq(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
abstimene(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
abstimelt(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
abstimegt(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
abstimele(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
abstimege(AbsoluteTime t1, AbsoluteTime t2)
{
if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
- return 0;
+ return(FALSE);
if (t1 == CURRENT_ABSTIME)
t1 = GetCurrentTransactionStartTime();
if (t2 == CURRENT_ABSTIME)
return(t1 >= t2);
}
+
/* datetime_abstime()
* Convert datetime to abstime.
*/
} else {
if (DATETIME_IS_RELATIVE(*datetime)) {
- datetime2tm( SetDateTime(*datetime), tm, &fsec);
+ datetime2tm( SetDateTime(*datetime), &CTimeZone, tm, &fsec);
result = tm2abstime( tm, 0);
- } else if (datetime2tm( *datetime, tm, &fsec) == 0) {
+ } else if (datetime2tm( *datetime, &CTimeZone, tm, &fsec) == 0) {
result = tm2abstime( tm, 0);
} else {
return(result);
} /* datetime_abstime() */
+
+/* abstime_datetime()
+ * Convert datetime to abstime.
+ */
+DateTime *
+abstime_datetime(AbsoluteTime abstime)
+{
+ DateTime *result;
+
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Unable to allocate space to convert abstime to datetime",NULL);
+
+ switch (abstime) {
+ case INVALID_ABSTIME:
+ DATETIME_INVALID(*result);
+ break;
+
+ case NOSTART_ABSTIME:
+ DATETIME_NOBEGIN(*result);
+ break;
+
+ case NOEND_ABSTIME:
+ DATETIME_NOEND(*result);
+ break;
+
+ case EPOCH_ABSTIME:
+ DATETIME_EPOCH(*result);
+ break;
+
+ case CURRENT_ABSTIME:
+ DATETIME_CURRENT(*result);
+ break;
+
+ default:
+ *result = abstime + ((date2j( 1970, 1, 1) - date2j( 2000, 1, 1))*86400);
+ };
+
+ return(result);
+} /* abstime_datetime() */
{
return difftime(t1, t2) <= 0;
}
+
+DateTime *
+timestamp_datetime(time_t timestamp)
+{
+ DateTime *result;
+
+ double fsec = 0;
+ struct tm *tm;
+
+ if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
+ elog(WARN,"Memory allocation failed, can't convert timestamp to datetime",NULL);
+
+ tm = localtime((time_t *) ×tamp);
+ tm->tm_year += 1900;
+ tm->tm_mon += 1;
+
+ *result = tm2datetime(tm, fsec, NULL);
+
+ return(result);
+} /* timestamp_datetime() */
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_aggregate.h,v 1.3 1996/11/14 21:39:07 scrappy Exp $
+ * $Id: pg_aggregate.h,v 1.4 1997/04/02 18:36:09 scrappy Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
* ---------------
*/
-DATA(insert OID = 0 ( avg PGUID int4pl int4inc int4div 23 23 23 23 0 0 ));
-DATA(insert OID = 0 ( avg PGUID int2pl int2inc int2div 21 21 21 21 0 0 ));
-DATA(insert OID = 0 ( avg PGUID float4pl float4inc float4div 700 700 700 700 0.0 0.0 ));
-DATA(insert OID = 0 ( avg PGUID float8pl float8inc float8div 701 701 701 701 0.0 0.0 ));
-
-DATA(insert OID = 0 ( sum PGUID int4pl - - 23 23 0 23 0 _null_ ));
-DATA(insert OID = 0 ( sum PGUID int2pl - - 21 21 0 21 0 _null_ ));
-DATA(insert OID = 0 ( sum PGUID float4pl - - 700 700 0 700 0.0 _null_ ));
-DATA(insert OID = 0 ( sum PGUID float8pl - - 701 701 0 701 0.0 _null_ ));
-
-DATA(insert OID = 0 ( max PGUID int4larger - - 23 23 0 23 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID int2larger - - 21 21 0 21 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID float4larger - - 700 700 0 700 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID float8larger - - 701 701 0 701 _null_ _null_ ));
-DATA(insert OID = 0 ( max PGUID date_larger - - 1082 1082 0 1082 _null_ _null_ ));
-
-DATA(insert OID = 0 ( min PGUID int4smaller - - 23 23 0 23 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID int2smaller - - 21 21 0 21 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID float4smaller - - 700 700 0 700 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID float8smaller - - 701 701 0 701 _null_ _null_ ));
-DATA(insert OID = 0 ( min PGUID date_smaller - - 1082 1082 0 1082 _null_ _null_ ));
-
-DATA(insert OID = 0 ( count PGUID - int4inc - 0 0 23 23 _null_ 0 ));
+DATA(insert OID = 0 ( avg PGUID int4pl int4inc int4div 23 23 23 23 0 0 ));
+DATA(insert OID = 0 ( avg PGUID int2pl int2inc int2div 21 21 21 21 0 0 ));
+DATA(insert OID = 0 ( avg PGUID float4pl float4inc float4div 700 700 700 700 0.0 0.0 ));
+DATA(insert OID = 0 ( avg PGUID float8pl float8inc float8div 701 701 701 701 0.0 0.0 ));
+
+DATA(insert OID = 0 ( sum PGUID int4pl - - 23 23 0 23 0 _null_ ));
+DATA(insert OID = 0 ( sum PGUID int2pl - - 21 21 0 21 0 _null_ ));
+DATA(insert OID = 0 ( sum PGUID float4pl - - 700 700 0 700 0.0 _null_ ));
+DATA(insert OID = 0 ( sum PGUID float8pl - - 701 701 0 701 0.0 _null_ ));
+
+DATA(insert OID = 0 ( max PGUID int4larger - - 23 23 0 23 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID int2larger - - 21 21 0 21 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float4larger - - 700 700 0 700 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float8larger - - 701 701 0 701 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID int4larger - - 702 702 0 702 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID date_larger - - 1082 1082 0 1082 _null_ _null_ ));
+DATA(insert OID = 0 ( max PGUID float8larger - - 1084 1084 0 1084 _null_ _null_ ));
+
+DATA(insert OID = 0 ( min PGUID int4smaller - - 23 23 0 23 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID int2smaller - - 21 21 0 21 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float4smaller - - 700 700 0 700 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float8smaller - - 701 701 0 701 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID int4smaller - - 702 702 0 702 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID date_smaller - - 1082 1082 0 1082 _null_ _null_ ));
+DATA(insert OID = 0 ( min PGUID float8smaller - - 1084 1084 0 1084 _null_ _null_ ));
+
+DATA(insert OID = 0 ( count PGUID - int4inc - 0 0 23 23 _null_ 0 ));
/*
* prototypes for fucnctions in pg_aggregate.c
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_operator.h,v 1.6 1997/03/25 08:10:37 scrappy Exp $
+ * $Id: pg_operator.h,v 1.7 1997/04/02 18:36:12 scrappy Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
DATA(insert OID = 1327 ( "+" PGUID 0 b t f 1184 1186 1184 1327 0 0 0 datetime_add_span - - ));
DATA(insert OID = 1328 ( "-" PGUID 0 b t f 1184 1184 1186 0 0 0 0 datetime_sub - - ));
+DATA(insert OID = 1329 ( "-" PGUID 0 b t f 1184 1186 1184 0 0 0 0 datetime_sub_span - - ));
/* timespan operators */
DATA(insert OID = 1330 ( "=" PGUID 0 b t f 1186 1186 16 1330 1331 1332 1332 timespan_eq eqsel eqjoinsel ));
DATA(insert OID = 1334 ( ">" PGUID 0 b t f 1186 1186 16 1333 1333 0 0 timespan_gt intltsel intltjoinsel ));
DATA(insert OID = 1335 ( ">=" PGUID 0 b t f 1186 1186 16 1332 1332 0 0 timespan_ge intltsel intltjoinsel ));
-DATA(insert OID = 1336 ( "-" PGUID 0 b t f 0 1186 1186 0 0 0 0 timespan_um 0 0 ));
+DATA(insert OID = 1336 ( "-" PGUID 0 l t f 0 1186 1186 0 0 0 0 timespan_um 0 0 ));
DATA(insert OID = 1337 ( "+" PGUID 0 b t f 1186 1186 1186 1337 0 0 0 timespan_add - - ));
DATA(insert OID = 1338 ( "-" PGUID 0 b t f 1186 1186 1186 0 0 0 0 timespan_sub - - ));
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.15 1997/04/02 03:29:37 vadim Exp $
+ * $Id: pg_proc.h,v 1.16 1997/04/02 18:36:24 scrappy Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
DATA(insert OID = 272 ( intervalstart PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
DATA(insert OID = 273 ( intervalend PGUID 11 f t f 1 f 702 "704" 100 0 0 100 foo bar ));
DATA(insert OID = 274 ( timeofday PGUID 11 f t f 0 f 25 "0" 100 0 0 100 foo bar ));
+DATA(insert OID = 275 ( abstime_finite PGUID 11 f t f 1 f 16 "702" 100 0 0 100 foo bar ));
DATA(insert OID = 276 ( int2fac PGUID 11 f t f 1 f 21 "21" 100 0 0 100 foo bar ));
DATA(insert OID = 279 ( float48mul PGUID 11 f t f 2 f 701 "700 701" 100 0 0 100 foo bar ));
DATA(insert OID = 1155 ( datetime_le PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
DATA(insert OID = 1156 ( datetime_ge PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
DATA(insert OID = 1157 ( datetime_gt PGUID 11 f t f 2 f 16 "1184 1184" 100 0 0 100 foo bar ));
-/* reserve OIDs 1158-1159 for additional date/time conversion routines! tgl 97/03/19 */
+DATA(insert OID = 1158 ( datetime_finite PGUID 11 f t f 1 f 16 "1184" 100 0 0 100 foo bar ));
+/* reserve OIDs 1158 for additional date/time conversion routines! tgl 97/03/19 */
+
DATA(insert OID = 1160 ( timespan_in PGUID 11 f t f 1 f 1186 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1161 ( timespan_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1162 ( timespan_eq PGUID 11 f t f 2 f 16 "1186 1186" 100 0 0 100 foo bar ));
DATA(insert OID = 1170 ( timespan_sub PGUID 11 f t f 2 f 1186 "1186 1186" 100 0 0 100 foo bar ));
DATA(insert OID = 1171 ( datetime_part PGUID 11 f t f 2 f 701 "25 1184" 100 0 0 100 foo bar ));
DATA(insert OID = 1172 ( timespan_part PGUID 11 f t f 2 f 701 "25 1186" 100 0 0 100 foo bar ));
-/* reserve OIDs 1173-1180 for additional date/time conversion routines! tgl 97/03/19 */
-DATA(insert OID = 1188 ( datetime_sub PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
-DATA(insert OID = 1189 ( datetime_add_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
-DATA(insert OID = 1190 ( datetime_sub_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
-/* reserve OIDs 1191-1199 for additional date/time conversion routines! tgl 97/03/19 */
+
+DATA(insert OID = 1173 ( abstime_datetime PGUID 11 f t f 1 f 1184 "702" 100 0 0 100 foo bar ));
+DATA(insert OID = 1174 ( date_datetime PGUID 11 f t f 1 f 1184 "1082" 100 0 0 100 foo bar ));
+DATA(insert OID = 1175 ( timestamp_datetime PGUID 11 f t f 1 f 1184 "1296" 100 0 0 100 foo bar ));
+DATA(insert OID = 1176 ( datetime_datetime PGUID 11 f t f 2 f 1184 "1082 1083" 100 0 0 100 foo bar ));
+DATA(insert OID = 1177 ( reltime_timespan PGUID 11 f t f 1 f 1186 "703" 100 0 0 100 foo bar ));
+DATA(insert OID = 1178 ( datetime_date PGUID 11 f t f 1 f 1082 "1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1179 ( abstime_date PGUID 11 f t f 1 f 1082 "702" 100 0 0 100 foo bar ));
+DATA(insert OID = 1180 ( datetime_abstime PGUID 11 f t f 1 f 702 "1184" 100 0 0 100 foo bar ));
+
+DATA(insert OID = 1188 ( datetime_sub PGUID 11 f t f 2 f 1186 "1184 1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1189 ( datetime_add_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1190 ( datetime_sub_span PGUID 11 f t f 2 f 1184 "1184 1186" 100 0 0 100 foo bar ));
+DATA(insert OID = 1191 ( text_datetime PGUID 11 f t f 1 f 1184 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1192 ( datetime_text PGUID 11 f t f 1 f 25 "1184" 100 0 0 100 foo bar ));
+DATA(insert OID = 1193 ( timespan_text PGUID 11 f t f 1 f 1186 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1194 ( timespan_reltime PGUID 11 f t f 1 f 703 "1186" 100 0 0 100 foo bar ));
+/* reserve OIDs 1195-1199 for additional date/time conversion routines! tgl 97/03/19 */
DATA(insert OID = 1200 ( int42reltime PGUID 11 f t f 1 f 703 "21" 100 0 0 100 foo bar ));
DATA(insert OID = 1239 ( texticregexne PGUID 11 f t f 2 f 16 "25 25" 100 0 1 0 foo bar ));
DATA(insert OID = 1240 ( nameicregexeq PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
DATA(insert OID = 1241 ( nameicregexne PGUID 11 f t f 2 f 16 "19 25" 100 0 0 100 foo bar ));
+
DATA(insert OID = 1297 ( timestamp_in PGUID 11 f t f 1 f 1296 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1298 ( timestamp_out PGUID 11 f t f 1 f 23 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1299 ( now PGUID 11 f t f 0 f 1296 "0" 100 0 0 100 foo bar ));
DATA(insert OID = 1309 ( timestampgt PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
DATA(insert OID = 1310 ( timestample PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
DATA(insert OID = 1311 ( timestampge PGUID 11 f t f 2 f 16 "1296 1296" 100 0 0 100 foo bar ));
-
+/* reserve OIDs 1312-1319 for additional date/time conversion routines! tgl 97/04/01 */
+
+DATA(insert OID = 1340 ( text PGUID 14 f t f 1 f 25 "1184" 100 0 0 100 "select datetime_text($1)" - ));
+DATA(insert OID = 1341 ( text PGUID 14 f t f 1 f 25 "1186" 100 0 0 100 "select timespan_text($1)" - ));
+/* reserve OIDs 1339-1349 for additional date/time conversion routines! tgl 97/04/01 */
+
+DATA(insert OID = 1350 ( datetime PGUID 14 f t f 1 f 1184 "1184" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1351 ( datetime PGUID 14 f t f 1 f 1184 "25" 100 0 0 100 "select text_datetime($1)" - ));
+DATA(insert OID = 1352 ( datetime PGUID 14 f t f 1 f 1184 "702" 100 0 0 100 "select abstime_datetime($1)" - ));
+DATA(insert OID = 1353 ( datetime PGUID 14 f t f 1 f 1184 "1082" 100 0 0 100 "select date_datetime($1)" - ));
+DATA(insert OID = 1354 ( datetime PGUID 14 f t f 1 f 1184 "1296" 100 0 0 100 "select timestamp_datetime($1)" - ));
+DATA(insert OID = 1355 ( datetime PGUID 14 f t f 2 f 1184 "1082 1083" 100 0 0 100 "select datetime_datetime($1, $2)" - ));
+DATA(insert OID = 1356 ( timespan PGUID 14 f t f 1 f 1186 "1186" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1357 ( timespan PGUID 14 f t f 1 f 1186 "703" 100 0 0 100 "select reltime_timespan($1)" - ));
+DATA(insert OID = 1358 ( timespan PGUID 14 f t f 1 f 1186 "1083" 100 0 0 100 "select time_timespan($1)" - ));
+DATA(insert OID = 1359 ( date PGUID 14 f t f 1 f 1082 "1082" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1360 ( date PGUID 14 f t f 1 f 1082 "1184" 100 0 0 100 "select datetime_date($1)" - ));
+DATA(insert OID = 1361 ( date PGUID 14 f t f 1 f 1082 "702" 100 0 0 100 "select abstime_date($1)" - ));
+DATA(insert OID = 1362 ( time PGUID 14 f t f 1 f 1083 "1083" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1363 ( time PGUID 14 f t f 1 f 1083 "1184" 100 0 0 100 "select datetime_time($1)" - ));
+DATA(insert OID = 1364 ( time PGUID 14 f t f 1 f 1083 "702" 100 0 0 100 "select abstime_time($1)" - ));
+DATA(insert OID = 1365 ( abstime PGUID 14 f t f 1 f 702 "702" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1366 ( abstime PGUID 14 f t f 1 f 702 "1184" 100 0 0 100 "select datetime_abstime($1)" - ));
+DATA(insert OID = 1367 ( reltime PGUID 14 f t f 1 f 703 "703" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1368 ( reltime PGUID 14 f t f 1 f 703 "1186" 100 0 0 100 "select timespan_reltime($1)" - ));
+DATA(insert OID = 1369 ( timestamp PGUID 14 f t f 1 f 1296 "1296" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1370 ( timestamp PGUID 14 f t f 1 f 1296 "1184" 100 0 0 100 "select datetime_timestamp($1)" - ));
+
+DATA(insert OID = 1380 ( date_part PGUID 14 f t f 2 f 701 "25 1184" 100 0 0 100 "select datetime_part($1, $2)" - ));
+DATA(insert OID = 1381 ( date_part PGUID 14 f t f 2 f 701 "25 1186" 100 0 0 100 "select timespan_part($1, $2)" - ));
+DATA(insert OID = 1382 ( date_part PGUID 14 f t f 2 f 701 "25 702" 100 0 0 100 "select datetime_part($1, datetime($2))" - ));
+DATA(insert OID = 1383 ( date_part PGUID 14 f t f 2 f 701 "25 703" 100 0 0 100 "select timespan_part($1, timespan($2))" - ));
+DATA(insert OID = 1384 ( date_part PGUID 14 f t f 2 f 701 "25 1082" 100 0 0 100 "select datetime_part($1, datetime($2))" - ));
+DATA(insert OID = 1385 ( date_part PGUID 14 f t f 2 f 701 "25 1083" 100 0 0 100 "select timespan_part($1, timespan($2))" - ));
+
+DATA(insert OID = 1390 ( isfinite PGUID 14 f t f 1 f 16 "1184" 100 0 0 100 "select datetime_finite($1)" - ));
+DATA(insert OID = 1391 ( isfinite PGUID 14 f t f 1 f 16 "1186" 100 0 0 100 "select timespan_finite($1)" - ));
+DATA(insert OID = 1392 ( isfinite PGUID 14 f t f 1 f 16 "702" 100 0 0 100 "select abstime_finite($1)" - ));
+/* reserve OIDs 1370-1399 for additional date/time conversion routines! tgl 97/04/01 */
+
+DATA(insert OID = 1400 ( float PGUID 14 f t f 1 f 701 "701" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1401 ( float PGUID 14 f t f 1 f 701 "700" 100 0 0 100 "select ftod($1)" - ));
+DATA(insert OID = 1402 ( float4 PGUID 14 f t f 1 f 700 "700" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1403 ( float4 PGUID 14 f t f 1 f 700 "701" 100 0 0 100 "select dtof($1)" - ));
+DATA(insert OID = 1404 ( int PGUID 14 f t f 1 f 23 "23" 100 0 0 100 "select $1" - ));
+DATA(insert OID = 1405 ( int2 PGUID 14 f t f 1 f 21 "21" 100 0 0 100 "select $1" - ));
+
+/* reserve OIDs 1370-1399 for additional date/time conversion routines! tgl 97/04/01 */
/* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
-DATA(insert OID = 870 ( lower PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 871 ( upper PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 872 ( initcap PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 873 ( lpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 874 ( rpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 875 ( ltrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 876 ( rtrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
-DATA(insert OID = 877 ( substr PGUID 11 f t f 3 f 25 "25 23 23" 100 0 0 100 foo bar ));
-DATA(insert OID = 878 ( translate PGUID 11 f t f 3 f 25 "25 18 18" 100 0 0 100 foo bar ));
-DATA(insert OID = 879 ( lpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select lpad($1, $2, \' \')" - ));
-DATA(insert OID = 880 ( rpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select rpad($1, $2, \' \')" - ));
-DATA(insert OID = 881 ( ltrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select ltrim($1, \' \')" - ));
-DATA(insert OID = 882 ( rtrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select rtrim($1, \' \')" - ));
-DATA(insert OID = 883 ( substr PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select substr($1, $2, 10000)" - ));
+DATA(insert OID = 870 ( lower PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 871 ( upper PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 872 ( initcap PGUID 11 f t f 1 f 25 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 873 ( lpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 874 ( rpad PGUID 11 f t f 3 f 25 "25 23 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 875 ( ltrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 876 ( rtrim PGUID 11 f t f 2 f 25 "25 25" 100 0 0 100 foo bar ));
+DATA(insert OID = 877 ( substr PGUID 11 f t f 3 f 25 "25 23 23" 100 0 0 100 foo bar ));
+DATA(insert OID = 878 ( translate PGUID 11 f t f 3 f 25 "25 18 18" 100 0 0 100 foo bar ));
+DATA(insert OID = 879 ( lpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select lpad($1, $2, \' \')" - ));
+DATA(insert OID = 880 ( rpad PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select rpad($1, $2, \' \')" - ));
+DATA(insert OID = 881 ( ltrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select ltrim($1, \' \')" - ));
+DATA(insert OID = 882 ( rtrim PGUID 14 f t f 1 f 25 "25" 100 0 0 100 "select rtrim($1, \' \')" - ));
+DATA(insert OID = 883 ( substr PGUID 14 f t f 2 f 25 "25 23" 100 0 0 100 "select substr($1, $2, 10000)" - ));
/* SEQUENCEs nextval & currval functions */
-DATA(insert OID = 1317 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
-DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1317 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
+DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
#define SeqNextValueRegProcedure 1317
#define SeqCurrValueRegProcedure 1319
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.13 1997/03/25 09:25:33 scrappy Exp $
+ * $Id: builtins.h,v 1.14 1997/04/02 18:31:52 scrappy Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
extern char *reltimeout(int32 timevalue);
extern TimeInterval tintervalin(char *intervalstr);
extern char *tintervalout(TimeInterval interval);
+extern RelativeTime timespan_reltime(TimeSpan *timespan);
+extern TimeSpan *reltime_timespan(RelativeTime reltime);
extern TimeInterval mktinterval(AbsoluteTime t1, AbsoluteTime t2);
extern AbsoluteTime timepl(AbsoluteTime t1, RelativeTime t2);
extern AbsoluteTime timemi(AbsoluteTime t1, RelativeTime t2);
bool timestampgt(time_t t1, time_t t2);
bool timestample(time_t t1, time_t t2);
bool timestampge(time_t t1, time_t t2);
+DateTime *timestamp_datetime(time_t timestamp);
/* varchar.c */
extern char *bpcharin(char *s, int dummy, int typlen);
extern int32 date_mi(DateADT dateVal1, DateADT dateVal2);
extern DateADT date_pli(DateADT dateVal, int32 days);
extern DateADT date_mii(DateADT dateVal, int32 days);
+extern DateTime *date_datetime(DateADT date);
+extern DateADT datetime_date(DateTime *datetime);
+extern DateTime *datetime_datetime(DateADT date, TimeADT *time);
+extern DateADT abstime_date(AbsoluteTime abstime);
#else
extern int32 date_mi(int4 dateVal1, int4 dateVal2);
extern int4 date_pli(int4 dateVal, int32 days);
extern int4 date_mii(int4 dateVal, int32 days);
+extern DateTime *date_datetime(int4 date);
+extern int4 datetime_date(DateTime *datetime);
+extern DateTime *datetime_datetime(int4 date, TimeADT *time);
+extern int4 abstime_date(AbsoluteTime abstime);
#endif
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dt.h,v 1.4 1997/03/28 07:13:21 scrappy Exp $
+ * $Id: dt.h,v 1.5 1997/04/02 18:32:20 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
} TimeSpan;
-#define USE_NEW_TIME_CODE 1
+/*
+ * USE_NEW_DATE enables a more efficient Julian day-based date type.
+ * USE_NEW_TIME enables a more efficient double-based time type.
+ * These have been tested in v6.1beta, but only by myself.
+ * These should be enabled for Postgres v7.0 - tgl 97/04/02
+ */
#define USE_NEW_DATE 0
#define USE_NEW_TIME 0
+
/* ----------------------------------------------------------------
* time types + support macros
*
|| DATETIME_IS_NOBEGIN(j) || DATETIME_IS_NOEND(j))
#define DATETIME_IS_RESERVED(j) (DATETIME_IS_RELATIVE(j) || DATETIME_NOT_FINITE(j))
-#define TIMESPAN_INVALID(j) {j->time = DT_INVALID;}
+#define TIMESPAN_INVALID(j) {(j).time = DT_INVALID;}
#ifdef NAN
#define TIMESPAN_IS_INVALID(j) (isnan((j).time))
#else
#define TIMESPAN_IS_INVALID(j) ((j).time == DT_INVALID)
#endif
+#define TIMESPAN_NOT_FINITE(j) TIMESPAN_IS_INVALID(j)
#define TIME_PREC 1e-6
#define JROUND(j) (rint(((double) j)/TIME_PREC)*TIME_PREC)
extern bool datetime_le(DateTime *dt1, DateTime *dt2);
extern bool datetime_ge(DateTime *dt1, DateTime *dt2);
extern bool datetime_gt(DateTime *dt1, DateTime *dt2);
+extern bool datetime_finite(DateTime *datetime);
extern TimeSpan *timespan_in(char *str);
extern char *timespan_out(TimeSpan *span);
extern bool timespan_le(TimeSpan *span1, TimeSpan *span2);
extern bool timespan_ge(TimeSpan *span1, TimeSpan *span2);
extern bool timespan_gt(TimeSpan *span1, TimeSpan *span2);
+extern bool timespan_finite(TimeSpan *span);
-float64 datetime_part(text *units, DateTime *datetime);
-float64 timespan_part(text *units, TimeSpan *timespan);
+extern text *datetime_text(DateTime *datetime);
+extern DateTime *text_datetime(text *str);
+extern text *timespan_text(TimeSpan *timespan);
+extern TimeSpan *text_timespan(text *str);
+extern float64 datetime_part(text *units, DateTime *datetime);
+extern float64 timespan_part(text *units, TimeSpan *timespan);
extern TimeSpan *timespan_um(TimeSpan *span);
extern TimeSpan *timespan_add(TimeSpan *span1, TimeSpan *span2);
extern DateTime *datetime_sub_span(DateTime *dt, TimeSpan *span);
extern void GetCurrentTime(struct tm *tm);
-DateTime SetDateTime(DateTime datetime);
-DateTime tm2datetime(struct tm *tm, double fsec, int tzp);
-int datetime2tm( DateTime dt, struct tm *tm, double *fsec);
+extern DateTime SetDateTime(DateTime datetime);
+extern DateTime tm2datetime(struct tm *tm, double fsec, int *tzp);
+extern int datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec);
-int timespan2tm(TimeSpan span, struct tm *tm, float8 *fsec);
-int tm2timespan(struct tm *tm, double fsec, TimeSpan *span);
+extern int timespan2tm(TimeSpan span, struct tm *tm, float8 *fsec);
+extern int tm2timespan(struct tm *tm, double fsec, TimeSpan *span);
extern DateTime dt2local( DateTime dt, int timezone);
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nabstime.h,v 1.6 1997/03/25 08:11:24 scrappy Exp $
+ * $Id: nabstime.h,v 1.7 1997/04/02 18:32:39 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#define RelativeTimeIsValid(time) \
((bool) (((RelativeTime) time) != INVALID_RELTIME))
-#if USE_NEW_TIME_CODE
-
extern AbsoluteTime GetCurrentAbsoluteTime(void);
-#else
-
-#define GetCurrentAbsoluteTime() \
- ((AbsoluteTime) getSystemTime())
-
-#endif
-
/*
* getSystemTime --
* Returns system time.
extern bool abstimegt(AbsoluteTime t1, AbsoluteTime t2);
extern bool abstimele(AbsoluteTime t1, AbsoluteTime t2);
extern bool abstimege(AbsoluteTime t1, AbsoluteTime t2);
+extern bool abstime_finite(AbsoluteTime time);
extern AbsoluteTime datetime_abstime(DateTime *datetime);
+extern DateTime *abstime_datetime(AbsoluteTime abstime);
extern bool AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2);
extern bool AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2);
+
+extern AbsoluteTime tm2abstime(struct tm *tm, int tz);
+extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm *tm);
+
extern AbsoluteTime dateconv(struct tm *tm, int zone);
extern time_t qmktime(struct tm *tp);
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/src/man/Attic/built-in.3,v 1.3 1996/12/11 00:27:02 momjian Exp $
-.TH BUILT-INS INTRO 11/05/95 PostgreSQL PostgreSQL
+.\" $Header: /cvsroot/pgsql/src/man/Attic/built-in.3,v 1.4 1997/04/02 18:31:22 scrappy Exp $
+.TH BUILT-INS INTRO 04/01/97 PostgreSQL PostgreSQL
.SH "DESCRIPTION"
This section describes the data types, functions and operators
available to users in Postgres as it is distributed.
-.SH "Built-in and System Types"
.SH "BUILT-IN TYPES"
-This section describes both
+This section describes
.BR built-in
data types.
-These Built-in types are
-are installed in every database.
+These Built-in types are installed in every database.
.PP
Users may add new types to Postgres using the
.IR "define type"
.in 0
.nf
\fBPOSTGRES Type\fP \fBMeaning\fP
- abstime absolute date and time
+ abstime (absolute) limited-range date and time
aclitem access control list item
- bool boolean
+ bool boolean
box 2-dimensional rectangle
bpchar blank-padded characters
bytea variable length array of bytes
char16 array of 16 characters
cid command identifier type
date ANSI SQL date type
+ datetime general-use date and time
filename large object filename
int alias for int4
integer alias for int4
int2 two-byte signed integer
- int28 array of 8 int2
+ int28 array of 8 int2
int4 four-byte signed integer
float alias for float4
float4 single-precision floating-point number
name a multi-character type for storing system identifiers
oid object identifier type
oid8 array of 8 oid
- oidchar16 oid and char16 composed
+ oidchar16 oid and char16 composed
oidint2 oid and int2 composed
oidint4 oid and int4 composed
path variable-length array of lseg
polygon 2-dimensional polygon
real alias for float4
regproc registered procedure
- reltime relative date and time
- smgr storage manager
+ reltime (relative) date and time span (duration)
+ smgr storage manager
smallint alias for int2
text variable length array of characters
tid tuple identifier type
- time ANSI SQL time type
- tinterval time interval
+ time ANSI SQL time type
+ timespan general-use time span (duration)
+ timestamp limited-range ISO-format date and time
+ tinterval time interval (start and stop abstime)
varchar variable-length characters
xid transaction identifier type
.PP
As a rule, the built-in types are all either (1) internal types, in
which case the user should not worry about their external format, or
-(2) have obvious formats. The exceptions to this rule are the three
+(2) have obvious formats. The exceptions to this rule are the date and
time types.
+
.SH "Syntax of date and time types"
+.SH "DATETIME"
+General-use date and time is input using a wide range of
+syntaxes, including ISO-compatible, SQL-compatible, traditional
+Postgres (see section on
+.IR "absolute time")
+and other permutations of date and time. Output styles can be ISO-compatible,
+SQL-compatible, or traditional Postgres, with the default set to be compatible
+with Postgres v6.0.
+.PP
+datetime is specified using the following syntax:
+.PP
+.nf
+Year-Month-Day [ Hour : Minute : Second ] [AD,BC] [ Timezone ]
+.nf
+ YearMonthDay [ Hour : Minute : Second ] [AD,BC] [ Timezone ]
+.nf
+ Month Day [ Hour : Minute : Second ] Year [AD,BC] [ Timezone ]
+.sp
+where
+ Year is 4013 BC, ..., very large
+ Month is Jan, Feb, ..., Dec or 1, 2, ..., 12
+ Day is 1, 2, ..., 31
+ Hour is 00, 02, ..., 23
+ Minute is 00, 01, ..., 59
+ Second is 00, 01, ..., 59 (60 for leap second)
+ Timezone is 3 characters or ISO offset to GMT
+.fi
+.PP
+Valid dates are from Nov 13 00:00:00 4013 BC GMT to far into the future.
+Timezones are either three characters (e.g. "GMT" or "PST") or ISO-compatible
+offsets to GMT (e.g. "-08" or "-08:00" when in Pacific Standard Time).
+Dates are stored internally in Greenwich Mean Time. Input and output routines
+translate time to the local time zone of the server.
+.PP
+All special values allowed for
+.IR "absolute time"
+are also allowed for
+.IR "datetime".
+The special values \*(lqcurrent\*(rq,
+\*(lqinfinity\*(rq and \*(lq-infinity\*(rq are provided.
+\*(lqinfinity\*(rq specifies a time later than any valid time, and
+\*(lq-infinity\*(rq specifies a time earlier than any valid time.
+\*(lqcurrent\*(rq indicates that the current time should be
+substituted whenever this value appears in a computation.
+.PP
+The strings \*(lqnow\*(rq and \*(lqepoch\*(rq can be used to specify
+time values. \*(lqnow\*(rq means the current time, and differs from
+\*(lqcurrent\*(rq in that the current time is immediately substituted
+for it. \*(lqepoch\*(rq means Jan 1 00:00:00 1970 GMT.
+
+
+.SH "TIMESPAN"
+General-use time span is input using a wide range of
+syntaxes, including ISO-compatible, SQL-compatible, traditional
+Postgres (see section on
+.IR "relative time"
+) and other permutations of time span. Output formats can be ISO-compatible,
+SQL-compatible, or traditional Postgres, with the default set to be Postgres-compatible.
+Months and years are a "qualitative" time interval, and are stored separately
+from the other "quantitative" time intervals such as day or hour. For date arithmetic,
+the qualitative time units are instantiated in the context of the relevant date or time.
+.PP
+Time span is specified with the following syntax:
+.PP
+.nf
+ Quantity Unit [Quantity Unit...] [Direction]
+.nf
+@ Quantity Unit [Direction]
+.sp
+where
+ Quantity is ..., '-1', '0', `1', `2', ...
+ Unit is `second', `minute', `hour', `day', `week', `month', `year',
+ or abbreviations or plurals of these units.
+ Direction is ``ago''
+.fi
.SH "ABSOLUTE TIME"
+Absolute time (abstime) is a limited-range (+/- 68 years) and limited-precision (1 sec)
+date data type.
+.IR "datetime"
+may be preferred, since it
+covers a larger range with greater precision.
+.PP
Absolute time is specified using the following syntax:
+.PP
.nf
Month Day [ Hour : Minute : Second ] Year [ Timezone ]
.sp
Second is 00, 01, ..., 59
Year is 1901, 1902, ..., 2038
.fi
+.PP
Valid dates are from Dec 13 20:45:53 1901 GMT to Jan 19 03:14:04
2038 GMT. As of Version 3.0, times are no longer read and written
using Greenwich Mean Time; the input and output routines default to
time values. \*(lqnow\*(rq means the current time, and differs from
\*(lqcurrent\*(rq in that the current time is immediately substituted
for it. \*(lqepoch\*(rq means Jan 1 00:00:00 1970 GMT.
+
.SH "RELATIVE TIME"
+Relative time (reltime) is a limited-range (+/- 68 years) and limited-precision (1 sec)
+time span data type.
+.IR "timespan"
+may be preferred, since it
+covers a larger range with greater precision, allows multiple units
+for an entry, and correctly handles qualitative time
+units such as year and month. For reltime, only one quantity and unit is allowed
+per entry, which can be inconvenient for complicated time spans.
+.PP
Relative time is specified with the following syntax:
+.PP
.nf
@ Quantity Unit [Direction]
.sp
provided.
.SH "TIME RANGES"
Time ranges are specified as:
+.PP
.nf
[ 'abstime' 'abstime']
.fi
.IR abstime
is a time in the absolute time format. Special abstime values such as
\*(lqcurrent\*(rq, \*(lqinfinity\*(rq and \*(lq-infinity\*(rq can be used.
+
.SH "Built-in operators and functions"
.SH OPERATORS
Postgres provides a large number of built-in operators on system types.
The rest of this section provides a list of the built-in operators and
the functions that implement them. Binary operators are listed first,
followed by unary operators.
-.SH "BINARY OPERATORS"
-This list was generated from the Postgres system catalogs with the
-query:
-.nf
-SELECT
- t0.typname AS result,
- t1.typname AS left_type,
- t2.typname AS right_type,
- o.oprname AS operatr,
- p.proname AS func_name
-FROM pg_proc p, pg_type t0,
- pg_type t1, pg_type t2,
- pg_operator o
-WHERE p.prorettype = t0.oid AND
- RegprocToOid(o.oprcode) = p.oid AND
- p.pronargs = 2 AND
- o.oprleft = t1.oid AND
- o.oprright = t2.oid
-ORDER BY result, left_type, right_type, operatr;
-.fi
-
-These operations are cast in terms of SQL types and so are
-.BR not
-directly usable as C function prototypes.
+.SH "BINARY OPERATORS"
.nf
Operators:
<?> abstime in tinterval
| start of interval
<#> convert to interval
+.fi
+
+.SH "FUNCTIONS"
+Many data types have functions available for conversion to other related types.
+In addition, there are some type-specific functions.
+
+.nf
+Functions:
+
+abstime
+ datetime datetime(abstime) convert to datetime
+ bool isfinite(abstime) TRUE if this is a finite time
+
+date
+ datetime datetime(date) convert to datetime
+ datetime datetime(date,time) convert to datetime
+
+datetime
+ abstime abstime(datetime) convert to abstime
+ float8 date_part(text,datetime) specified portion of date field
+ bool isfinite(datetime) TRUE if this is a finite time
+
+reltime
+ timespan timespan(reltime) convert to timespan
+
+time
+ datetime datetime(date,time) convert to datetime
+
+timespan
+ float8 date_part(text,timespan) specified portion of time field
+ bool isfinite(timespan) TRUE if this is a finite time
+ reltime reltime(timespan) convert to reltime
+.fi
+
+.PP
+This list was generated from the Postgres system catalogs with the
+query:
+
+.nf
+SELECT
+ t0.typname AS result,
+ t1.typname AS left_type,
+ t2.typname AS right_type,
+ o.oprname AS operatr,
+ p.proname AS func_name
+FROM
+ pg_proc p, pg_type t0,
+ pg_type t1, pg_type t2,
+ pg_operator o
+WHERE
+ p.prorettype = t0.oid AND
+ RegprocToOid(o.oprcode) = p.oid AND
+ p.pronargs = 2 AND
+ o.oprleft = t1.oid AND
+ o.oprright = t2.oid
+ORDER BY
+ result, left_type, right_type, operatr;
+.fi
+
+These operations are cast in terms of SQL types and so are
+.BR not
+directly usable as C function prototypes.
result |left_type |right_type|operatr|func_name
---------+----------+----------+-------+---------------