edn-query-language / eql

EQL is a declarative way to make hierarchical (and possibly nested) selections of information about data requirements. This repository contains the base specs and definitions for EQL parsing, AST, etc.
http://edn-query-language.org
MIT License
381 stars 18 forks source link

Preserve metadata on all nodes #17

Closed lilactown closed 2 years ago

lilactown commented 2 years ago

Currently, metadata is preserved in the AST when attached to the top-level query vector, or any child which is a map.

user> (eql/query->ast ^:foo [])
{:type :root, :children [], :meta {:foo true}}
user> (eql/query->ast [^:foo {[:person/id 0] [:person/name]}])
{:type :root,
 :children
 [{:type :join,
   :dispatch-key :person/id,
   :key [:person/id 0],
   :query [:person/name],
   :meta {:foo true},
   :children [{:type :prop, :dispatch-key :person/name, :key :person/name}]}]}

However, it is not preserved on join children

user> (eql/query->ast [{:people ^:foo [:person/id :person/name]}])
{:type :root,
 :children
 [{:type :join,
   :dispatch-key :people,
   :key :people,
   :query [:person/id :person/name],
   :children
   [{:type :prop, :dispatch-key :person/id, :key :person/id}
    {:type :prop, :dispatch-key :person/name, :key :person/name}]}]}

The only exception is a :component key, which is for some reason preserved but undocumented

user> (eql/query->ast [{:people ^:component [:person/id :person/name]}])
{:type :root,
 :children
 [{:type :join,
   :dispatch-key :people,
   :key :people,
   :query [:person/id :person/name],
   :component true,
   :children
   [{:type :prop, :dispatch-key :person/id, :key :person/id}
    {:type :prop, :dispatch-key :person/name, :key :person/name}]}]}

It would be great to be able to preserve metadata wherever it is in the query. It might be ambiguous where to store it, though; the :component way of storing the join children's metadata on the :join node is what I need for my use case, but that would clobber the way that metadata on the outer map of a join is currently stored.

Not sure the exact solution, but wanted to track and get feedback on the problem at least.

wilkerlucio commented 2 years ago

This is what I propose: we merge the meta from the join and the join vector, and place on the same :meta in the AST, the join will have priority. What do you think?

lilactown commented 2 years ago

Makes sense to me

lilactown commented 2 years ago

BTW I have a branch in my project pyramid trying to use this https://github.com/lilactown/pyramid/pull/30

wilkerlucio commented 2 years ago

Closing, after discussions we got to the point of not changing the library.