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.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index d7ee865cf75..c1d6f05b5ed 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -72,13 +72,13 @@ static Timestamp dt2local(Timestamp dt, int timezone);
static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod);
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod);
static TimestampTz timestamp2timestamptz(Timestamp timestamp);
+static Timestamp timestamptz2timestamp(TimestampTz timestamp);
/* common code for timestamptypmodin and timestamptztypmodin */
static int32
anytimestamp_typmodin(bool istz, ArrayType *ta)
{
- int32 typmod;
int32 *tl;
int n;
@@ -93,22 +93,27 @@ anytimestamp_typmodin(bool istz, ArrayType *ta)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid type modifier")));
- if (*tl < 0)
+ return anytimestamp_typmod_check(istz, tl[0]);
+}
+
+/* exported so parse_expr.c can use it */
+int32
+anytimestamp_typmod_check(bool istz, int32 typmod)
+{
+ if (typmod < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision must not be negative",
- *tl, (istz ? " WITH TIME ZONE" : ""))));
- if (*tl > MAX_TIMESTAMP_PRECISION)
+ typmod, (istz ? " WITH TIME ZONE" : ""))));
+ if (typmod > MAX_TIMESTAMP_PRECISION)
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
- *tl, (istz ? " WITH TIME ZONE" : ""),
+ typmod, (istz ? " WITH TIME ZONE" : ""),
MAX_TIMESTAMP_PRECISION)));
typmod = MAX_TIMESTAMP_PRECISION;
}
- else
- typmod = *tl;
return typmod;
}
@@ -336,6 +341,10 @@ timestamp_scale(PG_FUNCTION_ARGS)
PG_RETURN_TIMESTAMP(result);
}
+/*
+ * AdjustTimestampForTypmod --- round off a timestamp to suit given typmod
+ * Works for either timestamp or timestamptz.
+ */
static void
AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
{
@@ -1687,6 +1696,34 @@ IntegerTimestampToTimestampTz(int64 timestamp)
#endif
/*
+ * GetSQLCurrentTimestamp -- implements CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n)
+ */
+TimestampTz
+GetSQLCurrentTimestamp(int32 typmod)
+{
+ TimestampTz ts;
+
+ ts = GetCurrentTransactionStartTimestamp();
+ if (typmod >= 0)
+ AdjustTimestampForTypmod(&ts, typmod);
+ return ts;
+}
+
+/*
+ * GetSQLLocalTimestamp -- implements LOCALTIMESTAMP, LOCALTIMESTAMP(n)
+ */
+Timestamp
+GetSQLLocalTimestamp(int32 typmod)
+{
+ Timestamp ts;
+
+ ts = timestamptz2timestamp(GetCurrentTransactionStartTimestamp());
+ if (typmod >= 0)
+ AdjustTimestampForTypmod(&ts, typmod);
+ return ts;
+}
+
+/*
* TimestampDifference -- convert the difference between two timestamps
* into integer seconds and microseconds
*
@@ -5415,6 +5452,13 @@ Datum
timestamptz_timestamp(PG_FUNCTION_ARGS)
{
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
+
+ PG_RETURN_TIMESTAMP(timestamptz2timestamp(timestamp));
+}
+
+static Timestamp
+timestamptz2timestamp(TimestampTz timestamp)
+{
Timestamp result;
struct pg_tm tt,
*tm = &tt;
@@ -5434,7 +5478,7 @@ timestamptz_timestamp(PG_FUNCTION_ARGS)
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
}
- PG_RETURN_TIMESTAMP(result);
+ return result;
}
/* timestamptz_zone()