aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/timestamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/timestamp.c')
-rw-r--r--src/backend/utils/adt/timestamp.c115
1 files changed, 52 insertions, 63 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 4128e3a7392..ea0ada704f2 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -2156,16 +2156,34 @@ timestamp_hash_extended(PG_FUNCTION_ARGS)
* Cross-type comparison functions for timestamp vs timestamptz
*/
+int32
+timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
+{
+ TimestampTz dt1;
+ int overflow;
+
+ dt1 = timestamp2timestamptz_opt_overflow(timestampVal, &overflow);
+ if (overflow > 0)
+ {
+ /* dt1 is larger than any finite timestamp, but less than infinity */
+ return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
+ }
+ if (overflow < 0)
+ {
+ /* dt1 is less than any finite timestamp, but more than -infinity */
+ return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
+ }
+
+ return timestamptz_cmp_internal(dt1, dt2);
+}
+
Datum
timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
-
- dt1 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) == 0);
}
Datum
@@ -2173,11 +2191,8 @@ timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
- dt1 = timestamp2timestamptz(timestampVal);
-
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) != 0);
}
Datum
@@ -2185,11 +2200,8 @@ timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
-
- dt1 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) < 0);
}
Datum
@@ -2197,11 +2209,8 @@ timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
-
- dt1 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) > 0);
}
Datum
@@ -2209,11 +2218,8 @@ timestamp_le_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
-
- dt1 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0);
}
Datum
@@ -2221,11 +2227,8 @@ timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
-
- dt1 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0);
}
Datum
@@ -2233,11 +2236,8 @@ timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
- TimestampTz dt1;
- dt1 = timestamp2timestamptz(timestampVal);
-
- PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
+ PG_RETURN_INT32(timestamp_cmp_timestamptz_internal(timestampVal, dt2));
}
Datum
@@ -2245,11 +2245,8 @@ timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
-
- dt2 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) == 0);
}
Datum
@@ -2257,11 +2254,8 @@ timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
-
- dt2 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) != 0);
}
Datum
@@ -2269,11 +2263,8 @@ timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
- dt2 = timestamp2timestamptz(timestampVal);
-
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) > 0);
}
Datum
@@ -2281,11 +2272,8 @@ timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
-
- dt2 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) < 0);
}
Datum
@@ -2293,11 +2281,8 @@ timestamptz_le_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
-
- dt2 = timestamp2timestamptz(timestampVal);
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0);
}
Datum
@@ -2305,11 +2290,8 @@ timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
- dt2 = timestamp2timestamptz(timestampVal);
-
- PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
+ PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0);
}
Datum
@@ -2317,11 +2299,8 @@ timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
- TimestampTz dt2;
-
- dt2 = timestamp2timestamptz(timestampVal);
- PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
+ PG_RETURN_INT32(-timestamp_cmp_timestamptz_internal(timestampVal, dt1));
}
@@ -5178,9 +5157,12 @@ timestamp_timestamptz(PG_FUNCTION_ARGS)
/*
* Convert timestamp to timestamp with time zone.
*
- * On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow'
- * is set to -1 (+1) when result value exceed lower (upper) boundary and zero
- * returned.
+ * On successful conversion, *overflow is set to zero if it's not NULL.
+ *
+ * If the timestamp is finite but out of the valid range for timestamptz, then:
+ * if overflow is NULL, we throw an out-of-range error.
+ * if overflow is not NULL, we store +1 or -1 there to indicate the sign
+ * of the overflow, and return the appropriate timestamptz infinity.
*/
TimestampTz
timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
@@ -5191,10 +5173,14 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
fsec_t fsec;
int tz;
+ if (overflow)
+ *overflow = 0;
+
if (TIMESTAMP_NOT_FINITE(timestamp))
return timestamp;
- if (!timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL))
+ /* We don't expect this to fail, but check it pro forma */
+ if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
{
tz = DetermineTimeZoneOffset(tm, session_timezone);
@@ -5207,13 +5193,16 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
else if (overflow)
{
if (result < MIN_TIMESTAMP)
+ {
*overflow = -1;
+ TIMESTAMP_NOBEGIN(result);
+ }
else
{
- Assert(result >= END_TIMESTAMP);
*overflow = 1;
+ TIMESTAMP_NOEND(result);
}
- return (TimestampTz) 0;
+ return result;
}
}
@@ -5225,7 +5214,7 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
}
/*
- * Single-argument version of timestamp2timestamptz_opt_overflow().
+ * Promote timestamp to timestamptz, throwing error for overflow.
*/
static TimestampTz
timestamp2timestamptz(Timestamp timestamp)