1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Accept an INTERVAL argument for SET TIME ZONE per SQL99.

Modified the parser and the SET handlers to use full Node structures
 rather than simply a character string argument.
Implement INTERVAL() YEAR TO MONTH (etc) syntax per SQL99.
 Does not yet accept the goofy string format that goes along with, but
 this should be fairly straight forward to fix now as a bug or later
 as a feature.
Implement precision for the INTERVAL() type.
 Use the typmod mechanism for both of INTERVAL features.
Fix the INTERVAL syntax in the parser:
 opt_interval was in the wrong place.
INTERVAL is now a reserved word, otherwise we get reduce/reduce errors.
Implement an explicit date_part() function for TIMETZ.
 Should fix coersion problem with INTERVAL reported by Peter E.
Fix up some error messages for date/time types.
 Use all caps for type names within message.
Fix recently introduced side-effect bug disabling 'epoch' as a recognized
 field for date_part() etc. Reported by Peter E. (??)
Bump catalog version number.
Rename "microseconds" current transaction time field
 from ...Msec to ...Usec. Duh!
date/time regression tests updated for reference platform, but a few
 changes will be necessary for others.
This commit is contained in:
Thomas G. Lockhart
2001-10-18 17:30:21 +00:00
parent 6254465d06
commit 9310075a13
23 changed files with 940 additions and 368 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.61 2001/10/04 15:14:22 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.62 2001/10/18 17:30:15 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1458,6 +1458,117 @@ text_timetz(PG_FUNCTION_ARGS)
Int32GetDatum(-1));
}
/* timetz_part()
* Extract specified field from time type.
*/
Datum
timetz_part(PG_FUNCTION_ARGS)
{
text *units = PG_GETARG_TEXT_P(0);
TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
float8 result;
int type,
val;
int i;
char *up,
*lp,
lowunits[MAXDATELEN + 1];
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "TIMETZ units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
lp = lowunits;
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
*lp++ = tolower((unsigned char) *up++);
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (type == UNKNOWN_FIELD)
type = DecodeSpecial(0, lowunits, &val);
if (type == UNITS)
{
double trem;
double dummy;
int tz;
double fsec;
struct tm tt,
*tm = &tt;
trem = time->time;
TMODULO(trem, tm->tm_hour, 3600e0);
TMODULO(trem, tm->tm_min, 60e0);
TMODULO(trem, tm->tm_sec, 1e0);
fsec = trem;
tz = time->zone;
switch (val)
{
case DTK_TZ:
result = tz;
break;
case DTK_TZ_MINUTE:
result = tz / 60;
TMODULO(result, dummy, 60e0);
break;
case DTK_TZ_HOUR:
dummy = tz;
TMODULO(dummy, result, 3600e0);
break;
case DTK_MICROSEC:
result = ((tm->tm_sec + fsec) * 1000000);
break;
case DTK_MILLISEC:
result = ((tm->tm_sec + fsec) * 1000);
break;
case DTK_SECOND:
result = (tm->tm_sec + fsec);
break;
case DTK_MINUTE:
result = tm->tm_min;
break;
case DTK_HOUR:
result = tm->tm_hour;
break;
case DTK_DAY:
case DTK_MONTH:
case DTK_QUARTER:
case DTK_YEAR:
case DTK_DECADE:
case DTK_CENTURY:
case DTK_MILLENNIUM:
default:
elog(ERROR, "TIMETZ units '%s' not supported",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
result = 0;
}
}
else if ((type == RESERV) && (val == DTK_EPOCH))
{
result = time->time - time->zone;
}
else
{
elog(ERROR, "TIMETZ units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
result = 0;
}
PG_RETURN_FLOAT8(result);
}
/* timetz_zone()
* Encode time with time zone type with specified time zone.
*/

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.72 2001/10/11 18:06:52 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.73 2001/10/18 17:30:15 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,6 +38,7 @@ static int DecodeTimezone(char *str, int *tzp);
static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
static int DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);
static int DecodePosixTimezone(char *str, int *val);
void TrimTrailingZeros(char *str);
int day_tab[2][13] = {
@@ -239,81 +240,73 @@ static unsigned int australian_szdatetktbl = sizeof australian_datetktbl /
sizeof australian_datetktbl[0];
static datetkn deltatktbl[] = {
/* text, token, lexval */
{"@", IGNORE, 0}, /* postgres relative time prefix */
/* text, token, lexval */
{"@", IGNORE, 0}, /* postgres relative prefix */
{DAGO, AGO, 0}, /* "ago" indicates negative time offset */
{"c", UNITS, DTK_CENTURY}, /* "century" relative time units */
{"cent", UNITS, DTK_CENTURY}, /* "century" relative time units */
{"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative time units */
{DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative time units */
{"d", UNITS, DTK_DAY}, /* "day" relative time units */
{DDAY, UNITS, DTK_DAY}, /* "day" relative time units */
{"days", UNITS, DTK_DAY}, /* "days" relative time units */
{"dec", UNITS, DTK_DECADE}, /* "decade" relative time units */
{"decs", UNITS, DTK_DECADE},/* "decades" relative time units */
{DDECADE, UNITS, DTK_DECADE}, /* "decade" relative time units */
{"decades", UNITS, DTK_DECADE}, /* "decades" relative time units */
{"h", UNITS, DTK_HOUR}, /* "hour" relative time units */
{DHOUR, UNITS, DTK_HOUR}, /* "hour" relative time units */
{"hours", UNITS, DTK_HOUR}, /* "hours" relative time units */
{"hr", UNITS, DTK_HOUR}, /* "hour" relative time units */
{"hrs", UNITS, DTK_HOUR}, /* "hours" relative time units */
{"c", UNITS, DTK_CENTURY}, /* "century" relative */
{"cent", UNITS, DTK_CENTURY}, /* "century" relative */
{"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative */
{DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative */
{"d", UNITS, DTK_DAY}, /* "day" relative */
{DDAY, UNITS, DTK_DAY}, /* "day" relative */
{"days", UNITS, DTK_DAY}, /* "days" relative */
{"dec", UNITS, DTK_DECADE}, /* "decade" relative */
{"decs", UNITS, DTK_DECADE}, /* "decades" relative */
{DDECADE, UNITS, DTK_DECADE}, /* "decade" relative */
{"decades", UNITS, DTK_DECADE}, /* "decades" relative */
{"h", UNITS, DTK_HOUR}, /* "hour" relative */
{DHOUR, UNITS, DTK_HOUR}, /* "hour" relative */
{"hours", UNITS, DTK_HOUR}, /* "hours" relative */
{"hr", UNITS, DTK_HOUR}, /* "hour" relative */
{"hrs", UNITS, DTK_HOUR}, /* "hours" relative */
{INVALID, RESERV, DTK_INVALID}, /* reserved for invalid time */
{"m", UNITS, DTK_MINUTE}, /* "minute" relative time units */
{"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative
* time units */
{"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative time
* units */
{"mils", UNITS, DTK_MILLENNIUM}, /* "millennia" relative time units */
{"millennia", UNITS, DTK_MILLENNIUM}, /* "millennia" relative
* time units */
{DMILLENNIUM, UNITS, DTK_MILLENNIUM}, /* "millennium" relative
* time units */
{"millisecon", UNITS, DTK_MILLISEC}, /* relative time units */
{"min", UNITS, DTK_MINUTE}, /* "minute" relative time units */
{"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */
{"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */
{DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative time units */
{"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative time units */
{"mon", UNITS, DTK_MONTH}, /* "months" relative time units */
{"mons", UNITS, DTK_MONTH}, /* "months" relative time units */
{DMONTH, UNITS, DTK_MONTH}, /* "month" relative time units */
{"m", UNITS, DTK_MINUTE}, /* "minute" relative */
{"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative */
{"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative */
{"millennia", UNITS, DTK_MILLENNIUM}, /* "millennia" relative */
{DMILLENNIUM, UNITS, DTK_MILLENNIUM}, /* "millennium" relative */
{"millisecon", UNITS, DTK_MILLISEC}, /* relative */
{"mils", UNITS, DTK_MILLENNIUM}, /* "millennia" relative */
{"min", UNITS, DTK_MINUTE}, /* "minute" relative */
{"mins", UNITS, DTK_MINUTE}, /* "minutes" relative */
{"mins", UNITS, DTK_MINUTE}, /* "minutes" relative */
{DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative */
{"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative */
{"mon", UNITS, DTK_MONTH}, /* "months" relative */
{"mons", UNITS, DTK_MONTH}, /* "months" relative */
{DMONTH, UNITS, DTK_MONTH}, /* "month" relative */
{"months", UNITS, DTK_MONTH},
{"ms", UNITS, DTK_MILLISEC},
{"msec", UNITS, DTK_MILLISEC},
{DMILLISEC, UNITS, DTK_MILLISEC},
{"mseconds", UNITS, DTK_MILLISEC},
{"msecs", UNITS, DTK_MILLISEC},
{"qtr", UNITS, DTK_QUARTER},/* "quarter" relative time */
{DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative time */
{"reltime", IGNORE, 0}, /* for pre-v6.1 "Undefined Reltime" */
{"qtr", UNITS, DTK_QUARTER}, /* "quarter" relative */
{DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative */
{"reltime", IGNORE, 0}, /* pre-v6.1 "Undefined Reltime" */
{"s", UNITS, DTK_SECOND},
{"sec", UNITS, DTK_SECOND},
{DSECOND, UNITS, DTK_SECOND},
{"seconds", UNITS, DTK_SECOND},
{"secs", UNITS, DTK_SECOND},
{DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */
{DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */
{"timezone", UNITS, DTK_TZ}, /* "timezone" time offset */
{"timezone_h", UNITS, DTK_TZ_HOUR}, /* timezone hour units */
{"timezone_m", UNITS, DTK_TZ_MINUTE}, /* timezone minutes units */
{"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */
{"us", UNITS, DTK_MICROSEC},/* "microsecond" relative time units */
{"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative time
* units */
{DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative time
* units */
{"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative time
* units */
{"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative time
* units */
{"w", UNITS, DTK_WEEK}, /* "week" relative time units */
{DWEEK, UNITS, DTK_WEEK}, /* "week" relative time units */
{"weeks", UNITS, DTK_WEEK}, /* "weeks" relative time units */
{"y", UNITS, DTK_YEAR}, /* "year" relative time units */
{DYEAR, UNITS, DTK_YEAR}, /* "year" relative time units */
{"years", UNITS, DTK_YEAR}, /* "years" relative time units */
{"yr", UNITS, DTK_YEAR}, /* "year" relative time units */
{"yrs", UNITS, DTK_YEAR}, /* "years" relative time units */
{"us", UNITS, DTK_MICROSEC}, /* "microsecond" relative */
{"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative */
{DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative */
{"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative */
{"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative */
{"w", UNITS, DTK_WEEK}, /* "week" relative */
{DWEEK, UNITS, DTK_WEEK}, /* "week" relative */
{"weeks", UNITS, DTK_WEEK}, /* "weeks" relative */
{"y", UNITS, DTK_YEAR}, /* "year" relative */
{DYEAR, UNITS, DTK_YEAR}, /* "year" relative */
{"years", UNITS, DTK_YEAR}, /* "years" relative */
{"yr", UNITS, DTK_YEAR}, /* "year" relative */
{"yrs", UNITS, DTK_YEAR}, /* "years" relative */
};
static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];
@@ -346,8 +339,10 @@ date2j(int y, int m, int d)
{
int m12 = (m - 14) / 12;
return ((1461 * (y + 4800 + m12)) / 4 + (367 * (m - 2 - 12 * (m12))) / 12
- (3 * ((y + 4900 + m12) / 100)) / 4 + d - 32075);
return ((1461 * (y + 4800 + m12)) / 4
+ (367 * (m - 2 - 12 * (m12))) / 12
- (3 * ((y + 4900 + m12) / 100)) / 4
+ d - 32075);
} /* date2j() */
void
@@ -390,11 +385,28 @@ j2day(int date)
} /* j2day() */
/*
* parse and convert date in timestr (the normal interface)
*
* Returns the number of seconds since epoch (J2000)
*/
void
TrimTrailingZeros(char *str)
{
int len = strlen(str);
/* chop off trailing one to cope with interval rounding */
if (strcmp((str + len - 4), "0001") == 0)
{
len -= 4;
*(str + len) = '\0';
}
/* chop off trailing zeros... */
while ((*(str + len - 1) == '0')
&& (*(str + len - 3) != '.'))
{
len--;
*(str + len) = '\0';
}
return;
}
/* ParseDateTime()
* Break string into tokens based on a date/time context.
@@ -989,7 +1001,11 @@ DetermineLocalTimeZone(struct tm * tm)
{
int tz;
if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
if (HasCTZSet)
{
tz = CTimeZone;
}
else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
{
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
/*
@@ -1044,9 +1060,6 @@ DetermineLocalTimeZone(struct tm * tm)
* SQL92 TIME WITH TIME ZONE, but it reveals
* bogosity with SQL92 date/time standards, since
* we must infer a time zone from current time.
* XXX Later, we should probably support
* SET TIME ZONE <integer>
* which of course is a screwed up convention.
* - thomas 2000-03-10
*/
int
@@ -2246,33 +2259,23 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
*/
if (fsec != 0) {
sprintf((str + strlen(str)), ":%013.10f", sec);
/* chop off trailing pairs of zeros... */
while ((strcmp((str + strlen(str) - 2), "00") == 0)
&& (*(str + strlen(str) - 3) != '.'))
{
*(str + strlen(str) - 2) = '\0';
}
TrimTrailingZeros(str);
}
else
{
sprintf((str + strlen(str)), ":%02.0f", sec);
}
if ((*tzn != NULL) && (tm->tm_isdst >= 0))
/* tzp == NULL indicates that we don't want *any* time zone info in the output string.
* *tzn != NULL indicates that we *have* time zone info available.
* tm_isdst != -1 indicates that we have a valid time zone translation.
*/
if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0))
{
if (tzp != NULL)
{
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
}
else
{
hour = 0;
min = 0;
}
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
}
}
else
{
@@ -2305,12 +2308,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
*/
if (fsec != 0) {
sprintf((str + strlen(str)), ":%013.10f", sec);
/* chop off trailing pairs of zeros... */
while ((strcmp((str + strlen(str) - 2), "00") == 0)
&& (*(str + strlen(str) - 3) != '.'))
{
*(str + strlen(str) - 2) = '\0';
}
TrimTrailingZeros(str);
}
else
{
@@ -2319,6 +2317,13 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
if ((*tzn != NULL) && (tm->tm_isdst >= 0))
sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
else if (tzp != NULL)
{
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
}
}
else
sprintf((str + 5), "/%04d %02d:%02d %s",
@@ -2341,12 +2346,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
*/
if (fsec != 0) {
sprintf((str + strlen(str)), ":%013.10f", sec);
/* chop off trailing pairs of zeros... */
while ((strcmp((str + strlen(str) - 2), "00") == 0)
&& (*(str + strlen(str) - 3) != '.'))
{
*(str + strlen(str) - 2) = '\0';
}
TrimTrailingZeros(str);
}
else
{
@@ -2355,6 +2355,13 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
if ((*tzn != NULL) && (tm->tm_isdst >= 0))
sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
else if (tzp != NULL)
{
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
}
}
else
sprintf((str + 5), ".%04d %02d:%02d %s",
@@ -2387,12 +2394,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
*/
if (fsec != 0) {
sprintf((str + strlen(str)), ":%013.10f", sec);
/* chop off trailing pairs of zeros... */
while ((strcmp((str + strlen(str) - 2), "00") == 0)
&& (*(str + strlen(str) - 3) != '.'))
{
*(str + strlen(str) - 2) = '\0';
}
TrimTrailingZeros(str);
}
else
{
@@ -2400,8 +2402,16 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
}
sprintf((str + strlen(str)), " %04d", tm->tm_year);
if ((*tzn != NULL) && (tm->tm_isdst >= 0))
if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0))
sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
else if (HasCTZSet && (tzp != NULL))
{
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
}
}
else
{
@@ -2485,12 +2495,12 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
if (fsec != 0)
{
fsec += tm->tm_sec;
sprintf(cp, ":%05.2f", fabs(fsec));
sprintf(cp, ":%013.10f", fabs(fsec));
TrimTrailingZeros(cp);
cp += strlen(cp);
is_nonzero = TRUE;
/* otherwise, integer seconds only? */
}
/* otherwise, integer seconds only? */
else if (tm->tm_sec != 0)
{
sprintf(cp, ":%02d", abs(tm->tm_sec));

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.87 2001/10/01 02:31:33 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.88 2001/10/18 17:30:15 thomas Exp $
*
* NOTES
*
@@ -113,7 +113,7 @@ static int istinterval(char *i_string,
/* GetCurrentAbsoluteTime()
* Get the current system time. Set timezone parameters if not specified elsewhere.
* Define HasTZSet to allow clients to specify the default timezone.
* Define HasCTZSet to allow clients to specify the default timezone.
*
* Returns the number of seconds since epoch (January 1 1970 GMT)
*/
@@ -173,7 +173,7 @@ GetCurrentAbsoluteTime(void)
*/
strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));
#endif
};
}
return (AbsoluteTime) now;
} /* GetCurrentAbsoluteTime() */
@@ -181,7 +181,7 @@ GetCurrentAbsoluteTime(void)
/* GetCurrentAbsoluteTime()
* Get the current system time. Set timezone parameters if not specified elsewhere.
* Define HasTZSet to allow clients to specify the default timezone.
* Define HasCTZSet to allow clients to specify the default timezone.
*
* Returns the number of seconds since epoch (January 1 1970 GMT)
*/
@@ -284,7 +284,7 @@ GetCurrentTimeUsec(struct tm *tm, double *fsec)
void
abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn)
abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
{
time_t time = (time_t) _time;
@@ -297,9 +297,15 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn)
ftime(&tb);
#endif
/* If HasCTZSet is true then we have a brute force time zone specified.
* Go ahead and rotate to the local time zone since we will later bypass
* any calls which adjust the tm fields.
*/
if (HasCTZSet && (tzp != NULL))
time -= CTimeZone;
#if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE)
if (tzp != NULL)
if ((! HasCTZSet) && (tzp != NULL))
{
tx = localtime((time_t *) &time);
#ifdef NO_MKTIME_BEFORE_1970
@@ -329,47 +335,95 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn)
tm->tm_zone = tx->tm_zone;
if (tzp != NULL)
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
/* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
if (tzn != NULL)
{
/*
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
/* We have a brute force time zone per SQL99?
* Then use it without change
* since we have already rotated to the time zone.
*/
StrNCpy(tzn, tm->tm_zone, MAXTZLEN + 1);
if (strlen(tm->tm_zone) > MAXTZLEN)
elog(NOTICE, "Invalid timezone \'%s\'", tm->tm_zone);
if (HasCTZSet)
{
*tzp = CTimeZone;
tm->tm_gmtoff = CTimeZone;
tm->tm_isdst = -1;
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
}
else
{
*tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
/* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
if (tzn != NULL)
{
/*
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
*/
StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
if (strlen(tm->tm_zone) > MAXTZLEN)
elog(NOTICE, "Invalid timezone \'%s\'", tm->tm_zone);
}
}
}
#elif defined(HAVE_INT_TIMEZONE)
if (tzp != NULL)
*tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL);
if (tzn != NULL)
{
/*
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
/* We have a brute force time zone per SQL99?
* Then use it without change
* since we have already rotated to the time zone.
*/
StrNCpy(tzn, tzname[tm->tm_isdst], MAXTZLEN + 1);
if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN)
elog(NOTICE, "Invalid timezone \'%s\'", tzname[tm->tm_isdst]);
if (HasCTZSet)
{
*tzp = CTimeZone;
tm->tm_isdst = -1;
if (tzn != NULL)
*tzn = NULL;
}
else
{
*tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL);
if (tzn != NULL)
{
/*
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
*/
StrNCpy(*tzn, tzname[tm->tm_isdst], MAXTZLEN + 1);
if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN)
elog(NOTICE, "Invalid timezone \'%s\'", tzname[tm->tm_isdst]);
}
}
}
#endif
#else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
if (tzp != NULL)
*tzp = tb.timezone * 60;
/*
* XXX does this work to get the local timezone string in V7? - tgl
* 97/03/18
*/
if (tzn != NULL)
{
strftime(tzn, MAXTZLEN, "%Z", localtime(&now));
tzn[MAXTZLEN] = '\0'; /* let's just be sure it's null-terminated */
/* We have a brute force time zone per SQL99?
* Then use it without change
* since we have already rotated to the time zone.
*/
if (HasCTZSet)
{
*tzp = CTimeZone;
if (tzn != NULL)
*tzn = NULL;
}
else
{
*tzp = tb.timezone * 60;
/*
* XXX does this work to get the local timezone string in V7? - tgl
* 97/03/18
*/
if (tzn != NULL)
{
strftime(*tzn, MAXTZLEN, "%Z", localtime(&now));
tzn[MAXTZLEN] = '\0'; /* let's just be sure it's null-terminated */
}
}
}
#endif
@@ -508,7 +562,7 @@ nabstimeout(PG_FUNCTION_ARGS)
strcpy(buf, EARLY);
break;
default:
abstime2tm(time, &tz, tm, tzn);
abstime2tm(time, &tz, tm, &tzn);
EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf);
break;
}
@@ -676,7 +730,8 @@ abstime_timestamp(PG_FUNCTION_ARGS)
struct tm tt,
*tm = &tt;
int tz;
char tzn[MAXTZLEN];
char zone[MAXDATELEN + 1],
*tzn = zone;
switch (abstime)
{
@@ -694,7 +749,7 @@ abstime_timestamp(PG_FUNCTION_ARGS)
break;
default:
abstime2tm(abstime, &tz, tm, tzn);
abstime2tm(abstime, &tz, tm, &tzn);
result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400) + tz;
break;
};

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.55 2001/10/05 06:38:59 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.56 2001/10/18 17:30:15 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,6 +33,7 @@ static double time2t(const int hour, const int min, const double sec);
static int EncodeSpecialTimestamp(Timestamp dt, char *str);
static Timestamp dt2local(Timestamp dt, int timezone);
static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod);
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod);
/*****************************************************************************
@@ -69,7 +70,7 @@ timestamp_in(PG_FUNCTION_ARGS)
{
case DTK_DATE:
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Timestamp out of range '%s'", str);
elog(ERROR, "TIMESTAMP out of range '%s'", str);
break;
case DTK_EPOCH:
@@ -85,12 +86,12 @@ timestamp_in(PG_FUNCTION_ARGS)
break;
case DTK_INVALID:
elog(ERROR, "Timestamp '%s' no longer supported", str);
elog(ERROR, "TIMESTAMP '%s' no longer supported", str);
TIMESTAMP_NOEND(result);
break;
default:
elog(ERROR, "Timestamp '%s' not parsed; internal coding error", str);
elog(ERROR, "TIMESTAMP '%s' not parsed; internal coding error", str);
TIMESTAMP_NOEND(result);
}
@@ -157,7 +158,7 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
TimestampTypmod = typmod;
}
*time = (rint(((double) *time)*TimestampScale)/TimestampScale);
*time = (rint(((double) *time) * TimestampScale)/TimestampScale);
}
}
@@ -192,7 +193,7 @@ timestamptz_in(PG_FUNCTION_ARGS)
{
case DTK_DATE:
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Timestamp out of range '%s'", str);
elog(ERROR, "TIMESTAMP WITH TIME ZONE out of range '%s'", str);
break;
case DTK_EPOCH:
@@ -208,12 +209,12 @@ timestamptz_in(PG_FUNCTION_ARGS)
break;
case DTK_INVALID:
elog(ERROR, "Timestamp with time zone '%s' no longer supported", str);
elog(ERROR, "TIMESTAMP WITH TIME ZONE '%s' no longer supported", str);
TIMESTAMP_NOEND(result);
break;
default:
elog(ERROR, "Timestamp with time zone '%s' not parsed; internal coding error", str);
elog(ERROR, "TIMESTAMP WITH TIME ZONE '%s' not parsed; internal coding error", str);
TIMESTAMP_NOEND(result);
}
@@ -277,6 +278,10 @@ Datum
interval_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 typmod = PG_GETARG_INT32(2);
Interval *result;
double fsec;
struct tm tt,
@@ -306,6 +311,7 @@ interval_in(PG_FUNCTION_ARGS)
case DTK_DELTA:
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Bad interval external representation '%s'", str);
AdjustIntervalForTypmod(result, typmod);
break;
case DTK_INVALID:
@@ -342,6 +348,148 @@ interval_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result);
}
/* interval_scale()
* Adjust interval type for specified fields.
* Used by PostgreSQL type system to stuff columns.
*/
Datum
interval_scale(PG_FUNCTION_ARGS)
{
Interval *interval = PG_GETARG_INTERVAL_P(0);
int32 typmod = PG_GETARG_INT32(1);
Interval *result;
result = palloc(sizeof(Interval));
*result = *interval;
AdjustIntervalForTypmod(result, typmod);
PG_RETURN_INTERVAL_P(result);
}
#define MASK(b) (1 << (b))
static void
AdjustIntervalForTypmod(Interval *interval, int32 typmod)
{
if (typmod != -1)
{
int range = ((typmod >> 16) & 0xFFFF);
int precision = (typmod & 0xFFFF);
if (range == 0xFFFF)
{
/* Do nothing... */
}
if (range == MASK(YEAR))
{
interval->month = ((interval->month / 12) * 12);
interval->time = 0;
}
else if (range == MASK(MONTH))
{
interval->month %= 12;
interval->time = 0;
}
/* YEAR TO MONTH */
else if (range == (MASK(YEAR) | MASK(MONTH)))
{
interval->time = 0;
}
else if (range == MASK(DAY))
{
interval->month = 0;
interval->time = (((int)(interval->time / 86400)) * 86400);
}
else if (range == MASK(HOUR))
{
double day;
interval->month = 0;
TMODULO(interval->time, day, 86400.0);
interval->time = (((int)(interval->time / 3600)) * 3600.0);
}
else if (range == MASK(MINUTE))
{
double hour;
interval->month = 0;
TMODULO(interval->time, hour, 3600.0);
interval->time = (((int)(interval->time / 60)) * 60);
}
else if (range == MASK(SECOND))
{
double hour;
interval->month = 0;
TMODULO(interval->time, hour, 60.0);
// interval->time = (int)(interval->time);
}
/* DAY TO HOUR */
else if (range == (MASK(DAY) | MASK(HOUR)))
{
interval->month = 0;
interval->time = (((int)(interval->time / 3600)) * 3600);
}
/* DAY TO MINUTE */
else if (range == (MASK(DAY) | MASK(HOUR) | MASK(MINUTE)))
{
interval->month = 0;
interval->time = (((int)(interval->time / 60)) * 60);
}
/* DAY TO SECOND */
else if (range == (MASK(DAY) | MASK(HOUR) | MASK(MINUTE) | MASK(SECOND)))
{
interval->month = 0;
}
/* HOUR TO MINUTE */
else if (range == (MASK(HOUR) | MASK(MINUTE)))
{
double day;
interval->month = 0;
TMODULO(interval->time, day, 86400.0);
interval->time = (((int)(interval->time / 60)) * 60);
}
/* HOUR TO SECOND */
else if (range == (MASK(HOUR) | MASK(MINUTE) | MASK(SECOND)))
{
double day;
interval->month = 0;
TMODULO(interval->time, day, 86400.0);
}
/* MINUTE TO SECOND */
else if (range == (MASK(MINUTE) | MASK(SECOND)))
{
double hour;
interval->month = 0;
TMODULO(interval->time, hour, 3600.0);
}
else
{
elog(ERROR, "AdjustIntervalForTypmod(): internal coding error");
}
if (precision != 0xFFFF)
{
static double IntervalScale = 1;
static int IntervalTypmod = 0;
if (precision != IntervalTypmod)
{
IntervalTypmod = precision;
IntervalScale = pow(10.0, IntervalTypmod);
}
interval->time = (rint(interval->time * IntervalScale) / IntervalScale);
}
}
return;
}
/* EncodeSpecialTimestamp()
* Convert reserved timestamp data type to string.
@@ -417,6 +565,13 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
date0 = date2j(2000, 1, 1);
/* If HasCTZSet is true then we have a brute force time zone specified.
* Go ahead and rotate to the local time zone since we will later bypass
* any calls which adjust the tm fields.
*/
if (HasCTZSet && (tzp != NULL))
dt -= CTimeZone;
time = dt;
TMODULO(time, date, 86400e0);
@@ -441,7 +596,24 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
if (tzp != NULL)
{
if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
/* We have a brute force time zone per SQL99?
* Then use it without change
* since we have already rotated to the time zone.
*/
if (HasCTZSet)
{
*tzp = CTimeZone;
tm->tm_gmtoff = CTimeZone;
tm->tm_isdst = 0;
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
}
/* Does this fall within the capabilities of the localtime() interface?
* Then use this to rotate to the local time zone.
*/
else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
{
utime = (dt + (date0 - date2j(1970, 1, 1)) * 86400);
@@ -492,6 +664,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
*tzn = CTZName;
#endif
dt = dt2local(dt, *tzp);
}
else
{
@@ -500,9 +673,6 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
if (tzn != NULL)
*tzn = NULL;
}
dt = dt2local(dt, *tzp);
}
else
{
@@ -1072,14 +1242,14 @@ timestamp_pl_span(PG_FUNCTION_ARGS)
if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
{
elog(ERROR, "Unable to add timestamp and interval"
elog(ERROR, "Unable to add TIMESTAMP and INTERVAL"
"\n\ttimestamp_pl_span() internal error encoding timestamp");
PG_RETURN_NULL();
}
}
else
{
elog(ERROR, "Unable to add timestamp and interval"
elog(ERROR, "Unable to add TIMESTAMP and INTERVAL"
"\n\ttimestamp_pl_span() internal error decoding timestamp");
PG_RETURN_NULL();
}
@@ -1164,12 +1334,12 @@ timestamptz_pl_span(PG_FUNCTION_ARGS)
tz = DetermineLocalTimeZone(tm);
if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
elog(ERROR, "Unable to add timestamp and interval"
elog(ERROR, "Unable to add TIMESTAMP and INTERVAL"
"\n\ttimestamptz_pl_span() internal error encoding timestamp");
}
else
{
elog(ERROR, "Unable to add timestamp and interval"
elog(ERROR, "Unable to add TIMESTAMP and INTERVAL"
"\n\ttimestamptz_pl_span() internal error decoding timestamp");
}
}
@@ -1546,11 +1716,11 @@ timestamp_age(PG_FUNCTION_ARGS)
}
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Unable to encode interval"
elog(ERROR, "Unable to encode INTERVAL"
"\n\ttimestamp_age() internal coding error");
}
else
elog(ERROR, "Unable to decode timestamp"
elog(ERROR, "Unable to decode TIMESTAMP"
"\n\ttimestamp_age() internal coding error");
PG_RETURN_INTERVAL_P(result);
@@ -1655,10 +1825,10 @@ timestamptz_age(PG_FUNCTION_ARGS)
}
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Unable to decode timestamp");
elog(ERROR, "Unable to decode TIMESTAMP");
}
else
elog(ERROR, "Unable to decode timestamp");
elog(ERROR, "Unable to decode TIMESTAMP");
PG_RETURN_INTERVAL_P(result);
}
@@ -1711,7 +1881,7 @@ text_timestamp(PG_FUNCTION_ARGS)
dstr[MAXDATELEN + 1];
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Bad timestamp external representation (too long)");
elog(ERROR, "TIMESTAMP bad external representation (too long)");
sp = VARDATA(str);
dp = dstr;
@@ -1767,7 +1937,7 @@ text_timestamptz(PG_FUNCTION_ARGS)
dstr[MAXDATELEN + 1];
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Bad timestamp with time zone external representation (too long)");
elog(ERROR, "TIMESTAMP WITH TIME ZONE bad external representation (too long)");
sp = VARDATA(str);
dp = dstr;
@@ -1824,14 +1994,17 @@ text_interval(PG_FUNCTION_ARGS)
dstr[MAXDATELEN + 1];
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Bad interval external representation (too long)");
elog(ERROR, "INTERVAL bad external representation (too long)");
sp = VARDATA(str);
dp = dstr;
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
*dp++ = *sp++;
*dp = '\0';
return DirectFunctionCall1(interval_in, CStringGetDatum(dstr));
return DirectFunctionCall3(interval_in,
CStringGetDatum(dstr),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
}
/* timestamp_trunc()
@@ -1854,7 +2027,7 @@ timestamp_trunc(PG_FUNCTION_ARGS)
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "TIMESTAMP units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -1903,16 +2076,16 @@ timestamp_trunc(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits);
result = 0;
}
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits);
elog(ERROR, "Unable to truncate TIMESTAMP to '%s'", lowunits);
}
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
elog(ERROR, "TIMESTAMP units '%s' not recognized", lowunits);
result = 0;
}
@@ -1941,7 +2114,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -1984,24 +2157,23 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
case DTK_MILLISEC:
fsec = rint(fsec * 1000) / 1000;
break;
case DTK_MICROSEC:
fsec = rint(fsec * 1000000) / 1000000;
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits);
result = 0;
}
tz = DetermineLocalTimeZone(tm);
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits);
elog(ERROR, "Unable to truncate TIMESTAMP WITH TIME ZONE to '%s'", lowunits);
}
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", lowunits);
PG_RETURN_NULL();
}
@@ -2030,7 +2202,7 @@ interval_trunc(PG_FUNCTION_ARGS)
result = (Interval *) palloc(sizeof(Interval));
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "INTERVAL units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -2078,22 +2250,22 @@ interval_trunc(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Interval units '%s' not supported", lowunits);
elog(ERROR, "INTERVAL units '%s' not supported", lowunits);
}
if (tm2interval(tm, fsec, result) != 0)
elog(ERROR, "Unable to truncate interval to '%s'", lowunits);
elog(ERROR, "Unable to truncate INTERVAL to '%s'", lowunits);
}
else
{
elog(NOTICE, "Unable to decode interval; internal coding error");
elog(NOTICE, "Unable to decode INTERVAL; internal coding error");
*result = *interval;
}
}
else
{
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "INTERVAL units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
*result = *interval;
@@ -2202,7 +2374,7 @@ timestamp_part(PG_FUNCTION_ARGS)
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "TIMESTAMP units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -2212,7 +2384,7 @@ timestamp_part(PG_FUNCTION_ARGS)
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (type == IGNORE)
if (type == UNKNOWN_FIELD)
type = DecodeSpecial(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
@@ -2221,7 +2393,8 @@ timestamp_part(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(result);
}
if ((type == UNITS) && (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0))
if ((type == UNITS)
&& (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0))
{
switch (val)
{
@@ -2281,7 +2454,7 @@ timestamp_part(PG_FUNCTION_ARGS)
case DTK_TZ_MINUTE:
case DTK_TZ_HOUR:
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits);
result = 0;
}
}
@@ -2295,28 +2468,28 @@ timestamp_part(PG_FUNCTION_ARGS)
case DTK_DOW:
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to encode timestamp");
elog(ERROR, "Unable to encode TIMESTAMP");
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
break;
case DTK_DOY:
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to encode timestamp");
elog(ERROR, "Unable to encode TIMESTAMP");
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1);
break;
default:
elog(ERROR, "Timestamp units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits);
result = 0;
}
}
else
{
elog(ERROR, "Timestamp units '%s' not recognized", lowunits);
elog(ERROR, "TIMESTAMP units '%s' not recognized", lowunits);
result = 0;
}
@@ -2346,7 +2519,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -2356,7 +2529,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (type == IGNORE)
if (type == UNKNOWN_FIELD)
type = DecodeSpecial(0, lowunits, &val);
if (TIMESTAMP_NOT_FINITE(timestamp))
@@ -2436,7 +2609,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits);
result = 0;
}
@@ -2451,27 +2624,27 @@ timestamptz_part(PG_FUNCTION_ARGS)
case DTK_DOW:
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp with time zone");
elog(ERROR, "Unable to encode TIMESTAMP WITH TIME ZONE");
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
break;
case DTK_DOY:
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to encode timestamp with time zone");
elog(ERROR, "Unable to encode TIMESTAMP WITH TIME ZONE");
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1);
break;
default:
elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits);
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits);
result = 0;
}
}
else
{
elog(ERROR, "Timestamp with time zone units '%s' not recognized", lowunits);
elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", lowunits);
result = 0;
}
@@ -2499,7 +2672,7 @@ interval_part(PG_FUNCTION_ARGS)
*tm = &tt;
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "INTERVAL units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
up = VARDATA(units);
@@ -2509,7 +2682,7 @@ interval_part(PG_FUNCTION_ARGS)
*lp = '\0';
type = DecodeUnits(0, lowunits, &val);
if (type == IGNORE)
if (type == UNKNOWN_FIELD)
type = DecodeSpecial(0, lowunits, &val);
if (type == UNITS)
@@ -2567,7 +2740,7 @@ interval_part(PG_FUNCTION_ARGS)
break;
default:
elog(ERROR, "Interval units '%s' not supported",
elog(ERROR, "INTERVAL units '%s' not supported",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
result = 0;
@@ -2576,7 +2749,7 @@ interval_part(PG_FUNCTION_ARGS)
}
else
{
elog(NOTICE, "Unable to decode interval"
elog(NOTICE, "Unable to decode INTERVAL"
"\n\tinterval_part() internal coding error");
result = 0;
}
@@ -2592,7 +2765,7 @@ interval_part(PG_FUNCTION_ARGS)
}
else
{
elog(ERROR, "Interval units '%s' not recognized",
elog(ERROR, "INTERVAL units '%s' not recognized",
DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(units))));
result = 0;
@@ -2695,12 +2868,12 @@ timestamp_timestamptz(PG_FUNCTION_ARGS)
else
{
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to convert timestamp to timestamp with time zone (tm)");
elog(ERROR, "Unable to convert TIMESTAMP to TIMESTAMP WITH TIME ZONE (tm)");
tz = DetermineLocalTimeZone(tm);
if (tm2timestamp(tm, fsec, &tz, &result) != 0)
elog(ERROR, "Unable to convert timestamp to timestamp with time zone");
elog(ERROR, "Unable to convert TIMESTAMP to TIMESTAMP WITH TIME ZONE");
}
PG_RETURN_TIMESTAMPTZ(result);
@@ -2727,10 +2900,10 @@ timestamptz_timestamp(PG_FUNCTION_ARGS)
else
{
if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert timestamp with time zone to timestamp (tm)");
elog(ERROR, "Unable to convert TIMESTAMP WITH TIME ZONE to TIMESTAMP (tm)");
if (tm2timestamp(tm, fsec, NULL, &result) != 0)
elog(ERROR, "Unable to convert timestamp with time zone to timestamp");
elog(ERROR, "Unable to convert TIMESTAMP WITH TIME ZONE to TIMESTAMP");
}
PG_RETURN_TIMESTAMP(result);
@@ -2784,8 +2957,8 @@ timestamptz_zone(PG_FUNCTION_ARGS)
dt = dt2local(timestamp, tz);
if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to decode timestamp"
"\n\ttimestamp_zone() internal coding error");
elog(ERROR, "Unable to decode TIMESTAMP WITH TIME ZONE"
"\n\ttimestamptz_zone() internal coding error");
up = upzone;
lp = lowzone;
@@ -2845,8 +3018,8 @@ timestamptz_izone(PG_FUNCTION_ARGS)
dt = dt2local(timestamp, tz);
if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0)
elog(ERROR, "Unable to decode timestamp"
"\n\ttimestamp_izone() internal coding error");
elog(ERROR, "Unable to decode TIMESTAMP WITH TIME ZONE"
"\n\ttimestamptz_izone() internal coding error");
EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf);
len = (strlen(buf) + VARHDRSZ);