Current section
Files
Jump to
Current section
Files
CHANGELOG.md
# Changelog
## unreleased
## 0.2.0 (2026-08-23)
### Added
- Nested fields. An unquoted dotted field name is a path: `first.second: foo`
yields one `nested` node per dot, wrapping the comparison at the leaf, and the
operator travels down with it.
```elixir
%{"type" => "nested", "path" => "first",
"term" => %{"type" => "comparison", "field" => "second", "operator" => "=", ...}}
```
`nested` recurses through `"term"`, the same convention `not` and `group`
already use, so an existing walker descends it without changes. Empty segments
are rejected (`a.`, `a..b`), and a leading dot or digit still cannot start a
field name.
- Quoted field names: `"first.second": foo`. Quoting makes the name literal —
its dots are characters, not separators — so it stays a plain `comparison`
with `"field" => "first.second"`. This is how you address a field whose name
genuinely contains dots, and it also allows characters an unquoted name
cannot hold, such as spaces.
- Bracketed value lists: `field:[a,b]` is equivalent to `field:(a OR b)` and
produces the same `value_list` AST. Whitespace around the comma is optional,
elements may be quoted or globs, and a single-element list (`field:[a]`) is
valid.
- The nested-object form: `first: { second: foo and third: bar }`, which
produces the same `nested` nodes the dotted form does — `a:{b:c}` and `a.b:c`
are the same AST. Bodies may hold any expression, nest further
(`a:{b:{c:d}}`), and take a quoted or dotted path.
### Fixed
- Underscored the unused `error` and `acc` bindings in the generated parser.
Regenerating `lib/kql.ex` emitted nine warnings, which
`mix compile --warnings-as-errors` rejects. These are reapplied by hand after
each `mix compile.nimble` run.
### Notes
**One breaking change:** `{` and `}` join `\`, `(`, `)`, `:`, `<`, `>`, `"` and
`*` as characters that must be quoted or escaped in an unquoted value. A
character cannot be structural and an ordinary value character at once, which is
the same reason parens have always been excluded. This matches Kibana, whose
grammar defines `SpecialCharacter = [\\():<>"*{}]` — kql's set was that one
minus the braces, only because nested queries were unsupported.
So `make:a{b}c` parsed in 0.1.0 and is now an error; write `make:"a{b}c"` or
`make:a\{b\}c`.
Otherwise every query valid in 0.1.0 parses to the same AST. Dotted and quoted
field names did not parse at all in 0.1.0, so a `nested` node cannot appear for
any query that previously worked: an undotted `make:foo` is still a bare
`comparison`.
Because `[`, `]` and `,` remain legal unquoted-value characters, a value that
merely looks like a list keeps parsing as a value: `field:[a]x` is the value
`[a]x`, and an unclosed `field:[a,b` is the value `[a,b`. A bracketed list is
recognised only when nothing else follows the closing bracket. Inside a list, a
literal `,` or `]` must be quoted or escaped, as a literal paren already must be
inside `( ... )`.
## 0.1.0 (2025-11-25)
- Initial release