Unified state SQL
Unified.Sql.plan(allocator, text, source) parses the complete read-only
SELECT grammar and lowers it to Unified.Plan. compile(allocator, ast, source)
accepts the same owned AST. Supply one explicit Source { name, schema }; the
compiler performs no catalog lookup, I/O or authorization. Projection and literal
slices belong to the supplied allocator. A bounded request arena is recommended;
Unified.Sql.deinit releases a compiled plan with its original allocator. It must
not be used for decoded plans, which borrow encoded bytes.
The caller must bind the plan to the exact source basis before execution.
The source schema can describe KV, Table or accepted Document projections.
transit-query.Bundle.fromSql combines an explicit definition, SQL name and
positive execution budgets. UnifiedClient.compileSql first verifies current
source policy and its permitted budgets. Neither operation admits a query or
retains a source version. Subsequent finite upload and source admission establish
the committed source cut recorded in the result.
The v1 SQL contract defines the exact profile:
| SQL | Behavior |
|---|---|
SELECT * | All one to eight declared columns |
| One to eight named columns | Ordered projection; duplicate names reject |
column AS name, COUNT(*) AS name, COUNT(column) AS name, SUM(column) AS name | Owned output names; repeated inputs are allowed with distinct output names |
FROM source AS alias | Alias supplies the column qualifier; source and output column identities stay unchanged |
| Each comparison atom | Exactly typed int64, uint64, finite float64, bool, UTF-8 or binary literal; byte ordering for text/binary |
IS NULL, IS MISSING, IS VALUE, IS TYPE_ERROR, IS CONFLICT | Exact cell-state selection |
NOT, AND, OR, grouping | Up to 64 postfix instructions; precedence in that order; eager first-error evaluation |
LIMIT | Full u64 count after filtering; no limit means no implicit truncation |
COUNT(*) | uint64 count including all cell states |
SUM(column) | Checked int64 sum in source order; missing/null skipped, error/conflict fails |
COUNT(column) | Checked uint64 value count; any admitted type, missing/null skipped, error/conflict fails |
The existing restricted aggregate subquery spells filter โ limit โ aggregate.
An inner output alias becomes the column name resolved by the outer sum. Output
aliases do not enter WHERE scope; predicates retain original source names.
Output names are inline in the plan and affect canonical bytes and result-schema
identity without changing the input schema or source basis.
An outer aggregate LIMIT rejects. Uint64 and finite float64 comparison literals
use explicit 'digits'::uint64 and 'decimal'::float64 forms. column = NULL
rejects with UnsupportedNullComparison. No implicit casts or rewrites occur.
Comparisons on null/missing stay unknown through NOT; only true selects. Atoms
evaluate in source order, including after a determining Boolean value. The first
type error or conflict aborts evaluation; no short-circuit rewrite is enabled.
Document paths, expansion and text materialization belong to the declared source,
not SQL syntax. DDL, writes, joins, arbitrary expressions and continuous queries
remain unsupported. The syntax guide defines parser bounds and escaping.
Sql.parseLocated, parseInspectionLocated and
parseDeclarationLocated accept an optional *Sql.Location while preserving
their ordinary parser's results and errors. A failure supplies a statement byte
offset and, when known, static expected-token vocabulary. EOF points just beyond
the final byte; lexer failures point to the offending token's start.
SqlDiagnostic.query(text, cause, inspection) explains a SQL compilation or
inspection failure. The boolean selects whether the calling interface accepts
SQL inspection. Unknown runtime errors return null; callers retain their own
authorization, transport and uncertain-outcome handling. This is local failure
presentation, not a runtime feature registry or authorization check. Mutation and
state-declaration syntax is checked through its production parser; grammar-only
families are labeled without claiming full syntax validation.
The returned diagnostic owns a bounded, redacted context buffer and borrows only
static vocabulary. render emits an ASCII excerpt/caret and guidance.
renderStyled supplies the same semantic parts to the caller's
style.write(out, part, text) renderer; terminal colors and environment detection
stay with the interface. Both use the same redacted and escaped excerpt.
renderRemote emits at most 128 printable ASCII bytes, with only static vocabulary
and numeric coordinates. These renderers perform no I/O or telemetry capture.
Diagnostic rendering does not change ASTs, plan bytes or saved requests.
The SQL proof checks the production parser and current compiler. It independently evaluates 70 rows with six scalar types and five cell states, compares actual nested Arrow at all eight page widths under each source-kind basis, and exercises explicit failures. These are pure engine source-basis checks; actual adapter/service recovery has separate evidence in the proof guide.
Typed templatesโ
Prepared.init(allocator, text, source) compiles a finite template with $n
parameters at the existing comparison and LIMIT positions. parameterTypes()
returns inferred types in ordinal order. bind(allocator, current_source, values)
checks that exact name/schema and returns a separately owned Bound.plan.
Release the template and bound owner separately with deinit; inputs need not
outlive either owner. Treat an initialized template as immutable.
Binding uses Unified.Scalar, never SQL text substitution. Ordinals start at
one without gaps, comparison types match their input column, and LIMIT requires
uint64. Conflicting repeated types and outer aggregate LIMIT reject. Empty
bindings are valid for a constant template. The source name/schema commitment
does not check resource identity or current permission. Follow the
parameter contract for exact
typing, ownership and unsupported public transport profiles.