v6-0015-error-safe-for-casting-timestamp-to-other-types-per-pg_ca.patch
text/x-patch
Filename: v6-0015-error-safe-for-casting-timestamp-to-other-types-per-pg_ca.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v6-0015
Subject: error safe for casting timestamp to other types per pg_cast
| File | + | − |
|---|---|---|
| src/backend/utils/adt/date.c | 11 | 2 |
| src/backend/utils/adt/timestamp.c | 15 | 2 |
From b1cd2195beefa7a4995dcb2ec8a390ff99ca7c4d Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Sun, 10 Aug 2025 01:33:36 +0800
Subject: [PATCH v6 15/18] error safe for casting timestamp to other types per
pg_cast
select castsource::regtype, casttarget::regtype, castfunc, castcontext,castmethod, pp.prosrc, pp.proname
from pg_cast pc join pg_proc pp on pp.oid = pc.castfunc
and pc.castfunc > 0 and (castsource::regtype ='timestamp'::regtype)
order by castsource::regtype;
castsource | casttarget | castfunc | castcontext | castmethod | prosrc | proname
-----------------------------+-----------------------------+----------+-------------+------------+-----------------------+-------------
timestamp without time zone | date | 2029 | a | f | timestamp_date | date
timestamp without time zone | time without time zone | 1316 | a | f | timestamp_time | time
timestamp without time zone | timestamp with time zone | 2028 | i | f | timestamp_timestamptz | timestamptz
timestamp without time zone | timestamp without time zone | 1961 | i | f | timestamp_scale | timestamp
(4 rows)
---
src/backend/utils/adt/date.c | 13 +++++++++++--
src/backend/utils/adt/timestamp.c | 17 +++++++++++++++--
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 111bfd8f519..c5562b563e5 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -1373,7 +1373,16 @@ timestamp_date(PG_FUNCTION_ARGS)
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
DateADT result;
- result = timestamp2date_opt_overflow(timestamp, NULL);
+ if (likely(!fcinfo->context))
+ result = timestamptz2date_opt_overflow(timestamp, NULL);
+ else
+ {
+ int overflow;
+ result = timestamp2date_opt_overflow(timestamp, &overflow);
+
+ if (overflow != 0)
+ PG_RETURN_NULL();
+ }
PG_RETURN_DATEADT(result);
}
@@ -2089,7 +2098,7 @@ timestamp_time(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
- ereport(ERROR,
+ ereturn(fcinfo->context, (Datum) 0,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 8648a16db7f..b40dfd224d2 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -352,7 +352,8 @@ timestamp_scale(PG_FUNCTION_ARGS)
result = timestamp;
- AdjustTimestampForTypmod(&result, typmod, NULL);
+ if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
+ PG_RETURN_NULL();
PG_RETURN_TIMESTAMP(result);
}
@@ -6451,7 +6452,19 @@ timestamp_timestamptz(PG_FUNCTION_ARGS)
{
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
- PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(timestamp));
+ if (likely(!fcinfo->context))
+ PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(timestamp));
+ else
+ {
+ TimestampTz result;
+ int overflow;
+
+ result = timestamp2timestamptz_opt_overflow(timestamp, &overflow);
+ if (overflow != 0)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_TIMESTAMPTZ(result);
+ }
}
/*
--
2.34.1