aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/date.c167
-rw-r--r--src/backend/utils/adt/datetime.c18
-rw-r--r--src/backend/utils/adt/timestamp.c6
3 files changed, 183 insertions, 8 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index a19ae9e48af..d7f4da718bf 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 0f8f344ef58..a167943dff9 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 ab147d295b5..4478dc95efa 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: