On 6/17/19 11:36 AM, Alexander Korotkov wrote:
I'm going to push attached 3 patches if no objections.
Regarding 0003-Separate-two-distinctive-json-errors.patch, I think it
requires more thoughts.
RETURN_ERROR(ereport(ERROR,
(errcode(ERRCODE_SINGLETON_JSON_ITEM_REQUIRED),
errmsg("left operand of jsonpath
operator %s is not a single numeric value",
- jspOperationName(jsp->type)))));
+ jspOperationName(jsp->type)),
+ (llen != 1 ?
+ errdetail("It was an array with %d
elements.", llen):
+ errdetail("The only element was not a
numeric.")))));
When we have more than 1 value, it's no exactly array. Jsonpath can
extract values from various parts of json document, which never
constitute and array. Should we say something like "There are %d
values"? Also, probably we should display the type of single element
if it's not numeric. jsonb_path_match() also throws
ERRCODE_SINGLETON_JSON_ITEM_REQUIRED, should we add similar
errdetail() there?
------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Hi Alexander,
While I have no objections to the proposed fixes, I think we can further
improve patch 0003 and the text it refers to.
In attempt to clarify jsonpath docs and address the concern that ? is
hard to trace in the current text, I'd also like to propose patch 0004.
Please see both of them attached.
--
Liudmila Mantrova
Technical writer at Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index e918133..39ba18d 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -12281,7 +12281,7 @@ table2-mapping
<row>
<entry><literal>@?</literal></entry>
<entry><type>jsonpath</type></entry>
- <entry>Does JSON path returns any item for the specified JSON value?</entry>
+ <entry>Does JSON path return any item for the specified JSON value?</entry>
<entry><literal>'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)'</literal></entry>
</row>
<row>
@@ -12309,8 +12309,8 @@ table2-mapping
<note>
<para>
The <literal>@?</literal> and <literal>@@</literal> operators suppress
- errors including: lacking object field or array element, unexpected JSON
- item type and numeric errors.
+ the following errors: lacking object field or array element, unexpected
+ JSON item type, and numeric errors.
This behavior might be helpful while searching over JSON document
collections of varying structure.
</para>
@@ -13166,26 +13166,25 @@ table2-mapping
<literal>jsonb_path_query</literal>, <literal>jsonb_path_query_array</literal> and
<literal>jsonb_path_query_first</literal>
functions have optional <literal>vars</literal> and <literal>silent</literal>
- argument.
+ arguments.
</para>
<para>
- When <literal>vars</literal> argument is specified, it constitutes an object
- contained variables to be substituted into <literal>jsonpath</literal>
- expression.
+ If the <literal>vars</literal> argument is specified, it provides an
+ object containing named variables to be substituted into a
+ <literal>jsonpath</literal> expression.
</para>
<para>
- When <literal>silent</literal> argument is specified and has
- <literal>true</literal> value, the same errors are suppressed as it is in
- the <literal>@?</literal> and <literal>@@</literal> operators.
+ If the <literal>silent</literal> argument is specified and has the
+ <literal>true</literal> value, these functions suppress the same errors
+ as the <literal>@?</literal> and <literal>@@</literal> operators.
</para>
</note>
<para>
- See also <xref linkend="functions-aggregate"/> for the aggregate
- function <function>json_agg</function> which aggregates record
- values as JSON, and the aggregate function
- <function>json_object_agg</function> which aggregates pairs of values
- into a JSON object, and their <type>jsonb</type> equivalents,
+ See also <xref linkend="functions-aggregate"/> for details on
+ <function>json_agg</function> function that aggregates record
+ values as JSON, <function>json_object_agg</function> function
+ that aggregates pairs of values into a JSON object, and their <type>jsonb</type> equivalents,
<function>jsonb_agg</function> and <function>jsonb_object_agg</function>.
</para>
diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml
index b8246ba..daebb4f 100644
--- a/doc/src/sgml/json.sgml
+++ b/doc/src/sgml/json.sgml
@@ -733,10 +733,12 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
</row>
<row>
<entry><literal>$varname</literal></entry>
- <entry>A named variable. Its value must be set in the
- <command>PASSING</command> clause of an SQL/JSON query function.
- <!-- TBD: See <xref linkend="sqljson-input-clause"/> -->
- for details.
+ <entry>
+ A named variable. Its value can be set by the parameter
+ <parameter>vars</parameter> of several JSON processing functions.
+ See <xref linkend="functions-json-processing-table"/> and
+ its notes for details.
+ <!-- TODO: describe PASSING clause once implemented !-->
</entry>
</row>
<row>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 39ba18d..fa5afc1 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -11638,10 +11638,17 @@ table2-mapping
<para>
When defining the path, you can also use one or more
<firstterm>filter expressions</firstterm>, which work similar to
- the <literal>WHERE</literal> clause in SQL. Each filter expression
- can provide one or more filtering conditions that are applied
- to the result of the path evaluation. Each filter expression must
- be enclosed in parentheses and preceded by a question mark.
+ the <literal>WHERE</literal> clause in SQL. A filter expression must
+ be enclosed in parentheses and preceded by a question mark:
+
+ <programlisting>
+? (@ <replaceable>filter</replaceable> ...)
+ </programlisting>
+ </para>
+
+ <para>
+ Each filter expression can provide one or more filters
+ that are applied to the result of the path evaluation.
Filter expressions are evaluated from left to right and can be nested.
The <literal>@</literal> variable denotes the current path evaluation
result to be filtered, and can be followed by one or more accessor
diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml
index daebb4f..55286a6 100644
--- a/doc/src/sgml/json.sgml
+++ b/doc/src/sgml/json.sgml
@@ -815,21 +815,18 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
<literal>.**{<replaceable>level</replaceable>}</literal>
</para>
<para>
- <literal>.**{<replaceable>lower_level</replaceable> to
- <replaceable>upper_level</replaceable>}</literal>
- </para>
- <para>
- <literal>.**{<replaceable>lower_level</replaceable> to
- last}</literal>
+ <literal>.**{<replaceable>start_level</replaceable> to
+ <replaceable>end_level</replaceable>}</literal>
</para>
</entry>
<entry>
<para>
- Same as <literal>.**</literal>, but with filter over nesting
- level of JSON hierarchy. Levels are specified as integers.
- Zero level corresponds to current object. This is a
- <productname>PostgreSQL</productname> extension of the SQL/JSON
- standard.
+ Same as <literal>.**</literal>, but with a filter over nesting
+ levels of JSON hierarchy. Nesting levels are specified as integers.
+ Zero level corresponds to the current object. To access the lowest
+ nesting level, you can use the <literal>last</literal> keyword.
+ This is a <productname>PostgreSQL</productname> extension of
+ the SQL/JSON standard.
</para>
</entry>
</row>
@@ -841,19 +838,22 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
</entry>
<entry>
<para>
- Array element accessor. <literal><replaceable>subscript</replaceable></literal>
- might be given in two forms: <literal><replaceable>expr</replaceable></literal>
- or <literal><replaceable>lower_expr</replaceable> to <replaceable>upper_expr</replaceable></literal>.
- The first form specifies single array element by its index. The second
- form specified array slice by the range of indexes. Zero index
- corresponds to the first array element.
+ Array element accessor.
+ <literal><replaceable>subscript</replaceable></literal> can be
+ given in two forms: <literal><replaceable>index</replaceable></literal>
+ or <literal><replaceable>start_index</replaceable> to <replaceable>end_index</replaceable></literal>.
+ The first form returns a single array element by its index. The second
+ form returns an array slice by the range of indexes, including the
+ elements that correspond to the provided
+ <replaceable>start_index</replaceable> and <replaceable>end_index</replaceable>.
</para>
<para>
- Expression inside subscript may consititue an integer,
- numeric expression or any other <literal>jsonpath</literal> expression
- returning single numeric value. The <literal>last</literal> keyword
- can be used in the expression denoting the last subscript in an array.
- That's helpful for handling arrays of unknown length.
+ The specified <replaceable>index</replaceable> can be an integer,
+ as well as a numeric or <literal>jsonpath</literal> expression that
+ returns a single integer value. Zero index corresponds to the first
+ array element. To access the last element in an array, you can use
+ the <literal>last</literal> keyword, which is useful for handling
+ arrays of unknown length.
</para>
</entry>
</row>