1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-06 19:59:18 +03:00

Preserve tz when converting to jsonb timestamptz

This removes an inconsistency in the treatment of different datatypes by
the jsonpath timestamp_tz() function. Conversions from data types that
are not timestamp-aware, such as date and timestamp, are now treated
consistently with conversion from those that are such as timestamptz.

Author: David Wheeler
Reviewed-by: Junwang Zhao and Jeevan Chalke

Discussion: https://postgr.es/m/7DE080CE-6D8C-4794-9BD1-7D9699172FAB%40justatheory.com

Backpatch to release 17.
This commit is contained in:
Andrew Dunstan 2024-07-30 07:57:38 -04:00
parent 06ffce4559
commit 524d490a9f
2 changed files with 27 additions and 2 deletions

View File

@ -2707,12 +2707,27 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
break; break;
case jpiTimestampTz: case jpiTimestampTz:
{ {
struct pg_tm tm;
fsec_t fsec;
/* Convert result type to timestamp with time zone */ /* Convert result type to timestamp with time zone */
switch (typid) switch (typid)
{ {
case DATEOID: case DATEOID:
checkTimezoneIsUsedForCast(cxt->useTz, checkTimezoneIsUsedForCast(cxt->useTz,
"date", "timestamptz"); "date", "timestamptz");
/*
* Get the timezone value explicitly since JsonbValue
* keeps that separate.
*/
j2date(DatumGetDateADT(value) + POSTGRES_EPOCH_JDATE,
&(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
tz = DetermineTimeZoneOffset(&tm, session_timezone);
value = DirectFunctionCall1(date_timestamptz, value = DirectFunctionCall1(date_timestamptz,
value); value);
break; break;
@ -2726,6 +2741,16 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
case TIMESTAMPOID: case TIMESTAMPOID:
checkTimezoneIsUsedForCast(cxt->useTz, checkTimezoneIsUsedForCast(cxt->useTz,
"timestamp", "timestamptz"); "timestamp", "timestamptz");
/*
* Get the timezone value explicitly since JsonbValue
* keeps that separate.
*/
if (timestamp2tm(DatumGetTimestamp(value), NULL, &tm,
&fsec, NULL, NULL) == 0)
tz = DetermineTimeZoneOffset(&tm,
session_timezone);
value = DirectFunctionCall1(timestamp_timestamptz, value = DirectFunctionCall1(timestamp_timestamptz,
value); value);
break; break;

View File

@ -2964,7 +2964,7 @@ HINT: Use *_tz() function for time zone support.
select jsonb_path_query_tz('"2023-08-15"', '$.timestamp_tz()'); -- should work select jsonb_path_query_tz('"2023-08-15"', '$.timestamp_tz()'); -- should work
jsonb_path_query_tz jsonb_path_query_tz
----------------------------- -----------------------------
"2023-08-15T07:00:00+00:00" "2023-08-15T00:00:00-07:00"
(1 row) (1 row)
select jsonb_path_query('"12:34:56"', '$.timestamp_tz()'); select jsonb_path_query('"12:34:56"', '$.timestamp_tz()');
@ -3151,7 +3151,7 @@ HINT: Use *_tz() function for time zone support.
select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()'); -- should work select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()'); -- should work
jsonb_path_query_tz jsonb_path_query_tz
----------------------------- -----------------------------
"2023-08-15T02:34:56+00:00" "2023-08-15T12:34:56+10:00"
(1 row) (1 row)
select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()'); select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()');