Part of DALgo · github.com/dal-go/dalgo/dtql

DALgo queries as DTQL.

A 1:1, lossless, human-readable YAML serialization of dalgo's dal.StructuredQuery for the core relational read-only subset. Plain YAML over the existing query AST — no bespoke grammar, no hand-written parser. Save a query, hand-edit it, diff it in version control, reload it without loss.

Get the schema Browse examples $ go get github.com/dal-go/dalgo
covered subset

What DTQL represents

A single From over a root collection, the selected columns, a Where tree, ordering, and paging. Anything out of scope is rejected with a descriptive error rather than silently dropped.

In scope

Root CollectionRef source · selected Columns · Comparison and And/Or GroupCondition trees · OrderBy · Limit/Offset. Expressions: FieldRef, Constant, Array (inline values). Operators: ==, In, >, >=, <, <=, And, Or.

Out of scope (rejected)

Joins · CollectionGroupRef or parented CollectionRef · GroupBy · aggregate/scalar functions · cursor (StartFrom) · any operator outside the in-scope set. Serialization errors out — it never emits a document that loses query semantics.

Lossless & canonical

deserialize(serialize(q)) is structurally equal to q; serialization is canonical (stable key order), so serialize(deserialize(d)) is byte-identical to d and saved queries diff cleanly.

node → YAML

Mapping

Each in-scope dal node has a defined YAML representation.

dal nodeYAML representation
From over root CollectionReffrom: { name, alias? }
Columnitem under columns: — an expression plus optional as:
Comparison{ op, left, right }
GroupCondition (And){ and: [ … ] }
GroupCondition (Or){ or: [ … ] }
OrderExpressionitem under orderBy: — an expression plus optional desc: true
FieldRef{ field: <name> }
Constant{ value: <scalar> }
Array{ values: [ <scalar>, … ] }
Operator==, In, >, >=, <, <=
Limit / Offsetlimit: <int> / offset: <int>

An expression sets exactly one of field, value or values, which discriminates a FieldRef, a Constant or an Array.

example

A query as DTQL

Columns with an alias, a nested And/Or filter with an inline In array, ordering, and paging.

query.dtql.yaml YAML
from:
  name: users
columns:
  - field: name
  - field: age
    as: years
where:
  and:
    - op: '>='
      left:
        field: age
      right:
        value: 18
    - or:
        - op: In
          left:
            field: status
          right:
            values:
              - active
              - pending
        - op: ==
          left:
            field: country
          right:
            value: US
orderBy:
  - field: name
  - field: age
    desc: true
limit: 10
offset: 20
guarantees

Round-trip fidelity

Structural. For any in-scope query q, deserialize(serialize(q)) reconstructs a StructuredQuery structurally equal to q across From, Columns, Where (including inline Constant/Array values), OrderBy, Limit and Offset.

Canonical. Serialization is canonical (stable key order, 2-space indent), so serialize(deserialize(d)) is byte-identical to a valid in-scope document d — saved queries diff cleanly across edits.

Deserializing malformed or schema-invalid input returns a descriptive error and no partially-populated query.