diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index a19ae9e48a..d7f4da718b 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.51 2000/10/29 13:17:33 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.52 2000/11/11 19:55:19 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -339,6 +339,61 @@ abstime_date(PG_FUNCTION_ARGS) } +/* date_text() + * Convert date to text data type. + */ +Datum +date_text(PG_FUNCTION_ARGS) +{ + /* Input is a Date, but may as well leave it in Datum form */ + Datum date = PG_GETARG_DATUM(0); + text *result; + char *str; + int len; + + str = DatumGetCString(DirectFunctionCall1(date_out, date)); + + len = (strlen(str) + VARHDRSZ); + + result = palloc(len); + + VARATT_SIZEP(result) = len; + memmove(VARDATA(result), str, (len - VARHDRSZ)); + + pfree(str); + + PG_RETURN_TEXT_P(result); +} + + +/* text_date() + * Convert text string to date. + * Text type is not null terminated, so use temporary string + * then call the standard input routine. + */ +Datum +text_date(PG_FUNCTION_ARGS) +{ + text *str = PG_GETARG_TEXT_P(0); + int i; + char *sp, + *dp, + dstr[MAXDATELEN + 1]; + + if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) + elog(ERROR, "Bad date external representation (too long)"); + + sp = VARDATA(str); + dp = dstr; + for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) + *dp++ = *sp++; + *dp = '\0'; + + return DirectFunctionCall1(date_in, + CStringGetDatum(dstr)); +} + + /***************************************************************************** * Time ADT *****************************************************************************/ @@ -576,6 +631,61 @@ time_interval(PG_FUNCTION_ARGS) } +/* time_text() + * Convert time to text data type. + */ +Datum +time_text(PG_FUNCTION_ARGS) +{ + /* Input is a Time, but may as well leave it in Datum form */ + Datum time = PG_GETARG_DATUM(0); + text *result; + char *str; + int len; + + str = DatumGetCString(DirectFunctionCall1(time_out, time)); + + len = (strlen(str) + VARHDRSZ); + + result = palloc(len); + + VARATT_SIZEP(result) = len; + memmove(VARDATA(result), str, (len - VARHDRSZ)); + + pfree(str); + + PG_RETURN_TEXT_P(result); +} + + +/* text_time() + * Convert text string to time. + * Text type is not null terminated, so use temporary string + * then call the standard input routine. + */ +Datum +text_time(PG_FUNCTION_ARGS) +{ + text *str = PG_GETARG_TEXT_P(0); + int i; + char *sp, + *dp, + dstr[MAXDATELEN + 1]; + + if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) + elog(ERROR, "Bad time external representation (too long)"); + + sp = VARDATA(str); + dp = dstr; + for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) + *dp++ = *sp++; + *dp = '\0'; + + return DirectFunctionCall1(time_in, + CStringGetDatum(dstr)); +} + + /***************************************************************************** * Time With Time Zone ADT *****************************************************************************/ @@ -851,3 +961,58 @@ datetimetz_timestamp(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMP(result); } + + +/* timetz_text() + * Convert timetz to text data type. + */ +Datum +timetz_text(PG_FUNCTION_ARGS) +{ + /* Input is a Timetz, but may as well leave it in Datum form */ + Datum timetz = PG_GETARG_DATUM(0); + text *result; + char *str; + int len; + + str = DatumGetCString(DirectFunctionCall1(timetz_out, timetz)); + + len = (strlen(str) + VARHDRSZ); + + result = palloc(len); + + VARATT_SIZEP(result) = len; + memmove(VARDATA(result), str, (len - VARHDRSZ)); + + pfree(str); + + PG_RETURN_TEXT_P(result); +} + + +/* text_timetz() + * Convert text string to timetz. + * Text type is not null terminated, so use temporary string + * then call the standard input routine. + */ +Datum +text_timetz(PG_FUNCTION_ARGS) +{ + text *str = PG_GETARG_TEXT_P(0); + int i; + char *sp, + *dp, + dstr[MAXDATELEN + 1]; + + if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) + elog(ERROR, "Bad timetz external representation (too long)"); + + sp = VARDATA(str); + dp = dstr; + for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) + *dp++ = *sp++; + *dp = '\0'; + + return DirectFunctionCall1(timetz_in, + CStringGetDatum(dstr)); +} diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 0f8f344ef5..a167943dff 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.55 2000/11/06 15:57:00 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.56 2000/11/11 19:55:19 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -494,7 +494,7 @@ ParseDateTime(char *timestr, char *lowstr, { ftype[nf] = DTK_TZ; *lp++ = *cp++; - while (isdigit((int) *cp) || (*cp == ':')) + while (isdigit((int) *cp) || (*cp == ':') || (*cp == '.')) *lp++ = *cp++; /* special? */ @@ -1657,7 +1657,7 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do *dtype = DTK_DELTA; - type = DTK_SECOND; + type = IGNORE; tm->tm_year = 0; tm->tm_mon = 0; tm->tm_mday = 0; @@ -1687,7 +1687,7 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do * So, work this out to drop through to DTK_NUMBER, which *can* tolerate this. */ cp = field[i]+1; - while ((*cp != '\0') && (*cp != ':')) + while ((*cp != '\0') && (*cp != ':') && (*cp != '.')) cp++; if ((*cp == ':') && (DecodeTime((field[i]+1), fmask, &tmask, tm, fsec) == 0)) { @@ -1705,6 +1705,14 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do type = DTK_DAY; tmask = DTK_M(TZ); break; + } else if (type == IGNORE) { + if (*cp == '.') { + /* Got a decimal point? Then assume some sort of seconds specification */ + type = DTK_SECOND; + } else if (*cp == '\0') { + /* Only a signed integer? Then must assume a timezone-like usage */ + type = DTK_HOUR; + } } /* DROP THROUGH */ @@ -1714,6 +1722,8 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do if (*cp == '.') { + if (type == IGNORE) + type = DTK_SECOND; fval = strtod(cp, &cp); if (*cp != '\0') return -1; diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index ab147d295b..4478dc95ef 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.37 2000/11/06 15:57:00 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.38 2000/11/11 19:55:19 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -2100,11 +2100,11 @@ interval_part(PG_FUNCTION_ARGS) switch (val) { case DTK_MICROSEC: - result = (fsec * 1000000); + result = ((tm->tm_sec + fsec) * 1000000); break; case DTK_MILLISEC: - result = (fsec * 1000); + result = ((tm->tm_sec + fsec) * 1000); break; case DTK_SECOND: