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

Proposal: Array traversal by only supporting [] on attribute access #37

Closed
judofyr opened this issue Nov 17, 2020 · 4 comments
Closed
Assignees

Comments

@judofyr
Copy link
Contributor

judofyr commented Nov 17, 2020

Here's a proposal to specify array traversal at a grammar level. This means that the attribute access in *[_type == "user"].name becomes syntactically different from *[_type == "user"][0].name. The rules are as follows:

  • We have two different concept: avalue (array value) and value. avalue is the expressions which are guaranteed to return arrays: *, filtering, and projection on another avalue. value is everything else.
  • [] is not a generic operator, but instead an optional postfix on attribute access: .foo[]
  • This gives four cases for .foo:
    • value "." string: This is a plain attribute access (foo.bar)
    • value "." string "[]": This is also a plain attribute access (foo.bar[]), but the result is (syntactically) an avalue which means that further attributes will be mapped (foo.bar[].baz).
    • avalue "." string: This will map the attribute over the values (*._id).
    • avalue "." string "[]": This is a flat map over the attribute (*.books[]).
  • .foo on a value is always a plain attribute access, while .foo on a avalue is always a mapping.

Implications:

  • This means that:
    • *[_type == "user"].name is a mapping (since *[_type == "user"] is an avalue)
    • *{"firstName": name.firstName} is an attribute access
    • *{"firstName": name[].firstName} is a mapping
    • *{"firstName": name{firstName}} will filter the name-object (and return null if it's an array)
    • *{"firstName": name[]{firstName}} will filter over the entries of the name-array

Example which shows three of the different types:

Query:
  *[_type == "user"]{"a": books[].authors[].name}

AST (of the inner `a` attribute):
  (map_attribute
    (map_attribute_flatten
      (attribute_array (this) "books")
      "authors")
    "name")

Minimal grammar showing the example:

expr ::= avalue | value

value       ::= integer | attribute | wrap_object
attribute   ::= value "." string
element     ::= expr "[" integer "]"
wrap_object ::= value object

avalue   ::= star | filter | traverse | map_attribute | map_object
star     ::= "*"
filter   ::= expr "[" expr "]"
traverse ::= expr "[]"
map_attribute ::= avalue "." string
map_object    ::= avalue object


@judofyr judofyr self-assigned this Nov 17, 2020
@atombender
Copy link
Member

atombender commented Nov 17, 2020

My concern is that we don't break referential transparency. Is this semantics change purely syntactical, or do "avalue" expressions create distinct values? For example, does {"a": a[]} | a.b retain a as an "avalue" so that this is equivalent to {"a": a[].b} this is equivalent to {a} | a[].b?

@judofyr
Copy link
Contributor Author

judofyr commented Nov 17, 2020

This is purely syntactical and nothing is retained at runtime. *{"a": a[]} is equivalent to *{"a": a}. This will break referential transparency. Let's say we have a document with "a":[…]. We'd have to choose whether array literals should be avalue or value. If they are avalue then *{"a":a.b} will not be the same as *{"a":[…].b}, and if they are value then *{"a":a[].b} will not be the same as *{"a":[…].b}.

@atombender
Copy link
Member

I don't love that this breaks referential integrity, but I don't have very strong feelings about it. The most important thing is enabling the functionality we want. I just worry that it could cause problems down the line.

This doesn't cover flattening semantics. Do we supply a flatten() function?

@judofyr judofyr changed the title Proposal: Array traversal by splitting the grammar Proposal: Array traversal by only supporting [] on attribute access Nov 27, 2020
@judofyr
Copy link
Contributor Author

judofyr commented Jan 11, 2021

Closed in favor of #42.

@judofyr judofyr closed this as completed Jan 11, 2021
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

2 participants