Commit 26ae3aa8 authored by Tom Lane's avatar Tom Lane

Remove redundant function calls in timestamp[tz]_part().

The DTK_DOW/DTK_ISODOW and DTK_DOY switch cases in timestamp_part() and
timestamptz_part() contained calls of timestamp2tm() that were fully
redundant with the ones done just above the switch.  This evidently crept
in during commit 258ee1b6, which relocated that code from another place
where the calls were indeed needed.  Just delete the redundant calls.

I (tgl) noted that our test coverage of these functions left quite a
bit to be desired, so extend timestamp.sql and timestamptz.sql to
cover all the branches.

Back-patch to all supported branches, as the previous commit was.
There's no real issue here other than some wasted cycles in some
not-too-heavily-used code paths, but the test coverage seems valuable.

Report and patch by Li Japin; test case adjustments by me.

Discussion: https://postgr.es/m/SG2PR06MB37762CAE45DB0F6CA7001EA9B6550@SG2PR06MB3776.apcprd06.prod.outlook.com
parent 8ed428dc
...@@ -4651,20 +4651,12 @@ timestamp_part(PG_FUNCTION_ARGS) ...@@ -4651,20 +4651,12 @@ timestamp_part(PG_FUNCTION_ARGS)
case DTK_DOW: case DTK_DOW:
case DTK_ISODOW: case DTK_ISODOW:
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
if (val == DTK_ISODOW && result == 0) if (val == DTK_ISODOW && result == 0)
result = 7; result = 7;
break; break;
case DTK_DOY: case DTK_DOY:
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1); - date2j(tm->tm_year, 1, 1) + 1);
break; break;
...@@ -4855,20 +4847,12 @@ timestamptz_part(PG_FUNCTION_ARGS) ...@@ -4855,20 +4847,12 @@ timestamptz_part(PG_FUNCTION_ARGS)
case DTK_DOW: case DTK_DOW:
case DTK_ISODOW: case DTK_ISODOW:
if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
if (val == DTK_ISODOW && result == 0) if (val == DTK_ISODOW && result == 0)
result = 7; result = 7;
break; break;
case DTK_DOY: case DTK_DOY:
if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
- date2j(tm->tm_year, 1, 1) + 1); - date2j(tm->tm_year, 1, 1) + 1);
break; break;
......
This diff is collapsed.
This diff is collapsed.
...@@ -174,21 +174,30 @@ SELECT '' AS "54", d1 - timestamp without time zone '1997-01-02' AS diff ...@@ -174,21 +174,30 @@ SELECT '' AS "54", d1 - timestamp without time zone '1997-01-02' AS diff
WHERE d1 BETWEEN timestamp without time zone '1902-01-01' WHERE d1 BETWEEN timestamp without time zone '1902-01-01'
AND timestamp without time zone '2038-01-01'; AND timestamp without time zone '2038-01-01';
SELECT '' AS "54", d1 as "timestamp", -- DATE_PART (timestamp_part)
SELECT d1 as "timestamp",
date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, date_part( 'year', d1) AS year, date_part( 'month', d1) AS month,
date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour,
date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second
FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; FROM TIMESTAMP_TBL;
SELECT '' AS "54", d1 as "timestamp", SELECT d1 as "timestamp",
date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec,
date_part( 'usec', d1) AS usec date_part( 'usec', d1) AS usec
FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; FROM TIMESTAMP_TBL;
SELECT '' AS "54", d1 as "timestamp", SELECT d1 as "timestamp",
date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
date_part( 'dow', d1) AS dow date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow,
FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; date_part( 'doy', d1) AS doy
FROM TIMESTAMP_TBL;
SELECT d1 as "timestamp",
date_part( 'decade', d1) AS decade,
date_part( 'century', d1) AS century,
date_part( 'millennium', d1) AS millennium,
round(date_part( 'julian', d1)) AS julian
FROM TIMESTAMP_TBL;
-- TO_CHAR() -- TO_CHAR()
SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon')
......
...@@ -198,21 +198,36 @@ SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff ...@@ -198,21 +198,36 @@ SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff
FROM TIMESTAMPTZ_TBL FROM TIMESTAMPTZ_TBL
WHERE d1 BETWEEN timestamp with time zone '1902-01-01' AND timestamp with time zone '2038-01-01'; WHERE d1 BETWEEN timestamp with time zone '1902-01-01' AND timestamp with time zone '2038-01-01';
SELECT '' AS "54", d1 as timestamptz, -- DATE_PART (timestamptz_part)
SELECT d1 as timestamptz,
date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, date_part( 'year', d1) AS year, date_part( 'month', d1) AS month,
date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour,
date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second
FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; FROM TIMESTAMPTZ_TBL;
SELECT '' AS "54", d1 as timestamptz, SELECT d1 as timestamptz,
date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec,
date_part( 'usec', d1) AS usec date_part( 'usec', d1) AS usec
FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; FROM TIMESTAMPTZ_TBL;
SELECT '' AS "54", d1 as timestamptz, SELECT d1 as timestamptz,
date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
date_part( 'dow', d1) AS dow date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow,
FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; date_part( 'doy', d1) AS doy
FROM TIMESTAMPTZ_TBL;
SELECT d1 as timestamptz,
date_part( 'decade', d1) AS decade,
date_part( 'century', d1) AS century,
date_part( 'millennium', d1) AS millennium,
round(date_part( 'julian', d1)) AS julian
FROM TIMESTAMPTZ_TBL;
SELECT d1 as timestamptz,
date_part( 'timezone', d1) AS timezone,
date_part( 'timezone_hour', d1) AS timezone_hour,
date_part( 'timezone_minute', d1) AS timezone_minute
FROM TIMESTAMPTZ_TBL;
-- TO_CHAR() -- TO_CHAR()
SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment