Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bracket notation #92

Closed
goessner opened this issue Mar 29, 2021 · 15 comments
Closed

bracket notation #92

goessner opened this issue Mar 29, 2021 · 15 comments

Comments

@goessner
Copy link
Collaborator

goessner commented Mar 29, 2021

Also addressing Glyn's point

  1. "script" expressions (()) - I'd hope we could offer minimal support for these without too much contention.

from #78 here, obviously common agreement exists about the "bracket child operator", selecting a child value

  • either from a JSON object by "name"
  • or from a JSON array by index.

So in $..[<expr>] the result of expression <expr> will be interpreted as a member name or element index depending on the parent value type. While accepting this important statement, let's have a look at @danielaparker's JSON example in #88:

{
  "firstName": "John",
  "address"  : {
    "city" : "Nara",
  }
}

Applying following queries gives us

expression result
$.firstName ["John"]
$['firstName'] ["John"]
$[@.firstName] === $['John'] []
$.address.city ["Nara"]
$['address']['city'] ["Nara"]
$['address.city'] []
$[@.address.city] === $['Nara'] []

according to the member name or element index interpretation principle.

In general any query expression ala $.x[@.a.b.c] means:

"Find member name or element index of JSON value named "x" as the value of its descendant node location '@.a.b.c'".

From my point of view it is of very low practical use to bury member name or element index of any JSON value deep down in its subtree.

My [@.length-1] index arithmetic is also generally commented of being of low practical use.

Using root value symbol $ in $.x[$.id] meaning member name or element index referencing might be of some practical use, but potentially leads to security issues.

As a consequence of this I propose to completely dispense use of $ and @ in other expressions than filter expressions.

@goessner
Copy link
Collaborator Author

... leaving out the parenthesis in [()] above, was intended here for better readability only ...

@glyn
Copy link
Collaborator

glyn commented Mar 29, 2021

As a consequence of this I propose to completely dispense use of $ and @ in other expressions than filter expressions.

+1

@gregsdennis
Copy link
Collaborator

gregsdennis commented Mar 29, 2021

A few things. First,

... leaving out the parenthesis in [()] above, was intended here for better readability only ...

I don't think we should shortcut notation in our discussions. Doing so will end up with shortcutted notation becoming actual notation. Please use the full notation intended.

Second, I think there are multiple syntaxes being discussed;

  • Numeric index: $[0]
  • Named index: $['foo']
  • Path-as-index: $[@.address.city] or $['@.address.city'] or $['address.city']
  • Index-selection query: [(@.length-1)] or $.x[($.id)]

These should each have their own issues. Since the first two are pretty basic and agreed upon, let's focus on the last two. We can keep this one for the path-as-index (we should edit the title). I'll create a new issue for the latter.

@goessner
Copy link
Collaborator Author

You are right with demanding always complete syntax.

My points were:

  • No discussion about $[0], $['foo'], $['address.city']
  • Disallow use of $ and @: $[(@.address.city)], [(@.length-1)], $.x[($.id)]

I don't think, we need another issue for bracket notation ...

@gregsdennis
Copy link
Collaborator

gregsdennis commented Mar 30, 2021

No discussion about $[0], $['foo'], $['address.city'] - @goessner

What does $['address.city'] return for these Arguments?

{ "address": { "city": "Dallas" } }

{ "address.city": "Austin" }

{
  "address": { "city": "Dallas" },
  "address.city": "Austin"
}

My point is to say that the dot syntax as an index bears discussion. We don't have agreement on it.

The door dotted syntax itself, as a string, is a valid key, so it creates ambiguity that shouldn't be left to implementations to resolve.

I think a way around this would to use a @-path without quotes (also note the lack of ()): $[@.address.city]. This indicates that the index is a path that needs to be evaluated to obtain the correct value.

@cabo
Copy link
Member

cabo commented Mar 30, 2021

What does $['address.city'] return for these Arguments?

{ "address": { "city": "Dallas" } }

{ "address.city": "Austin" }

{
  "address": { "city": "Dallas" },
  "address.city": "Austin"
}

Empty nodelist, "Austin", "Austin".

My point is to say that the dot syntax as an index bears discussion. We don't have agreement on it.

So far the agreement appears to be that there is no such special syntax.

@goessner
Copy link
Collaborator Author

@gregsdennis:

What does $['address.city'] return for these Arguments?
...
My point is to say that the dot syntax as an index bears discussion. We don't have agreement on it.

But ['address.city'] is merely a string. Even ['..'] is valid and no "dot syntax". I think everyone agrees here.

