mirror of https://github.com/postgres/postgres
Make jsonpath .string() be immutable for datetimes.
Discussion of commited055d249
revealed that we don't actually want jsonpath's .string() method to depend on DateStyle, nor TimeZone either, because the non-"_tz" jsonpath functions are supposed to be immutable. Potentially we could allow a TimeZone dependency in the "_tz" variants, but it seems better to just uniformly define this method as returning the same string that jsonb text output would do. That's easier to implement too, saving a couple dozen lines. Patch by me, per complaint from Peter Eisentraut. Back-patch to v17 where this feature came in (in66ea94e8e
). Also back-patched055d249
to provide test cases. Discussion: https://postgr.es/m/5e8879d0-a3c8-4be2-950f-d83aa2af953a@eisentraut.org
This commit is contained in:
parent
4eada203a5
commit
cb599b9ddf
|
@ -18017,16 +18017,15 @@ ERROR: jsonpath member accessor can only be applied to an object
|
|||
</para>
|
||||
<para>
|
||||
String value converted from a JSON boolean, number, string, or
|
||||
datetime (the output format for datetimes is determined by
|
||||
the <xref linkend="guc-datestyle"/> parameter)
|
||||
datetime
|
||||
</para>
|
||||
<para>
|
||||
<literal>jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()')</literal>
|
||||
<returnvalue>["1.23", "xyz", "false"]</returnvalue>
|
||||
</para>
|
||||
<para>
|
||||
<literal>jsonb_path_query('"2023-08-15"', '$.datetime().string()')</literal>
|
||||
<returnvalue>"2023-08-15"</returnvalue>
|
||||
<literal>jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()')</literal>
|
||||
<returnvalue>"2023-08-15T12:34:56"</returnvalue>
|
||||
</para></entry>
|
||||
</row>
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "utils/datetime.h"
|
||||
#include "utils/float.h"
|
||||
#include "utils/formatting.h"
|
||||
#include "utils/json.h"
|
||||
#include "utils/jsonpath.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
|
@ -1629,32 +1630,13 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
|
|||
break;
|
||||
case jbvDatetime:
|
||||
{
|
||||
switch (jb->val.datetime.typid)
|
||||
{
|
||||
case DATEOID:
|
||||
tmp = DatumGetCString(DirectFunctionCall1(date_out,
|
||||
jb->val.datetime.value));
|
||||
break;
|
||||
case TIMEOID:
|
||||
tmp = DatumGetCString(DirectFunctionCall1(time_out,
|
||||
jb->val.datetime.value));
|
||||
break;
|
||||
case TIMETZOID:
|
||||
tmp = DatumGetCString(DirectFunctionCall1(timetz_out,
|
||||
jb->val.datetime.value));
|
||||
break;
|
||||
case TIMESTAMPOID:
|
||||
tmp = DatumGetCString(DirectFunctionCall1(timestamp_out,
|
||||
jb->val.datetime.value));
|
||||
break;
|
||||
case TIMESTAMPTZOID:
|
||||
tmp = DatumGetCString(DirectFunctionCall1(timestamptz_out,
|
||||
jb->val.datetime.value));
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
|
||||
jb->val.datetime.typid);
|
||||
}
|
||||
char buf[MAXDATELEN + 1];
|
||||
|
||||
JsonEncodeDateTime(buf,
|
||||
jb->val.datetime.value,
|
||||
jb->val.datetime.typid,
|
||||
&jb->val.datetime.tz);
|
||||
tmp = pstrdup(buf);
|
||||
}
|
||||
break;
|
||||
case jbvNull:
|
||||
|
|
|
@ -2653,8 +2653,8 @@ ERROR: cannot convert value from timestamptz to timestamp without time zone usa
|
|||
HINT: Use *_tz() function for time zone support.
|
||||
select jsonb_path_query_tz('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()'); -- should work
|
||||
jsonb_path_query_tz
|
||||
----------------------------
|
||||
"Tue Aug 15 00:04:56 2023"
|
||||
-----------------------
|
||||
"2023-08-15T00:04:56"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz().string()');
|
||||
|
@ -2662,63 +2662,20 @@ ERROR: cannot convert value from timestamp to timestamptz without time zone usa
|
|||
HINT: Use *_tz() function for time zone support.
|
||||
select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()'); -- should work
|
||||
jsonb_path_query_tz
|
||||
--------------------------------
|
||||
"Tue Aug 15 12:34:56 2023 PDT"
|
||||
-----------------------------
|
||||
"2023-08-15T12:34:56-07:00"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()');
|
||||
jsonb_path_query
|
||||
--------------------------------
|
||||
"Tue Aug 15 00:04:56 2023 PDT"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()');
|
||||
jsonb_path_query
|
||||
----------------------------
|
||||
"Tue Aug 15 12:34:56 2023"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()');
|
||||
jsonb_path_query
|
||||
------------------
|
||||
"12:34:56+05:30"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()');
|
||||
jsonb_path_query_tz
|
||||
---------------------
|
||||
"12:34:56-07"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"12:34:56"', '$.time().string()');
|
||||
jsonb_path_query
|
||||
------------------
|
||||
"12:34:56"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15"', '$.date().string()');
|
||||
jsonb_path_query
|
||||
------------------
|
||||
"08-15-2023"
|
||||
(1 row)
|
||||
|
||||
set datestyle = 'ISO';
|
||||
select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()');
|
||||
jsonb_path_query_tz
|
||||
--------------------------
|
||||
"2023-08-15 12:34:56-07"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()');
|
||||
jsonb_path_query
|
||||
--------------------------
|
||||
"2023-08-15 00:04:56-07"
|
||||
-----------------------------
|
||||
"2023-08-15T12:34:56+05:30"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()');
|
||||
jsonb_path_query
|
||||
-----------------------
|
||||
"2023-08-15 12:34:56"
|
||||
"2023-08-15T12:34:56"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()');
|
||||
|
@ -2730,7 +2687,7 @@ select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()');
|
|||
select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()');
|
||||
jsonb_path_query_tz
|
||||
---------------------
|
||||
"12:34:56-07"
|
||||
"12:34:56-07:00"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"12:34:56"', '$.time().string()');
|
||||
|
@ -2745,7 +2702,23 @@ select jsonb_path_query('"2023-08-15"', '$.date().string()');
|
|||
"2023-08-15"
|
||||
(1 row)
|
||||
|
||||
reset datestyle;
|
||||
-- .string() does not react to timezone or datestyle
|
||||
begin;
|
||||
set local timezone = 'UTC';
|
||||
set local datestyle = 'German';
|
||||
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()');
|
||||
jsonb_path_query
|
||||
-----------------------------
|
||||
"2023-08-15T12:34:56+05:30"
|
||||
(1 row)
|
||||
|
||||
select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()');
|
||||
jsonb_path_query
|
||||
-----------------------
|
||||
"2023-08-15T12:34:56"
|
||||
(1 row)
|
||||
|
||||
rollback;
|
||||
-- Test .time()
|
||||
select jsonb_path_query('null', '$.time()');
|
||||
ERROR: jsonpath item method .time() can only be applied to a string
|
||||
|
|
|
@ -611,15 +611,13 @@ select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()');
|
|||
select jsonb_path_query('"12:34:56"', '$.time().string()');
|
||||
select jsonb_path_query('"2023-08-15"', '$.date().string()');
|
||||
|
||||
set datestyle = 'ISO';
|
||||
select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()');
|
||||
-- .string() does not react to timezone or datestyle
|
||||
begin;
|
||||
set local timezone = 'UTC';
|
||||
set local datestyle = 'German';
|
||||
select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()');
|
||||
select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()');
|
||||
select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()');
|
||||
select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()');
|
||||
select jsonb_path_query('"12:34:56"', '$.time().string()');
|
||||
select jsonb_path_query('"2023-08-15"', '$.date().string()');
|
||||
reset datestyle;
|
||||
rollback;
|
||||
|
||||
-- Test .time()
|
||||
select jsonb_path_query('null', '$.time()');
|
||||
|
|
Loading…
Reference in New Issue