On 7/3/19 11:59 PM, Alexander Korotkov wrote:
Hi!

On Wed, Jul 3, 2019 at 5:27 PM Liudmila Mantrova
<l.mantr...@postgrespro.ru> wrote:
I have rechecked the standard and I agree that we should use "filter
expression" whenever possible.
"A filter expression must be enclosed in parentheses..." looks like an
oversight, so I fixed it. As for what's actually enclosed, I believe we
can still use the word "condition" here as it's easy to understand and
is already used in our docs, e.g. in description of the WHERE clause
that serves a similar purpose.
The new version of the patch fixes the terminology, tweaks the examples,
and provides some grammar and style fixes in the jsonpath-related chapters.

It looks good to me.  But this sentence looks a bit too complicated.

"It can be followed by one or more accessor operators to define the
JSON element on a lower nesting level by which to filter the result."

Could we phrase this as following?

"In order to filter the result by values lying on lower nesting level,
@ operator can be followed by one or more accessor operators."

------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

ThankĀ  you!

I think we can make this sentence even shorter, the fix is attached:

"To refer to a JSON element stored at a lower nesting level, add one or more accessor operators after <literal>@</literal>."


--
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 3a8581d..6d2aefb 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -11538,7 +11538,8 @@ table2-mapping
    from the JSON data, similar to XPath expressions used
    for SQL access to XML. In <productname>PostgreSQL</productname>,
    path expressions are implemented as the <type>jsonpath</type>
-   data type, described in <xref linkend="datatype-jsonpath"/>.
+   data type and can use any elements described in
+   <xref linkend="datatype-jsonpath"/>.
   </para>
 
   <para>JSON query functions and operators
@@ -11585,7 +11586,7 @@ table2-mapping
       },
       { "location":   [ 47.706, 13.2635 ],
         "start time": "2018-10-14 10:39:21",
-        "HR": 130
+        "HR": 135
       } ]
   }
 }
@@ -11637,23 +11638,33 @@ 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.
-   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
-   operators to define the JSON element by which to filter the result.
-   Functions and operators that can be used in the filtering condition
-   are listed in <xref linkend="functions-sqljson-filter-ex-table"/>.
-   SQL/JSON defines three-valued logic, so the result of the filter
-   expression may be <literal>true</literal>, <literal>false</literal>,
+   <firstterm>filter expressions</firstterm> that work similar to the
+   <literal>WHERE</literal> clause in SQL. A filter expression begins with
+   a question mark and provides a condition in parentheses:
+
+    <programlisting>
+? (<replaceable>condition</replaceable>)
+    </programlisting>
+  </para>
+
+  <para>
+   Filter expressions must be specified right after the path evaluation step
+   to which they are applied. The result of this step is filtered to include
+   only those items that satisfy the provided condition. SQL/JSON defines
+   three-valued logic, so the condition can be <literal>true</literal>, <literal>false</literal>,
    or <literal>unknown</literal>. The <literal>unknown</literal> value
-   plays the same role as SQL <literal>NULL</literal>. Further path
+   plays the same role as SQL <literal>NULL</literal> and can be tested
+   for with the <literal>is unknown</literal> predicate. Further path
    evaluation steps use only those items for which filter expressions
-   return true.
+   return <literal>true</literal>.
+  </para>
+
+  <para>
+   Functions and operators that can be used in filter expressions are listed
+   in <xref linkend="functions-sqljson-filter-ex-table"/>. The path
+   evaluation result to be filtered is denoted by the <literal>@</literal>
+   variable. To refer to a JSON element stored at a lower nesting level,
+   add one or more accessor operators after <literal>@</literal>.
   </para>
 
   <para>
@@ -11667,8 +11678,8 @@ table2-mapping
   <para>
    To get the start time of segments with such values instead, you have to
    filter out irrelevant segments before returning the start time, so the
-   filter is applied to the previous step and the path in the filtering
-   condition is different:
+   filter expression is applied to the previous step, and the path used
+   in the condition is different:
 <programlisting>
 '$.track.segments[*] ? (@.HR &gt; 130)."start time"'
 </programlisting>
@@ -11693,9 +11704,9 @@ table2-mapping
   </para>
 
   <para>
-   You can also nest filters within each other:
+   You can also nest filter expressions within each other:
 <programlisting>
-'$.track ? (@.segments[*] ? (@.HR &gt; 130)).segments.size()'
+'$.track ? (exists(@.segments[*] ? (@.HR &gt; 130))).segments.size()'
 </programlisting>
    This expression returns the size of the track if it contains any
    segments with high heart rate values, or an empty sequence otherwise.
@@ -12285,7 +12296,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>
@@ -12313,8 +12324,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>
@@ -13170,17 +13181,17 @@ 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>
 
diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml
index daebb4f..0d8e2c6 100644
--- a/doc/src/sgml/json.sgml
+++ b/doc/src/sgml/json.sgml
@@ -815,21 +815,18 @@ SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"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-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"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 an expression returning a single numeric value, which is
+        automatically cast to integer. Zero index corresponds to the first
+        array element. You can also use the <literal>last</literal> keyword
+        to denote the last array element, which is useful for handling arrays
+        of unknown length.
        </para>
       </entry>
      </row>

Reply via email to