The door syntax itself, as a string, is a valid key, ...

What is a "door syntax" ?

I think a way around this would to use a @-path without quotes (also note the lack of ()): $[@.address.city]. This indicates that the index is a path that needs to be evaluated to obtain the correct value.

Letting the lack of () aside, this is exactly the point I want to focus the usefulness aspect at. Take

{ 
  "key": "secret",
  "proxy": "key",
  "sub": { "hidden":"key" }
}

Result of both $[(@.proxy)] and $[(@.sub.hidden)] will be "secret". But why would anyone cumbersome reference a value in the same parent on the same level or below. Everybody would simply write $['key']. A little more use value might exist with $.obj[($.proxy)] and

{  "proxy": "key",
   "obj":  { 
     "key": "secret",
   }
}

But then come with $[($..key[($..key[($..key[])])])] security concerns, which outweighs the little use by far.

Except that referencing trick I see no other use case of [($.<path>)] let alone [(@.<path>)].

Even index arithmetic ala [(@.length-5)] is of little use.

@danielaparker writes in #57 (comment)

The only example of a "[()]" expression that I've ever seen is the one in the original JSONPath article,

$.store.book[(@.length-1)].title

and I believe it was Glyn that noted it can be rewritten without using expressions. My sense is that this construct wouldn't be missed.

So I pragmatically propose to disallow the use of $ and @ with bracket notation with [()] or without [] parenthesis, as long as no striking use case unexpectedly comes up. This applies to unions also.

To be clear: filter expressions are a completely other beast and need to be discussed in the following.

@gregsdennis
Copy link
Collaborator

But ['address.city'] is merely a string. Even ['..'] is valid and no "dot syntax". I think everyone agrees here.

@danielaparker & @bettio haven't commented here. Of those who have been involved, I'd expect one of them to disagree.

What is a "door syntax" ?

Sorry. Autocorrect. Dotted syntax. I've fixed it.

Result of both $[(@.proxy)] and $[(@.sub.hidden)] will be "secret". But why would anyone cumbersome reference a value in the same parent on the same level or below.

See #93 where I explain the usefulness of this syntax. I also suggest we take conversation of this syntax to that issue and focus on ['address.city'] here.

@gregsdennis
Copy link
Collaborator

gregsdennis commented Mar 30, 2021

Letting the lack of () aside... - @goessner

Omitting the () was done on purpose to differentiate from the [()] syntax (again, see #93 for that).

You never address the syntax $[@.address.city] that I mentioned. You instead went on to address $[(@.address.city)] which is not under discussion here (see #93).

This syntax would be equivalent to just having $.address.city, so it's true that there's no immediate benefit. The power comes when you combine it with unions.

Given the data

{
  "name": "Greg",
  "address": {
    "city": "Auckland"
  }
}

The union path $['name',@.address.city] would yield ["Greg", "Auckland"]`. There's not another way to do this.

@goessner
Copy link
Collaborator Author

Ahh ... I see ... this would be different indeed, a complete other thing.

So this must be allowed also for single bracket expressions

$[@.address.city] === $.address.city

when accepting the singularization principle. Consequently we would have to allow then constructs like $[@.address[(@.proxyCity)]], thus introducing a new level of complexity.

I think I made my point sufficiently precise. Others should decide regarding use of $ and @ inside of bracket expressions.

@gregsdennis
Copy link
Collaborator

Consequently we would have to allow then constructs like $[@.address[(@.proxyCity)]], thus introducing a new level of complexity.

I think we've already discussed allowing this level of complexity elsewhere for [?()]. How is this different?

@goessner
Copy link
Collaborator Author

... but now we have three different syntaxes ...

  • [@.<path>] or [$.<path>]
  • [(expr($,@))]
  • [?(expr($,@))]

which can be combined arbitrarily, where @ has different meaning each. And yes, [?()] is still to be defined.

Of course we can add that to the spec. I simply would like to discuss effort to benefit ratio before.

@glyn
Copy link
Collaborator

glyn commented Mar 31, 2021

I simply would like to discuss effort to benefit ratio before.

Agreed. And I'm concerned about the end user complexity/benefit ratio too as I've mentioned elsewhere. My personal preference is to focus on the core/common features or at least to get them nailed down first.

@gregsdennis
Copy link
Collaborator

gregsdennis commented Apr 9, 2021

Worth mentioning: a StackOverflow question just came in regarding nested query expressions.

@cabo
Copy link
Member

cabo commented Jan 17, 2022

I can't find anything actionable in here any more.
Please open a new issue if anything needs to be done for -base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants