Re: SQL:2023 JSON simplified accessor support

Alexandra Wang <alexandra.wang.oss@gmail.com>

From: Alexandra Wang <alexandra.wang.oss@gmail.com>
To: Chao Li <li.evan.chao@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@postgresql.org>, Nikita Glukhov <glukhov.n.a@gmail.com>, jian he <jian.universality@gmail.com>, Nikita Malakhov <hukutoc@gmail.com>, Vik Fearing <vik@postgresfriends.org>, Mark Dilger <mark.dilger@enterprisedb.com>, Matheus Alcantara <matheusssilv97@gmail.com>, Peter Eisentraut <peter@eisentraut.org>, Andrew Dunstan <andrew@dunslane.net>, "David E. Wheeler" <david@justatheory.com>
Date: 2025-09-24T01:05:26Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Add test coverage for indirection transformation

  2. Fix typo in comment

  3. Implementation of subscripting for jsonb

Attachments

Hi Chao,

Thanks for reviewing. I'm glad you like the new approach of
introducing "transform_partial". I've attached v22, which addresses
some of your feedback, and I ran pgindent again.

See detailed replies below.

On Mon, Sep 22, 2025 at 10:48 PM Chao Li <li.evan.chao@gmail.com> wrote:

> The new approach of introducing “transform_partial” looks like a better
> solution, which leads to less code change to hstore_subs and arraysubs.
> However, when I tested the v21, I encountered errors when combine composite
> type, array and jsonb together.
>
> Prepare test data:
> ```
> drop table if exists people;
> drop type if exists person;
> CREATE TYPE person AS (
>     name text,
>     size int[],
>     meta jsonb[]
> );
>
> CREATE TABLE people (
>     p person
> );
>
> INSERT INTO people VALUES (ROW('Alice', array[10, 20], array['{"a":
> 30}'::jsonb, '{"a": 40}'::jsonb]));
> ```
>
> Then run the test:
> ```
> # old jsonb accessor works to extract a jsonb field from an array item of
> a composite field
> evantest=# select (p).meta[1]->'a' from people;
>  ?column?
> ----------
>  30
> (1 row)
>
> # dot notation also works
> evantest=# select (p).meta[1].a from people;
>  a
> ----
>  30
> (1 row)
>
> # but index accessor doesn’t work
> evantest=# select (p).meta[1]['a'] from people;
> ERROR:  invalid input syntax for type integer: "a"
> LINE 1: select (p).meta[1]['a'] from people;
>                            ^
>

This is the expected behavior for array subscripting, and my patch
doesn't change that. I don't think this is a problem. With or without
my patch, you can avoid the ERROR by adding parentheses:

test=# select ((p).meta[1])['a'] from people; meta ------ 30 (1 row)

On Mon, Sep 22, 2025 at 10:48 PM Chao Li <li.evan.chao@gmail.com> wrote:

> 2 - 0002
> ```
> + /* Collect leading A_Indices subscripts */
> + foreach(lc, indirection)
> + {
> + Node   *n = lfirst(lc);
> +
> + if (IsA(n, A_Indices))
> + {
> + A_Indices  *ai = (A_Indices *) n;
> +
> + subscriptlist = lappend(subscriptlist, n);
> + if (ai->is_slice)
> + isSlice = true;
> + }
> + else
> + break;
> ```
>
> We can break after “isSlice=true”.
>

Why? We still want to get the whole prefix list of A_Indices.

On Mon, Sep 22, 2025 at 10:48 PM Chao Li <li.evan.chao@gmail.com> wrote:

> 6 - 0002
> ```
> + /* This should not happen with well-behaved transform functions */
> + elog(ERROR, "subscripting transform function failed to consume any
> indirection elements”);
> ```
>
> I don’t see an existing error message uses “indirection” and “transform”.
> This error message looks more like a log message rather than a message to
> show to end users.
>

This is a defensive elog message that should not happen. So it is a
log message for developers. That said, I'm open to suggestions for
better wording.

The rest of your feedback I've made changes accordingly as you suggested.

Best,
Alex