oqx
OQX (omgbase Query eXpressions) — Rust implementation.
OQX is a small query language for querying JSON-shaped collections — arrays of records, nested relations, recursive trees — with a readable, declarative syntax:
select name, id, title
from people
where jobs exists { where employer == "Globocorp" && !end_date }
This crate is the second implementation of the language. The reference
implementation is the TypeScript package
@omgbase/oqx.
Both conform to the language-neutral specification and fixtures at
spec/oqx in the same
repository, and each reports the spec version it conforms to.
Status
Conformance-first, and conformant: tests/spec.rs runs every fixture in
spec/oqx/cases (850 cases in 29 files at language version 0.13) and all of them
pass, so cargo test -p oqx requires every case to pass. Published on crates.io
as oqx.
The runner keeps an allowlist mechanism for the periods when the spec runs
ahead of the port (from spec/oqx/README.md): if tests/spec-passing.txt
exists, it names the case ids (<file-stem>::<name>, one per line) that must
pass; a listed case that fails fails the build, an unlisted case that passes
fails the build with a message asking for it to be added, and a listed id that
no longer exists is an error too. When the file is absent — the current state —
every case must pass. cargo test -p oqx prints spec: N passed, M failed, K listed on stderr and, on failure, the offending case ids grouped by fixture
file with a one-line reason each.
To (re)generate the allowlist from the currently passing set — for example
after new fixtures land in spec/oqx/cases before the port catches up — run:
OQX_SPEC_UPDATE=1
This writes the list (and prints any listed case that now fails, so nothing is blessed silently), or deletes the file once every case passes.
Layering
Mirrors the reference so the two can be read side by side:
lexer/parser→ast— the fixed clause order (select, from, where, follow, order by, limit, offset; only a leadingselectmay drop its keyword) and the expression grammar.semantics— the scalar contract every backend obeys: typed equality with no coercion, absent-aware ordering (absent sorts last both ways), membership, ranges, arithmetic, builtins.regex_dialect—matches(): the spec's regex baseline parsed and rewritten for theregexcrate (\d→[0-9],\b→(?-u:\b),\s→one listed set, flags→(?ims)), so a pattern means the same here as in the reference;DataContext::regex_dialect()/DefaultContext::with_regex_dialectopt a host into the crate's native syntax instead (not portable).engine— the in-memory engine over aDataContext(the seam that binds the language to a data model; the default context is plainValues).planner— the seam for pushing work into a store and finishing the residual in memory.
Features
json—From/Intobetweenoqx::Valueandserde_json::Value.sqlite—adapters::sqlite::SqliteTable, aQueryPlannerthat pushes the flat query core (scan + translatable conjunctive predicates,LIMITfor unorderedfirst/single) into SQL over a bundled SQLite viarusqlite, leaving the rest to the in-memory residual. Impliesjson.
License
MIT