On Jul 9, 2024, at 11:08, Junwang Zhao <zhjw...@gmail.com> wrote:

> In JsonbValue.val.datatime, there is a tz field, I think that's where
> the offset stored, it is 18000 in the first example
> 
> struct
> {
> Datum value;
> Oid typid;
> int32 typmod;
> int tz; /* Numeric time zone, in seconds, for
>          * TimestampTz data type */
> } datetime;

Oooh, okay, so it’s a jsonb variant of the type. Interesting. Ah, and it’s 
assigned here[1]:

  jb->val.datetime.tz = tz;

It seems like JSONB timestamptz values want to display the recorded time zone, 
so I suspect we need to set it when the converting from a non-tz to a local tz 
setting, something like this:

``` patch
diff --git a/src/backend/utils/adt/jsonpath_exec.c 
b/src/backend/utils/adt/jsonpath_exec.c
index d79c929822..f63b3b9330 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -2707,12 +2707,16 @@ executeDateTimeMethod(JsonPathExecContext *cxt, 
JsonPathItem *jsp,
                        break;
                case jpiTimestampTz:
                        {
+                               struct pg_tm *tm;
                                /* Convert result type to timestamp with time 
zone */
                                switch (typid)
                                {
                                        case DATEOID:
                                                
checkTimezoneIsUsedForCast(cxt->useTz,
                                                                                
                   "date", "timestamptz");
+                                               if 
(timestamp2tm(DatumGetTimestamp(value), NULL, tm, NULL, NULL, NULL) == 0) {
+                                                       tz = 
DetermineTimeZoneOffset(tm, session_timezone);
+                                               }
                                                value = 
DirectFunctionCall1(date_timestamptz,
                                                                                
                        value);
                                                break;
@@ -2726,6 +2730,9 @@ executeDateTimeMethod(JsonPathExecContext *cxt, 
JsonPathItem *jsp,
                                        case TIMESTAMPOID:
                                                
checkTimezoneIsUsedForCast(cxt->useTz,
                                                                                
                   "timestamp", "timestamptz");
+                                               if 
(timestamp2tm(DatumGetTimestamp(value), NULL, tm, NULL, NULL, NULL) == 0) {
+                                                       tz = 
DetermineTimeZoneOffset(tm, session_timezone);
+                                               }
                                                value = 
DirectFunctionCall1(timestamp_timestamptz,
                                                                                
                        value);
                                                break;
```

Only, you know, doesn’t crash the server.

Best,

David


[1]: 
https://github.com/postgres/postgres/blob/629520be5f9da9d0192c7f6c8796bfddb4746760/src/backend/utils/adt/jsonpath_exec.c#L2784




Reply via email to