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 5fe304cea75..0159e05209f 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -2152,16 +2152,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
@@ -2169,11 +2187,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
@@ -2181,11 +2196,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
@@ -2193,11 +2205,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
@@ -2205,11 +2214,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
@@ -2217,11 +2223,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
@@ -2229,11 +2232,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
@@ -2241,11 +2241,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
@@ -2253,11 +2250,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
@@ -2265,11 +2259,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
@@ -2277,11 +2268,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
@@ -2289,11 +2277,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
@@ -2301,11 +2286,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
@@ -2313,11 +2295,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));
}
@@ -5174,9 +5153,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)
@@ -5187,10 +5169,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);
@@ -5203,13 +5189,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;
}
}
@@ -5221,7 +5210,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)