aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/date.c
diff options
context:
space:
mode:
authorThomas G. Lockhart <lockhart@fourpalms.org>2000-03-14 23:06:59 +0000
committerThomas G. Lockhart <lockhart@fourpalms.org>2000-03-14 23:06:59 +0000
commit64568100787a5d03d036e70b32147385a35245e2 (patch)
tree4b6091aedff9deed40992a05d1cacf9ce1b54c8b /src/backend/utils/adt/date.c
parentce543b2121a772d18e25e1efbad252dcd360df96 (diff)
downloadpostgresql-64568100787a5d03d036e70b32147385a35245e2.tar.gz
postgresql-64568100787a5d03d036e70b32147385a35245e2.zip
Implement column aliases on views "CREATE VIEW name (collist)".
Implement TIME WITH TIME ZONE type (timetz internal type). Remap length() for character strings to CHAR_LENGTH() for SQL92 and to remove the ambiguity with geometric length() functions. Keep length() for character strings for backward compatibility. Shrink stored views by removing internal column name list from visible rte. Implement min(), max() for time and timetz data types. Implement conversion of TIME to INTERVAL. Implement abs(), mod(), fac() for the int8 data type. Rename some math functions to generic names: round(), sqrt(), cbrt(), pow(), etc. Rename NUMERIC power() function to pow(). Fix int2 factorial to calculate result in int4. Enhance the Oracle compatibility function translate() to work with string arguments (from Edwin Ramirez). Modify pg_proc system table to remove OID holes.
Diffstat (limited to 'src/backend/utils/adt/date.c')
-rw-r--r--src/backend/utils/adt/date.c336
1 files changed, 319 insertions, 17 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 7102f64a44f..378289373b8 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.42 2000/02/16 18:17:02 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.43 2000/03/14 23:06:35 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,7 +198,7 @@ date_timestamp(DateADT dateVal)
double fsec = 0;
char *tzn;
- result = palloc(sizeof(Timestamp));
+ result = palloc(sizeof(*result));
if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert date to timestamp");
@@ -392,10 +392,10 @@ time_in(char *str)
elog(ERROR, "Bad (null) time external representation");
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, NULL) != 0))
elog(ERROR, "Bad time external representation '%s'", str);
- time = palloc(sizeof(TimeADT));
+ time = palloc(sizeof(*time));
*time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
@@ -422,7 +422,7 @@ time_out(TimeADT *time)
fsec = 0;
- EncodeTimeOnly(tm, fsec, DateStyle, buf);
+ EncodeTimeOnly(tm, fsec, NULL, DateStyle, buf);
result = palloc(strlen(buf) + 1);
@@ -456,8 +456,8 @@ time_lt(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 < *time2;
-} /* time_eq() */
+ return (*time1 < *time2);
+} /* time_lt() */
bool
time_le(TimeADT *time1, TimeADT *time2)
@@ -465,8 +465,8 @@ time_le(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 <= *time2;
-} /* time_eq() */
+ return (*time1 <= *time2);
+} /* time_le() */
bool
time_gt(TimeADT *time1, TimeADT *time2)
@@ -474,8 +474,8 @@ time_gt(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 > *time2;
-} /* time_eq() */
+ return (*time1 > *time2);
+} /* time_gt() */
bool
time_ge(TimeADT *time1, TimeADT *time2)
@@ -483,8 +483,8 @@ time_ge(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 >= *time2;
-} /* time_eq() */
+ return (*time1 >= *time2);
+} /* time_ge() */
int
time_cmp(TimeADT *time1, TimeADT *time2)
@@ -492,6 +492,43 @@ time_cmp(TimeADT *time1, TimeADT *time2)
return (*time1 < *time2) ? -1 : (((*time1 > *time2) ? 1 : 0));
} /* time_cmp() */
+TimeADT *
+time_larger(TimeADT *time1, TimeADT *time2)
+{
+ return time_gt(time1, time2)? time1: time2;
+} /* time_larger() */
+
+TimeADT *
+time_smaller(TimeADT *time1, TimeADT *time2)
+{
+ return time_lt(time1, time2)? time1: time2;
+} /* time_smaller() */
+
+/* overlaps_time()
+ * Implements the SQL92 OVERLAPS operator.
+ * Algorithm from Date and Darwen, 1997
+ */
+bool
+overlaps_time(TimeADT *ts1, TimeADT *te1, TimeADT *ts2, TimeADT *te2)
+{
+ /* Make sure we have ordered pairs... */
+ if (time_gt(ts1, te1))
+ {
+ TimeADT *tt = ts1;
+ ts1 = te1;
+ te1 = tt;
+ }
+ if (time_gt(ts2, te2))
+ {
+ TimeADT *tt = ts2;
+ ts2 = te2;
+ te2 = tt;
+ }
+
+ return ((time_gt(ts1, ts2) && (time_lt(ts1, te2) || time_lt(te1, te2)))
+ || (time_gt(ts2, ts1) && (time_lt(ts2, te1) || time_lt(te2, te1)))
+ || time_eq(ts1, ts2));
+}
/* timestamp_time()
* Convert timestamp to time data type.
@@ -515,12 +552,10 @@ timestamp_time(Timestamp *timestamp)
if (TIMESTAMP_IS_EPOCH(*timestamp))
{
timestamp2tm(SetTimestamp(*timestamp), NULL, tm, &fsec, NULL);
-
}
else if (TIMESTAMP_IS_CURRENT(*timestamp))
{
timestamp2tm(SetTimestamp(*timestamp), &tz, tm, &fsec, &tzn);
-
}
else
{
@@ -528,7 +563,7 @@ timestamp_time(Timestamp *timestamp)
elog(ERROR, "Unable to convert timestamp to date");
}
- result = palloc(sizeof(TimeADT));
+ result = palloc(sizeof(*result));
*result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
@@ -546,7 +581,7 @@ datetime_timestamp(DateADT date, TimeADT *time)
if (!PointerIsValid(time))
{
- result = palloc(sizeof(Timestamp));
+ result = palloc(sizeof(*result));
TIMESTAMP_INVALID(*result);
}
else
@@ -557,3 +592,270 @@ datetime_timestamp(DateADT date, TimeADT *time)
return result;
} /* datetime_timestamp() */
+
+
+/* time_interval()
+ * Convert time to interval data type.
+ */
+Interval *
+time_interval(TimeADT *time)
+{
+ Interval *result;
+
+ if (!PointerIsValid(time))
+ return NULL;
+
+ result = palloc(sizeof(*result));
+ result->time = *time;
+ result->month = 0;
+
+ return result;
+} /* time_interval() */
+
+
+/*****************************************************************************
+ * Time With Time Zone ADT
+ *****************************************************************************/
+
+
+TimeTzADT *
+timetz_in(char *str)
+{
+ TimeTzADT *time;
+
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+
+ int nf;
+ char lowstr[MAXDATELEN + 1];
+ char *field[MAXDATEFIELDS];
+ int dtype;
+ int ftype[MAXDATEFIELDS];
+
+ if (!PointerIsValid(str))
+ elog(ERROR, "Bad (null) time external representation");
+
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
+ elog(ERROR, "Bad time external representation '%s'", str);
+
+ time = palloc(sizeof(*time));
+
+ time->time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
+ time->zone = tz;
+
+ return time;
+} /* timetz_in() */
+
+
+char *
+timetz_out(TimeTzADT *time)
+{
+ char *result;
+ struct tm tt,
+ *tm = &tt;
+
+ double fsec;
+ int tz;
+ char buf[MAXDATELEN + 1];
+
+ if (!PointerIsValid(time))
+ return NULL;
+
+ tm->tm_hour = (time->time / (60 * 60));
+ tm->tm_min = (((int) (time->time / 60)) % 60);
+ tm->tm_sec = (((int) time->time) % 60);
+
+ fsec = 0;
+ tz = time->zone;
+
+ EncodeTimeOnly(tm, fsec, &tz, DateStyle, buf);
+
+ result = palloc(strlen(buf) + 1);
+
+ strcpy(result, buf);
+
+ return result;
+} /* timetz_out() */
+
+
+bool
+timetz_eq(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) == (time2->time + time2->zone));
+} /* timetz_eq() */
+
+bool
+timetz_ne(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) != (time2->time + time2->zone));
+} /* timetz_ne() */
+
+bool
+timetz_lt(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) < (time2->time + time2->zone));
+} /* timetz_lt() */
+
+bool
+timetz_le(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) <= (time2->time + time2->zone));
+} /* timetz_le() */
+
+bool
+timetz_gt(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) > (time2->time + time2->zone));
+} /* timetz_gt() */
+
+bool
+timetz_ge(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) >= (time2->time + time2->zone));
+} /* timetz_ge() */
+
+int
+timetz_cmp(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return (timetz_lt(time1, time2) ? -1 : (timetz_gt(time1, time2)? 1: 0));
+} /* timetz_cmp() */
+
+TimeTzADT *
+timetz_larger(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return timetz_gt(time1, time2)? time1: time2;
+} /* timetz_larger() */
+
+TimeTzADT *
+timetz_smaller(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return timetz_lt(time1, time2)? time1: time2;
+} /* timetz_smaller() */
+
+/* overlaps_timetz()
+ * Implements the SQL92 OVERLAPS operator.
+ * Algorithm from Date and Darwen, 1997
+ */
+bool
+overlaps_timetz(TimeTzADT *ts1, TimeTzADT *te1, TimeTzADT *ts2, TimeTzADT *te2)
+{
+ /* Make sure we have ordered pairs... */
+ if (timetz_gt(ts1, te1))
+ {
+ TimeTzADT *tt = ts1;
+ ts1 = te1;
+ te1 = tt;
+ }
+ if (timetz_gt(ts2, te2))
+ {
+ TimeTzADT *tt = ts2;
+ ts2 = te2;
+ te2 = tt;
+ }
+
+ return ((timetz_gt(ts1, ts2) && (timetz_lt(ts1, te2) || timetz_lt(te1, te2)))
+ || (timetz_gt(ts2, ts1) && (timetz_lt(ts2, te1) || timetz_lt(te2, te1)))
+ || timetz_eq(ts1, ts2));
+} /* overlaps_timetz() */
+
+/* timestamp_timetz()
+ * Convert timestamp to timetz data type.
+ */
+TimeTzADT *
+timestamp_timetz(Timestamp *timestamp)
+{
+ TimeTzADT *result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec;
+ char *tzn;
+
+ if (!PointerIsValid(timestamp))
+ elog(ERROR, "Unable to convert null timestamp to date");
+
+ if (TIMESTAMP_NOT_FINITE(*timestamp))
+ elog(ERROR, "Unable to convert timestamp to date");
+
+ if (TIMESTAMP_IS_EPOCH(*timestamp))
+ {
+ timestamp2tm(SetTimestamp(*timestamp), NULL, tm, &fsec, NULL);
+ tz = 0;
+ }
+ else if (TIMESTAMP_IS_CURRENT(*timestamp))
+ {
+ timestamp2tm(SetTimestamp(*timestamp), &tz, tm, &fsec, &tzn);
+ }
+ else
+ {
+ if (timestamp2tm(*timestamp, &tz, tm, &fsec, &tzn) != 0)
+ elog(ERROR, "Unable to convert timestamp to date");
+ }
+
+ result = palloc(sizeof(*result));
+
+ result->time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
+ result->zone = tz;
+
+ return result;
+} /* timestamp_timetz() */
+
+
+/* datetimetz_timestamp()
+ * Convert date and timetz to timestamp data type.
+ * Timestamp is stored in GMT, so add the time zone
+ * stored with the timetz to the result.
+ * - thomas 2000-03-10
+ */
+Timestamp *
+datetimetz_timestamp(DateADT date, TimeTzADT *time)
+{
+ Timestamp *result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec = 0;
+ char *tzn;
+
+ result = palloc(sizeof(*result));
+
+ if (!PointerIsValid(date) || !PointerIsValid(time))
+ {
+ TIMESTAMP_INVALID(*result);
+ }
+ else
+ {
+ if (date2tm(date, &tz, tm, &fsec, &tzn) != 0)
+ elog(ERROR, "Unable to convert date to timestamp");
+
+ if (tm2timestamp(tm, fsec, &time->zone, result) != 0)
+ elog(ERROR, "Timestamp out of range");
+
+ *result += time->time;
+ }
+
+ return result;
+} /* datetimetz_timestamp() */
+
+