aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/nabstime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/nabstime.c')
-rw-r--r--src/backend/utils/adt/nabstime.c254
1 files changed, 115 insertions, 139 deletions
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index a4f3b061e6f..f694349db7a 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.113 2003/08/04 02:40:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.114 2003/08/17 19:58:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -505,11 +505,11 @@ abstime_finite(PG_FUNCTION_ARGS)
static int
abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
{
-/*
- * We consider all INVALIDs to be equal and larger than any non-INVALID.
- * This is somewhat arbitrary; the important thing is to have a
- * consistent sort order.
- */
+ /*
+ * We consider all INVALIDs to be equal and larger than any non-INVALID.
+ * This is somewhat arbitrary; the important thing is to have a
+ * consistent sort order.
+ */
if (a == INVALID_ABSTIME)
{
if (b == INVALID_ABSTIME)
@@ -904,7 +904,7 @@ tintervalout(PG_FUNCTION_ARGS)
char *i_str,
*p;
- i_str = (char *) palloc(T_INTERVAL_LEN); /* ['...' '...'] */
+ i_str = (char *) palloc(T_INTERVAL_LEN); /* ["..." "..."] */
strcpy(i_str, "[\"");
if (interval->status == T_INTERVAL_INVAL)
strcat(i_str, INVALID_INTERVAL_STR);
@@ -920,7 +920,7 @@ tintervalout(PG_FUNCTION_ARGS)
strcat(i_str, p);
pfree(p);
}
- strcat(i_str, "\"]\0");
+ strcat(i_str, "\"]");
PG_RETURN_CSTRING(i_str);
}
@@ -1190,22 +1190,42 @@ timenow(PG_FUNCTION_ARGS)
}
/*
- * reltimeeq - returns true iff arguments are equal
- * reltimene - returns true iff arguments are not equal
- * reltimelt - returns true iff t1 less than t2
- * reltimegt - returns true iff t1 greater than t2
- * reltimele - returns true iff t1 less than or equal to t2
- * reltimege - returns true iff t1 greater than or equal to t2
+ * reltime comparison routines
*/
+static int
+reltime_cmp_internal(RelativeTime a, RelativeTime b)
+{
+ /*
+ * We consider all INVALIDs to be equal and larger than any non-INVALID.
+ * This is somewhat arbitrary; the important thing is to have a
+ * consistent sort order.
+ */
+ if (a == INVALID_RELTIME)
+ {
+ if (b == INVALID_RELTIME)
+ return 0; /* INVALID = INVALID */
+ else
+ return 1; /* INVALID > non-INVALID */
+ }
+
+ if (b == INVALID_RELTIME)
+ return -1; /* non-INVALID < INVALID */
+
+ if (a > b)
+ return 1;
+ else if (a == b)
+ return 0;
+ else
+ return -1;
+}
+
Datum
reltimeeq(PG_FUNCTION_ARGS)
{
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 == t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) == 0);
}
Datum
@@ -1214,9 +1234,7 @@ reltimene(PG_FUNCTION_ARGS)
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 != t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) != 0);
}
Datum
@@ -1225,9 +1243,7 @@ reltimelt(PG_FUNCTION_ARGS)
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 < t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) < 0);
}
Datum
@@ -1236,9 +1252,7 @@ reltimegt(PG_FUNCTION_ARGS)
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 > t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) > 0);
}
Datum
@@ -1247,9 +1261,7 @@ reltimele(PG_FUNCTION_ARGS)
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 <= t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) <= 0);
}
Datum
@@ -1258,9 +1270,16 @@ reltimege(PG_FUNCTION_ARGS)
RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
- if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
- PG_RETURN_BOOL(false);
- PG_RETURN_BOOL(t1 >= t2);
+ PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) >= 0);
+}
+
+Datum
+btreltimecmp(PG_FUNCTION_ARGS)
+{
+ RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
+ RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
+
+ PG_RETURN_INT32(reltime_cmp_internal(t1, t2));
}
@@ -1287,59 +1306,71 @@ tintervalsame(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
}
-
/*
- * tintervaleq - returns true iff interval i1 is equal to interval i2
- * Check length of intervals.
+ * tinterval comparison routines
+ *
+ * Note: comparison is based on the lengths of the intervals, not on
+ * endpoint value. This is pretty bogus, but since it's only a legacy
+ * datatype I'm not going to propose changing it.
*/
-Datum
-tintervaleq(PG_FUNCTION_ARGS)
+static int
+tinterval_cmp_internal(TimeInterval a, TimeInterval b)
{
- TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
- TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
+ bool a_invalid;
+ bool b_invalid;
+ AbsoluteTime a_len;
+ AbsoluteTime b_len;
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
+ /*
+ * We consider all INVALIDs to be equal and larger than any non-INVALID.
+ * This is somewhat arbitrary; the important thing is to have a
+ * consistent sort order.
+ */
+ a_invalid = ((a->status == T_INTERVAL_INVAL) ||
+ (a->data[0] == INVALID_ABSTIME) ||
+ (a->data[1] == INVALID_ABSTIME));
+ b_invalid = ((b->status == T_INTERVAL_INVAL) ||
+ (b->data[0] == INVALID_ABSTIME) ||
+ (b->data[1] == INVALID_ABSTIME));
+
+ if (a_invalid)
+ {
+ if (b_invalid)
+ return 0; /* INVALID = INVALID */
+ else
+ return 1; /* INVALID > non-INVALID */
+ }
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
+ if (b_invalid)
+ return -1; /* non-INVALID < INVALID */
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
+ a_len = a->data[1] - a->data[0];
+ b_len = b->data[1] - b->data[0];
- PG_RETURN_BOOL((t11 - t10) == (t21 - t20));
+ if (a_len > b_len)
+ return 1;
+ else if (a_len == b_len)
+ return 0;
+ else
+ return -1;
}
Datum
-tintervalne(PG_FUNCTION_ARGS)
+tintervaleq(PG_FUNCTION_ARGS)
{
TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
-
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) == 0);
+}
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
+Datum
+tintervalne(PG_FUNCTION_ARGS)
+{
+ TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
+ TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- PG_RETURN_BOOL((t11 - t10) != (t21 - t20));
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) != 0);
}
Datum
@@ -1347,24 +1378,8 @@ tintervallt(PG_FUNCTION_ARGS)
{
TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
-
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
-
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
-
- PG_RETURN_BOOL((t11 - t10) < (t21 - t20));
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) < 0);
}
Datum
@@ -1372,24 +1387,8 @@ tintervalle(PG_FUNCTION_ARGS)
{
TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
-
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
-
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
-
- PG_RETURN_BOOL((t11 - t10) <= (t21 - t20));
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) <= 0);
}
Datum
@@ -1397,24 +1396,8 @@ tintervalgt(PG_FUNCTION_ARGS)
{
TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
-
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
-
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
-
- PG_RETURN_BOOL((t11 - t10) > (t21 - t20));
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) > 0);
}
Datum
@@ -1422,24 +1405,17 @@ tintervalge(PG_FUNCTION_ARGS)
{
TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- AbsoluteTime t10,
- t11,
- t20,
- t21;
-
- if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
- PG_RETURN_BOOL(false);
- t10 = i1->data[0];
- t11 = i1->data[1];
- t20 = i2->data[0];
- t21 = i2->data[1];
+ PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) >= 0);
+}
- if ((t10 == INVALID_ABSTIME) || (t11 == INVALID_ABSTIME)
- || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
- PG_RETURN_BOOL(false);
+Datum
+bttintervalcmp(PG_FUNCTION_ARGS)
+{
+ TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
+ TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
- PG_RETURN_BOOL((t11 - t10) >= (t21 - t20));
+ PG_RETURN_INT32(tinterval_cmp_internal(i1, i2));
}
@@ -1652,7 +1628,7 @@ istinterval(char *i_string,
break;
}
p++;
- /* skip leading blanks up to "'" */
+ /* skip leading blanks up to '"' */
while ((c = *p) != '\0')
{
if (IsSpace(c))
@@ -1680,10 +1656,10 @@ istinterval(char *i_string,
/* get the first date */
*i_start = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
CStringGetDatum(p)));
- /* rechange NULL at the end of the first date to a "'" */
+ /* rechange NULL at the end of the first date to a '"' */
*p1 = '"';
p = ++p1;
- /* skip blanks up to "'", beginning of second date */
+ /* skip blanks up to '"', beginning of second date */
while ((c = *p) != '\0')
{
if (IsSpace(c))
@@ -1708,7 +1684,7 @@ istinterval(char *i_string,
/* get the second date */
*i_end = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
CStringGetDatum(p)));
- /* rechange NULL at the end of the first date to a ''' */
+ /* rechange NULL at the end of the first date to a '"' */
*p1 = '"';
p = ++p1;
/* skip blanks up to ']' */