From: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>

Subject: [HACKERS] More date time functions

Here are some additional patches mostly related to the date and time
data types. It includes some type conversion routines to move between
the different date types and some other date manipulation routines such
as date_part(units,datetime).

I noticed Edmund Mergl et al's neat trick for getting function overloading
for builtin functions, so started to use that for the date and time stuff.
Later, if someone figures out how to get function overloading directly
for internal C code, then we can move to that technique.

These patches include documentation updates (don't faint!) for the built-in
man page. Doesn't yet include mention of timestamp, since I don't know
much about it and since it may change a bit to become a _real_ ANSI timestamp
which would include parser support for the declaration syntax (what do you
think, Dan?).

The patches were developed on the 970330 release, but have been rebuilt
off of the 970402 release. The first patch below is to get libpq to compile,
on my Linux box, but is not related to the rest of the patches and you can
choose not to apply that one at this time. Thanks in advance, scrappy!
This commit is contained in:
Marc G. Fournier 1997-04-02 18:36:24 +00:00
parent 920c58df71
commit 2ab34dfe1a
12 changed files with 997 additions and 340 deletions

View File

@ -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 <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 '@'
@ -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
*/

View File

@ -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 <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},
@ -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 */

View File

@ -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 <errno.h>
#include "postgres.h"
#include <miscadmin.h>
#include "miscadmin.h"
#ifdef HAVE_FLOAT_H
# include <float.h>
#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);

View File

@ -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 <sys/timeb.h>
#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() */

View File

@ -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 *) &timestamp);
tm->tm_year += 1900;
tm->tm_mon += 1;
*result = tm2datetime(tm, fsec, NULL);
return(result);
} /* timestamp_datetime() */

View File

@ -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

View File

@ -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 - - ));

View File

@ -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 <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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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
---------+----------+----------+-------+---------------