Validate Statements
Validate Statements
Validate statements check model promises against datasource bindings and data. Executing them requires access to the bound sources; parsing the statements alone does not run warehouse checks.
Syntax
validate_statement: ("validate" "all") | ("validate" SCOPE (IDENTIFIER ("," IDENTIFIER)*)?)
| ("validate" IDENTIFIER? "select natural" STRING "matches" "(" select_statement ")" config?)
Where SCOPE is one of: concepts, concept, datasources, datasource
Validate All
Check all concepts and datasources:
validate all;
Validate Concepts
Validate all concepts or specific ones:
# Validate all concepts
validate concepts;
# Validate specific concepts
validate concept customer.id, customer.name;
Validate Datasources
Validate all datasources or specific ones:
# Validate all datasources
validate datasources;
# Validate a specific datasource
validate datasource customers;
What Validation Checks
| Scope | Checks |
|---|---|
| Datasources | Column bindings and sampled types/nullability, grain and unique properties, declared ranges/enums/patterns, containment within complete where, and datasource assertions |
| Concepts | Root concepts have datasource bindings; complete bindings agree on distinct cardinality, or totals for additive sum/count metrics |
| All | Both datasource and concept checks |
Domain checks inspect the source for out-of-domain values, beyond the sample used for type checks. Cross-source cardinality checks detect missing populations but do not prove set equality when two populations have the same size. Unsupported or unavailable checks should not be read as a successful data-quality check.
Partial and Complete Bindings
~ marks a binding that contains only some of a concept's domain. It does not disable that column's type or value-domain validation:
key customer_id int;
key purchase_id int;
datasource customer_domain (customer_id)
grain (customer_id)
address customers;
datasource purchases (purchase_id, customer_id: ~customer_id)
grain (purchase_id)
address purchases;
validate concept customer_id;
Leaving off ~ would claim that the purchases source contains the full customer population. A smaller distinct count would then fail concept validation. Use partial datasource and complete where for a source complete within a specific slice; see the validation guide.
Assertions
validate datasource evaluates absolute assert conditions against the published asset. Assertions containing prior(...) are reported as not run: they need the old/new build pair available during refresh or persist. See datasource assertions.
Imported Names
Address an imported datasource by its alias-qualified name:
import customer as c;
validate datasource c.customers;
validate concept c.id;
Natural-Language Answer Validation
Embed a question and an authored expected query to test how reliably an agent can use the model:
import customer as customer;
validate customer_count
select natural 'How many customers are there? Return one count.'
matches (
select count(customer.id) as customer_count
) with (repetitions = 3, target = 1.0, comparison = exact);
The optional name identifies the check in reports. repetitions sets the number of attempts and target the required pass rate. comparison accepts tolerant (the default), exact, or ordered; columns are compared by position. ordered also checks row order.
Agent checks are excluded from the default unit/integration run. Opt in with --include-type agent and configure the provider/model under [agent] in trilogy.toml. These checks call the configured provider and consume tokens. Unit mode uses generated data; integration mode uses the live sources. They test whether the model supports the question, not independent correctness of the SQL engine, since both answers use the same compiler.
Example
import customer as customer;
import order as order;
# Check the model and its data before running queries
validate all;
select
customer.id,
customer.name
;