Query structure
Clause order is significant:
[EXPLAIN [PLAN|CONTEXT|ANALYZE] [FORMAT TEXT|JSON]] -- optional: inspect, don't (necessarily) run
PREDICT <target> [CLASSIFY | RANK TOP <k>] -- required: what to predict
FOR [EACH] <entity_table>.<pkey> -- required: the population
[= <literal> | IN (<list>)] -- ...or explicit entities
[WHERE <condition>] -- optional: entity filter (past-facing)
[ASSUMING <condition>] -- optional: counterfactual
[AS OF <anchor>] -- optional: bind the anchor time
[RETURN <return_spec>] -- optional: choose the output form
[WINDOW <name> AS (<window_spec>)] -- optional, repeatable: named frames
The trailing clauses — WHERE, ASSUMING, AS OF, RETURN, WINDOW —
may appear in any order after FOR. Each may appear at
most once, except WINDOW, which repeats (one per named frame).
There is no FORECAST N TIMEFRAMES clause. To forecast, give the target's
window multiple horizons (... OVER (7 DAYS FOLLOWING HORIZONS 4)); a
multi-horizon window implies forecasting. See
Aggregations & windows.
Clauses
PREDICT <target>— a static column reference (customers.age,articles.description IS NULL), an aggregation over linked rows in anOVERframe, or a richer expression (arithmetic,CASE WHEN … END,COALESCE, column-to-column comparison), optionally compared to a literal.CLASSIFYandRANK TOP kare target directives (see task types).FOR EACH table.pk— predict for every entity (requires aTableScanner).FOR table.pk = <lit>/IN (...)selects explicit entities.WHERE <condition>— filters the population using static attributes and past-facing aggregations. See Conditions.ASSUMING <condition>— a counterfactual assumption, parsed and validated and carried on the query (not yet applied to context assembly).AS OF <anchor>— binds the anchor time (the instantNOWand every frame are measured from). The anchor is aDATEliteral (2026-07-01), a parameter (:prediction_time, bound at execution time), orNOW. ADATEor bound parameter takes precedence over the execution anchor;NOW(or noAS OF) uses the execution anchor.RETURN <return_spec>— selects the output form (see below).WINDOW <name> AS (<window_spec>)— declares a reusable named frame, referenced elsewhere asOVER <name>. Declared exactly once; referencing an undeclared name is an error. See Aggregations & windows.
RETURN — output form
RETURN overrides the default output implied by the task type:
EXPECTED VALUE | PROBABILITY | CLASS | DISTRIBUTION
| QUANTILES (<num>, ...) | INTERVAL <int> [%] | MULTILABEL | MULTICLASS
PREDICT SUM(payments.amount) OVER (30 DAYS FOLLOWING)
FOR EACH customers.customer_id
AS OF :t
RETURN INTERVAL 90%
EXPLAIN — inspect without (necessarily) running
An EXPLAIN prefix asks the engine to describe what it would do. The engine's
explain() entry point returns a result you can render as text or JSON
(FORMAT TEXT | JSON):
EXPLAIN [PLAN | CONTEXT | ANALYZE] [FORMAT TEXT | JSON]
PLAN— the default (bareEXPLAIN==EXPLAIN PLAN). Describes the query from parsing and validation alone: the normalized target, inferred task type, entity selector, resolved output form, each aggregation's normalized window, and the resolved anchor source. Does not assemble context or invoke the model.CONTEXT— additionally assembles the per-entity context and reports row/cell counts, links traversed, time ranges, and rows dropped by the temporal bound. Does not score the model.ANALYZE— assembles and scores, returning the predictions with the plan.
EXPLAIN PLAN FORMAT TEXT
PREDICT EXISTS(orders.*) OVER (30 DAYS FOLLOWING)
FOR EACH customers.customer_id
RETURN PROBABILITY
Lexical rules
- Keywords are case-insensitive:
PREDICT,OVER,FOLLOWING,PRECEDING,RANGE,BETWEEN,HORIZONS,STEP,WINDOW,AS OF,RETURN,EXPLAIN,FOR,EACH,WHERE,ASSUMING,CLASSIFY,RANK,TOP. - Aggregation and condition words (
COUNT,SUM,AND,LIKE, ...) are soft keywords — still usable as column names (usage.countparses). - Column references are always qualified:
table.column;table.*counts rows. - Literals: numbers,
'quoted strings', booleans,DATEs (2026-07-01). Frame bounds useUNBOUNDED PRECEDINGfor all history. - Comments are supported.