diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 8d2587ce38..3f6d192424 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -9,7 +9,7 @@ * * * 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. @@ -32,15 +32,14 @@ #include "postgres.h" #include "miscadmin.h" +#ifdef HAVE_LIMITS_H +# include +#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 '@' @@ -235,6 +234,55 @@ char *tintervalout(TimeInterval interval) * 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 */ diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index e5569281d0..43207b2a87 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -7,18 +7,19 @@ * * * 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 /* for sprintf() */ #include -#include -#include -#include -#include -#include +#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}, @@ -72,36 +73,23 @@ printf( "date_in- input string is %s\n", str); 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) @@ -256,6 +244,82 @@ date_mii(DateADT dateVal, int4 days) 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 @@ -392,69 +456,15 @@ date_smaller(int4 dateVal1, int4 dateVal2) 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); } @@ -463,8 +473,6 @@ date_mi(int4 dateVal1, int4 dateVal2) int4 date_pli(int4 dateVal, int32 days) { -#if USE_NEW_TIME_CODE - DateADT *date1 = (DateADT *) &dateVal; int date, year, month, day; @@ -474,41 +482,6 @@ date_pli(int4 dateVal, int32 days) 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() */ @@ -519,8 +492,93 @@ date_mii(int4 dateVal, int32 days) 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 *****************************************************************************/ @@ -583,15 +641,14 @@ time_out(TimeADT *time) 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); }; }; @@ -666,6 +723,29 @@ time_cmp(TimeADT *time1, TimeADT *time2) 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 @@ -734,6 +814,34 @@ time_cmp(TimeADT *time1, TimeADT *time2) 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 */ diff --git a/src/backend/utils/adt/dt.c b/src/backend/utils/adt/dt.c index f56eb68a5f..28f31a1472 100644 --- a/src/backend/utils/adt/dt.c +++ b/src/backend/utils/adt/dt.c @@ -7,7 +7,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,7 @@ #include #include "postgres.h" -#include +#include "miscadmin.h" #ifdef HAVE_FLOAT_H # include #endif @@ -34,6 +34,10 @@ #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}; @@ -55,26 +59,26 @@ datetime_in(char *str) 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); @@ -103,7 +107,7 @@ 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); @@ -118,7 +122,7 @@ datetime_out(DateTime *dt) char *result; struct tm tt, *tm = &tt; double fsec; - char buf[MAXDATELEN]; + char buf[MAXDATELEN+1]; if (!PointerIsValid(dt)) return(NULL); @@ -126,7 +130,7 @@ datetime_out(DateTime *dt) 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 { @@ -134,7 +138,7 @@ datetime_out(DateTime *dt) }; 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); @@ -159,7 +163,7 @@ timespan_in(char *str) int nf; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; - char lowstr[MAXDATELEN]; + char lowstr[MAXDATELEN+1]; tm->tm_year = 0; tm->tm_mon = 0; @@ -170,14 +174,14 @@ timespan_in(char *str) 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: @@ -189,7 +193,7 @@ timespan_in(char *str) 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); @@ -205,7 +209,7 @@ timespan_out(TimeSpan *span) struct tm tt, *tm = &tt; double fsec; - char buf[MAXDATELEN]; + char buf[MAXDATELEN+1]; if (!PointerIsValid(span)) return(NULL); @@ -229,6 +233,26 @@ timespan_out(TimeSpan *span) *****************************************************************************/ +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. *---------------------------------------------------------*/ @@ -267,14 +291,14 @@ SetDateTime( DateTime dt) { 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 @@ -520,7 +544,7 @@ TimeSpan *datetime_sub(DateTime *datetime1, DateTime *datetime2) 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); @@ -538,46 +562,83 @@ TimeSpan *datetime_sub(DateTime *datetime1, DateTime *datetime2) } /* 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); +printf( "datetime_add_span- add %f to %d %f\n", *datetime, span->month, span->time); #endif - *result = *datetime; - if (DATETIME_IS_RELATIVE(*result)) *result = SetDateTime(*result); + if (DATETIME_NOT_FINITE(*datetime)) { + *result = *datetime; - if (span->month != 0) { - time = JROUND(modf( (*result/86400), &date)*86400); - date += date2j(2000,1,1); + } else if (TIMESPAN_IS_INVALID(*span)) { + DATETIME_INVALID(*result); - 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; + } 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() */ @@ -607,13 +668,13 @@ TimeSpan *timespan_um(TimeSpan *timespan) 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) @@ -624,7 +685,7 @@ 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); @@ -640,7 +701,7 @@ TimeSpan *timespan_sub(TimeSpan *span1, TimeSpan *span2) 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); @@ -654,6 +715,125 @@ TimeSpan *timespan_sub(TimeSpan *span1, TimeSpan *span2) *---------------------------------------------------------*/ +/* 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) { @@ -662,7 +842,7 @@ 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; @@ -670,7 +850,7 @@ datetime_part(text *units, DateTime *datetime) 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; @@ -694,7 +874,7 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val); 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; @@ -768,6 +948,9 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val); } /* datetime_part() */ +/* timespan_part() + * Extract specified field from timespan. + */ float64 timespan_part(text *units, TimeSpan *timespan) { @@ -775,7 +958,7 @@ 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; @@ -783,7 +966,7 @@ timespan_part(text *units, TimeSpan *timespan) 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; @@ -879,10 +1062,6 @@ printf( "timespan_part- units %s type=%d value=%d\n", lowunits, type, val); * 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 @@ -1218,11 +1397,12 @@ int j2day( int date) * 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; @@ -1233,7 +1413,8 @@ datetime2tm( DateTime dt, struct tm *tm, double *fsec) 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); @@ -1254,8 +1435,8 @@ printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, t 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; @@ -1268,7 +1449,7 @@ printf( "datetime2tm- timezone is %s; offset is %d; daylight is %d\n", * 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; @@ -1284,7 +1465,7 @@ tm2datetime( struct tm *tm, double fsec, int tzp) { 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() */ @@ -1832,40 +2013,17 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm *tm) *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; @@ -1876,7 +2034,25 @@ printf( "DecodeDate- illegal field %s value is %d\n", field[i], val); #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; @@ -1955,6 +2131,19 @@ printf( "DecodeNumber- %s is %d fmask=%08x tmask=%08x\n", str, val, fmask, *tmas 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? */ @@ -1966,7 +2155,7 @@ printf( "DecodeNumber- match %d (%s) as year\n", val, str); &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); @@ -1975,11 +2164,7 @@ 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 @@ -1996,6 +2181,14 @@ printf( "DecodeNumber- (2) match %d (%s) as month\n", val, str); *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); @@ -2467,7 +2660,7 @@ int EncodeDateTime(struct tm *tm, double fsec, int style, char *str) int day, hour, min; double sec; #ifdef DATEDEBUG - char buf[MAXDATELEN]; + char buf[MAXDATELEN+1]; #endif sec = (tm->tm_sec + fsec); diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c index 3ae1978b73..8f1420bbd2 100644 --- a/src/backend/utils/adt/nabstime.c +++ b/src/backend/utils/adt/nabstime.c @@ -7,7 +7,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #ifndef USE_POSIX_TIME #include #endif +#include "utils/builtins.h" #include "access/xact.h" @@ -90,11 +91,19 @@ printf( "GetCurrentAbsoluteTime- timezone is %s -> %d seconds from UTC\n", 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; @@ -105,11 +114,13 @@ GetCurrentTime(struct tm *tm) 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) { @@ -122,13 +133,13 @@ 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; @@ -136,7 +147,7 @@ tm2abstime( struct tm *tm, int tz) /* 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 */ @@ -147,7 +158,7 @@ tm2abstime( struct tm *tm, int tz) /* check for reserved values (e.g. "current" on edge of usual range */ if (!AbsoluteTimeIsReal(sec)) - return INVALID_ABSTIME; + return(INVALID_ABSTIME); return sec; } /* tm2abstime() */ @@ -369,6 +380,16 @@ AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2) } +/* 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 @@ -381,7 +402,7 @@ bool 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) @@ -394,7 +415,7 @@ bool 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) @@ -407,7 +428,7 @@ bool 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) @@ -420,7 +441,7 @@ bool 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) @@ -433,7 +454,7 @@ bool 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) @@ -446,7 +467,7 @@ bool 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) @@ -455,6 +476,7 @@ abstimege(AbsoluteTime t1, AbsoluteTime t2) return(t1 >= t2); } + /* datetime_abstime() * Convert datetime to abstime. */ @@ -480,10 +502,10 @@ datetime_abstime(DateTime *datetime) } 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 { @@ -493,3 +515,42 @@ datetime_abstime(DateTime *datetime) 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() */ diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 641dff80e0..99c7d0f70f 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -88,3 +88,23 @@ timestampge(time_t t1, time_t t2) { 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() */ diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index e5db0259ae..b2d9b4afb9 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -7,7 +7,7 @@ * * 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 @@ -87,29 +87,33 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; * --------------- */ -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 ( 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 ( 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 ( 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 date_smaller - - 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 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 )); +DATA(insert OID = 0 ( count PGUID - int4inc - 0 0 23 23 _null_ 0 )); /* * prototypes for fucnctions in pg_aggregate.c diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 681c9b54f8..04e826b0f2 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -7,7 +7,7 @@ * * 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 @@ -413,6 +413,7 @@ DATA(insert OID = 1325 ( ">=" PGUID 0 b t f 1184 1184 16 1322 1322 0 0 da 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 )); @@ -422,7 +423,7 @@ DATA(insert OID = 1333 ( "<=" PGUID 0 b t f 1186 1186 16 1334 1334 0 0 ti 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 - - )); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 1d8da69051..e8db3a263e 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -6,7 +6,7 @@ * * 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 @@ -337,6 +337,7 @@ DATA(insert OID = 271 ( intervallenge PGUID 11 f t f 2 f 16 "704 703" 100 0 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 )); @@ -754,7 +755,9 @@ DATA(insert OID = 1154 ( datetime_lt PGUID 11 f t f 2 f 16 "1184 1184" 100 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 )); @@ -768,11 +771,24 @@ DATA(insert OID = 1169 ( timespan_add PGUID 11 f t f 2 f 1186 "1186 1186" 1 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 )); @@ -788,6 +804,7 @@ DATA(insert OID = 1238 ( texticregexeq PGUID 11 f t f 2 f 16 "25 25" 100 0 1 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 )); @@ -797,26 +814,73 @@ DATA(insert OID = 1308 ( timestamplt PGUID 11 f t f 2 f 16 "1296 1296" 100 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 */ -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 diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 680566d6a3..7d780b7fc1 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -6,7 +6,7 @@ * * 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. @@ -224,6 +224,8 @@ extern int32 reltimein(char *timestring); 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); @@ -416,6 +418,7 @@ bool timestamplt(time_t t1, time_t 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); @@ -476,6 +479,10 @@ extern DateADT date_smaller(DateADT dateVal1, DateADT dateVal2); 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 @@ -493,6 +500,10 @@ extern int4 date_smaller(int4 dateVal1, int4 dateVal2); 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 diff --git a/src/include/utils/dt.h b/src/include/utils/dt.h index e771f4cffb..9005f5c51f 100644 --- a/src/include/utils/dt.h +++ b/src/include/utils/dt.h @@ -8,7 +8,7 @@ * * 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 $ * *------------------------------------------------------------------------- */ @@ -36,10 +36,16 @@ typedef struct { } 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 * @@ -225,12 +231,13 @@ typedef struct { || 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) @@ -247,6 +254,7 @@ extern bool datetime_lt(DateTime *dt1, DateTime *dt2); 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); @@ -256,9 +264,14 @@ extern bool timespan_lt(TimeSpan *span1, TimeSpan *span2); 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); @@ -269,12 +282,12 @@ extern DateTime *datetime_add_span(DateTime *dt, TimeSpan *span); 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); diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h index e8691f7273..400bb045c5 100644 --- a/src/include/utils/nabstime.h +++ b/src/include/utils/nabstime.h @@ -6,7 +6,7 @@ * * 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 $ * *------------------------------------------------------------------------- */ @@ -84,17 +84,8 @@ typedef TimeIntervalData *TimeInterval; #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. @@ -121,11 +112,17 @@ extern bool abstimelt(AbsoluteTime t1, AbsoluteTime t2); 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); diff --git a/src/man/built-in.3 b/src/man/built-in.3 index 3a667260b8..5f2cf8d456 100644 --- a/src/man/built-in.3 +++ b/src/man/built-in.3 @@ -1,17 +1,15 @@ .\" 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" @@ -24,9 +22,9 @@ described in this section. .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 @@ -37,11 +35,12 @@ described in this section. 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 @@ -50,7 +49,7 @@ described in this section. 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 @@ -58,13 +57,15 @@ described in this section. 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 @@ -73,11 +74,94 @@ described in this section. .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 @@ -89,6 +173,7 @@ where 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 @@ -105,8 +190,19 @@ 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 "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 @@ -124,6 +220,7 @@ In addition, the special relative time \*(lqUndefined RelTime\*(rq is provided. .SH "TIME RANGES" Time ranges are specified as: +.PP .nf [ 'abstime' 'abstime'] .fi @@ -131,6 +228,7 @@ where .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. @@ -151,31 +249,8 @@ select * from emp where int4lt(salary, 40000); 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. .nf Operators: @@ -262,6 +337,68 @@ tinterval 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 ---------+----------+----------+-------+---------------