Re: Q: Escapes in jsonpath Idents

From: "David E(dot) Wheeler" <david(at)justatheory(dot)com>
To: Erik Wienhold <ewie(at)ewie(dot)name>
Cc: Peter Eisentraut <peter(at)eisentraut(dot)org>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Q: Escapes in jsonpath Idents
Date: 2024-04-24 20:30:52
Message-ID: C16D6239-3F2F-4628-91A7-636F08278D78@justatheory.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Apr 24, 2024, at 3:22 PM, Erik Wienhold <ewie(at)ewie(dot)name> wrote:

> Thanks Peter! But what is the definition of the entire path expression?
> Perhaps something like:
>
> <JSON path> ::= <JSON path identifier> { "." <JSON path identifier> }
>
> That would imply that "$.$foo" is a valid path that accesses a variable
> member (but I guess the path evaluation is also specified somewhere).

I read it as “if it starts with a dollar sign, it’s a variable and not a path identifier”, and I assume any `.foo` expression is a path identifier.

> What bugs me about this description, after reading it a couple of times,
> is that it's not clear what is meant by ."$varname". It could mean two
> things: (1) the double-quoting masks $varname in order to not interpret
> those characters as a variable or (2) an interpolated string that
> resolves $varname and yields a dynamic member accessor.

My understanding is that if it’s in double quotes it’s never anything other than a string (whether a string literal or a path identifier string literal). IOW, variables don’t interpolate inside strings.

> Under case (2) I'd expect that query to return 456 (because $foo
> resolves to "bar"). (Similar to how psql would resolve :'foo' to
> 'bar'.)

Yes, I suspect this is the correct interpretation, but agree the wording could use some massaging, especially since path identifiers cannot start with a dollar sign anyway. Perhaps:

"If the key name starts with $ or does not meet the JavaScript rules for an identifier, it must be enclosed in double quotes to make it a string literal."

> Variables already work in array accessors and table 8.25 says that "The
> specified index can be an integer, as well as an expression returning a
> single numeric value [...]". A variable is such an expression.
>
> => select jsonb_path_query('[2,3,5]', '$[$i]', '{"i":1}');
> jsonb_path_query
> ------------------
> 3
> (1 row)
>
> So I'd expect a similar behavior for member accessors as well when
> seeing ."$varname" in the same table.

Oh, interesting point! Now I wonder if the standard has this inconsistency (and is aware of it).

> Yes, I think so. That would be case C in the spec excerpt provided by
> Peter. So it's just a key name that happens to contain (but not start
> with) the dollar sign.

Exactly. It also matches the doc you quote above. Something would have to change in src/backend/utils/adt/jsonpath_scan.l to fix that, but that file makes my eyes water, so I’m not gonna take a stab at it. :-)

D

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Melanie Plageman 2024-04-24 20:46:19 Re: BitmapHeapScan streaming read user and prelim refactoring
Previous Message Justin Pryzby 2024-04-24 20:26:47 Re: Add SPLIT PARTITION/MERGE PARTITIONS commands