On Tue, Jun 25, 2024 at 11:23 AM Amit Langote <amitlangot...@gmail.com> wrote:
>
> On Tue, Jun 25, 2024 at 12:18 PM jian he <jian.universal...@gmail.com> wrote:
> > On Mon, Jun 24, 2024 at 7:46 PM Amit Langote <amitlangot...@gmail.com> 
> > wrote:
> > > On Mon, Jun 24, 2024 at 7:04 PM jian he <jian.universal...@gmail.com> 
> > > wrote:
> > > >
> > > > hi.
> > > > the following two queries should return the same result?
> > > >
> > > > SELECT * FROM JSON_query (jsonb 'null', '$' returning jsonb);
> > > > SELECT * FROM JSON_value (jsonb 'null', '$' returning jsonb);
> > >
> > > I get this with HEAD:
> > >
> > > SELECT * FROM JSON_query (jsonb 'null', '$' returning jsonb);
> > >  json_query
> > > ------------
> > >  null
> > > (1 row)
> > >
> > > Time: 734.587 ms
> > > SELECT * FROM JSON_value (jsonb 'null', '$' returning jsonb);
> > >  json_value
> > > ------------
> > >
> > > (1 row)
> > >
> > > Much like:
> > >
> > > SELECT JSON_QUERY('{"key": null}', '$.key');
> > >  json_query
> > > ------------
> > >  null
> > > (1 row)
> > >
> > > Time: 2.975 ms
> > > SELECT JSON_VALUE('{"key": null}', '$.key');
> > >  json_value
> > > ------------
> > >
> > > (1 row)
> > >
> > > Which makes sense to me, because JSON_QUERY() is supposed to return a
> > > JSON null in both cases and JSON_VALUE() is supposed to return a SQL
> > > NULL for a JSON null.
> > >
> > > --
> > > Thanks, Amit Langote
> >
> > hi amit, sorry to bother you again.
>
> No worries.
>
> > My thoughts  for the above cases are:
> > * json_value, json_query main description is the same:
> > {{Returns the result of applying the SQL/JSON path_expression to the
> > context_item using the PASSING values.}}
> > same context_item, same path_expression, for the above cases, the
> > result should be the same?
> >
> > * in json_value, description
> > {{The extracted value must be a single SQL/JSON scalar item; an error
> > is thrown if that's not the case. If you expect that extracted value
> > might be an object or an array, use the json_query function instead.}}
> > query: `SELECT * FROM JSON_value (jsonb 'null', '$' returning jsonb);`
> > the returned jsonb 'null' (applying the path expression) is a single
> > SQL/JSON scalar item.
> > json_value return jsonb null should be fine
> >
> >
> > However, other database implementations return SQL null,
> > so I guess returning SQL null is fine)
> > (based on the doc explanation, returning jsonb null more make sense, imho)
>
> If the difference in behavior is not clear from the docs, I guess that
> means that we need to improve the docs.  Would you like to give a shot
> at writing the patch?
>

other databases did mention how json_value deals with  json null. eg.
[0] mysql description:
When the data at the specified path consists of or resolves to a JSON
null literal, the function returns SQL NULL.
[1] oracle description:
SQL/JSON function json_value applied to JSON value null returns SQL
NULL, not the SQL string 'null'. This means, in particular, that you
cannot use json_value to distinguish the JSON value null from the
absence of a value; SQL NULL indicates both cases.


imitate above, i come up with following:
"The extracted value must be a single SQL/JSON scalar item; an error
is thrown if that's not the case. ..."
to
"The extracted value must be a single SQL/JSON scalar item; an error
is thrown if that's not the case.
If the extracted value is a JSON null, an SQL NULL value will return.
This means that you cannot use json_value to distinguish the JSON
value null from evaluating path_expression yields no value at all; SQL
NULL indicates both cases, to distinguish these two cases, use
json_query instead.
"


I also changed from
ON EMPTY is not specified is to return a null value.
ON ERROR is not specified is to return a null value.
to
The default when ON EMPTY is not specified is to return an SQL NULL value.
The default when ON ERROR is not specified is to return an SQL NULL value.

[0] 
https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
[1]https://docs.oracle.com/en/database/oracle/oracle-database/19/adjsn/function-JSON_VALUE.html#GUID-622170D8-7BAD-4F5F-86BF-C328451FC3BE
From dbc50acce12efcd25e7c55c51609e125e1545439 Mon Sep 17 00:00:00 2001
From: jian he <jian.universal...@gmail.com>
Date: Tue, 25 Jun 2024 12:35:40 +0800
Subject: [PATCH v1 1/1] document how json_value dealing with jsonb 'null'

---
 doc/src/sgml/func.sgml | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 26092696..f6ec96ae 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -18772,7 +18772,7 @@ ERROR:  jsonpath array subscript is out of bounds
         The <literal>ON EMPTY</literal> clause specifies the behavior if
         evaluating <replaceable>path_expression</replaceable> yields no value
         at all. The default when <literal>ON EMPTY</literal> is not specified
-        is to return a null value.
+        is to return an SQL <literal>NULL</literal> value.
        </para>
        <para>
         The <literal>ON ERROR</literal> clause specifies the
@@ -18781,7 +18781,7 @@ ERROR:  jsonpath array subscript is out of bounds
         coerce the result value to the output type, or during the execution of
         <literal>ON EMPTY</literal> behavior (that is caused by empty result
         of <replaceable>path_expression</replaceable> evaluation).  The default
-        when <literal>ON ERROR</literal> is not specified is to return a null
+        when <literal>ON ERROR</literal> is not specified is to return an SQL <literal>NULL</literal>
         value.
        </para>
        <para>
@@ -18823,8 +18823,13 @@ DETAIL:  Missing "]" after array dimensions.
        </para>
        <para>
         The extracted value must be a single <acronym>SQL/JSON</acronym>
-        scalar item; an error is thrown if that's not the case.  If you expect
-        that extracted value might be an object or an array, use the
+        scalar item; an error is thrown if that's not the case.
+        If the extracted value is a JSON null, an SQL <literal>NULL</literal> value will return.
+        This means that you cannot use <function>json_value</function> to distinguish the JSON value null
+        from evaluating path_expression yields no value at all;
+        SQL <literal>NULL</literal> indicates both cases,
+        to distinguish these two cases, use <function>json_query</function> instead.
+        If you expect that extracted value might be an object or an array, use the
         <function>json_query</function> function instead.
        </para>
        <para>
-- 
2.34.1

Reply via email to