@@ -2042,7 +2042,6 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
2042
2042
{
2043
2043
JsonbValue jbvbuf ;
2044
2044
Datum value ;
2045
- text * datetime ;
2046
2045
Oid typid ;
2047
2046
int32 typmod = -1 ;
2048
2047
int tz ;
@@ -2053,84 +2052,113 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
2053
2052
2054
2053
res = jperMakeError (ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION );
2055
2054
2056
- if (jb -> type != jbvString )
2057
- break ;
2055
+ if (jb -> type == jbvNumeric && !jsp -> content .args .left )
2056
+ {
2057
+ /* Standard extension: unix epoch to timestamptz */
2058
+ MemoryContext mcxt = CurrentMemoryContext ;
2058
2059
2059
- datetime = cstring_to_text_with_len (jb -> val .string .val ,
2060
- jb -> val .string .len );
2060
+ PG_TRY ();
2061
+ {
2062
+ Datum unix_epoch =
2063
+ DirectFunctionCall1 (numeric_float8 ,
2064
+ NumericGetDatum (jb -> val .numeric ));
2065
+
2066
+ value = DirectFunctionCall1 (float8_timestamptz ,
2067
+ unix_epoch );
2068
+ typid = TIMESTAMPTZOID ;
2069
+ tz = 0 ;
2070
+ res = jperOk ;
2071
+ }
2072
+ PG_CATCH ();
2073
+ {
2074
+ if (ERRCODE_TO_CATEGORY (geterrcode ()) !=
2075
+ ERRCODE_DATA_EXCEPTION )
2076
+ PG_RE_THROW ();
2061
2077
2062
- if (jsp -> content .args .left )
2078
+ FlushErrorState ();
2079
+ MemoryContextSwitchTo (mcxt );
2080
+ }
2081
+ PG_END_TRY ();
2082
+ }
2083
+ else if (jb -> type == jbvString )
2063
2084
{
2064
- char * template_str ;
2065
- int template_len ;
2066
- char * tzname = NULL ;
2085
+ text * datetime =
2086
+ cstring_to_text_with_len ( jb -> val . string . val ,
2087
+ jb -> val . string . len ) ;
2067
2088
2068
- jspGetLeftArg (jsp , & elem );
2089
+ if (jsp -> content .args .left )
2090
+ {
2091
+ char * template_str ;
2092
+ int template_len ;
2093
+ char * tzname = NULL ;
2069
2094
2070
- if (elem .type != jpiString )
2071
- elog (ERROR , "invalid jsonpath item type for .datetime() argument" );
2095
+ jspGetLeftArg (jsp , & elem );
2072
2096
2073
- template_str = jspGetString (& elem , & template_len );
2097
+ if (elem .type != jpiString )
2098
+ elog (ERROR , "invalid jsonpath item type for .datetime() argument" );
2074
2099
2075
- if (jsp -> content .args .right )
2076
- {
2077
- JsonValueList tzlist = { 0 };
2078
- JsonPathExecResult tzres ;
2079
- JsonbValue * tzjbv ;
2100
+ template_str = jspGetString (& elem , & template_len );
2080
2101
2081
- jspGetRightArg (jsp , & elem );
2082
- tzres = recursiveExecuteNoUnwrap (cxt , & elem , jb ,
2083
- & tzlist );
2102
+ if (jsp -> content .args .right )
2103
+ {
2104
+ JsonValueList tzlist = { 0 };
2105
+ JsonPathExecResult tzres ;
2106
+ JsonbValue * tzjbv ;
2084
2107
2085
- if (jperIsError (tzres ))
2086
- return tzres ;
2108
+ jspGetRightArg (jsp , & elem );
2109
+ tzres = recursiveExecuteNoUnwrap (cxt , & elem , jb ,
2110
+ & tzlist );
2087
2111
2088
- if (JsonValueListLength ( & tzlist ) != 1 )
2089
- break ;
2112
+ if (jperIsError ( tzres ) )
2113
+ return tzres ;
2090
2114
2091
- tzjbv = JsonValueListHead (& tzlist );
2115
+ if (JsonValueListLength (& tzlist ) != 1 )
2116
+ break ;
2092
2117
2093
- if (tzjbv -> type != jbvString )
2094
- break ;
2118
+ tzjbv = JsonValueListHead (& tzlist );
2095
2119
2096
- tzname = pnstrdup (tzjbv -> val .string .val ,
2097
- tzjbv -> val .string .len );
2098
- }
2120
+ if (tzjbv -> type != jbvString )
2121
+ break ;
2099
2122
2100
- if (tryToParseDatetime (template_str , template_len , datetime ,
2101
- tzname , false,
2102
- & value , & typid , & typmod , & tz ))
2103
- res = jperOk ;
2123
+ tzname = pnstrdup (tzjbv -> val .string .val ,
2124
+ tzjbv -> val .string .len );
2125
+ }
2104
2126
2105
- if (tzname )
2106
- pfree (tzname );
2107
- }
2108
- else
2109
- {
2110
- const char * templates [] = {
2111
- "yyyy-mm-dd HH24:MI:SS TZH:TZM" ,
2112
- "yyyy-mm-dd HH24:MI:SS TZH" ,
2113
- "yyyy-mm-dd HH24:MI:SS" ,
2114
- "yyyy-mm-dd" ,
2115
- "HH24:MI:SS TZH:TZM" ,
2116
- "HH24:MI:SS TZH" ,
2117
- "HH24:MI:SS"
2118
- };
2119
- int i ;
2120
-
2121
- for (i = 0 ; i < sizeof (templates ) / sizeof (* templates ); i ++ )
2127
+ if (tryToParseDatetime (template_str , template_len ,
2128
+ datetime , tzname , false,
2129
+ & value , & typid , & typmod , & tz ))
2130
+ res = jperOk ;
2131
+
2132
+ if (tzname )
2133
+ pfree (tzname );
2134
+ }
2135
+ else
2122
2136
{
2123
- if (tryToParseDatetime (templates [i ], -1 , datetime ,
2124
- NULL , true, & value , & typid ,
2125
- & typmod , & tz ))
2137
+ const char * templates [] = {
2138
+ "yyyy-mm-dd HH24:MI:SS TZH:TZM" ,
2139
+ "yyyy-mm-dd HH24:MI:SS TZH" ,
2140
+ "yyyy-mm-dd HH24:MI:SS" ,
2141
+ "yyyy-mm-dd" ,
2142
+ "HH24:MI:SS TZH:TZM" ,
2143
+ "HH24:MI:SS TZH" ,
2144
+ "HH24:MI:SS"
2145
+ };
2146
+ int i ;
2147
+
2148
+ for (i = 0 ; i < sizeof (templates ) / sizeof (* templates ); i ++ )
2126
2149
{
2127
- res = jperOk ;
2128
- break ;
2150
+ if (tryToParseDatetime (templates [i ], -1 , datetime ,
2151
+ NULL , true, & value , & typid ,
2152
+ & typmod , & tz ))
2153
+ {
2154
+ res = jperOk ;
2155
+ break ;
2156
+ }
2129
2157
}
2130
2158
}
2131
- }
2132
2159
2133
- pfree (datetime );
2160
+ pfree (datetime );
2161
+ }
2134
2162
2135
2163
if (jperIsError (res ))
2136
2164
break ;
0 commit comments