malloydata / malloy

Malloy is an experimental language for describing data relationships and transformations.
http://www.malloydata.dev
MIT License
1.92k stars 75 forks source link

Fix bug where `nest: a + b + { order_by: a }` could not look up `a` #1607

Closed christopherswenson closed 5 months ago

christopherswenson commented 5 months ago

Fixes https://github.com/malloydata/malloy/issues/1605

Bug: nest: a + b + { order_by: a } failed to compile with an error that a could not be found in the output space (when evaluating the order_by.

This was actually an unfortunate parsing error. The rule for nests was:

nestEntry
  : tags fieldPath (PLUS vExpr)?    # nestExisting
  | tags queryName isDefine vExpr   # nestDef
  ;

But this meant that nest: a + b + { order_by: a } would be parsed the same as nest: a + (b + { order_by: a }), which should make it clear why "a is not in the output space."

My solution is to change the rule for nests to:

nestEntry
  : tags (queryName isDefine)? vExpr   # nestDef
  ;

This makes the name is part syntactically optional. Then, in the AST builder for the nestDef, we traverse the View tree to see if there's a valid inferable name (refinement X + Y asks X for its name, field reference a has a name, arrow X -> Y asks Y for its name, and query properties { ... } has no name). If there is no inferable name, we yield an error telling you to add a name.

This has a nice side effect that now if you write nest: { group_by: foo } you no longer get a nasty parse error, but instead get a nice error telling you that you need a name.