Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

7. Parameters, variables and explain

7.1 Parameters: $name

A query can reference named parameters. Their values travel next to the query:

{"query": "on users | where age >= $min and city in $cities | limit $n",
 "params": {"min": 18, "cities": ["Paris", "Lyon"], "n": 10}}

Behavior

  • Each $name outside a string literal is replaced by the literal of its value before the query is authorized, planned or run. Strings are quoted and escaped, so a value never changes the structure of the query: $name bound to x" | delete stays one string.
  • Any JSON value works: numbers, strings, booleans, null, arrays (for in), objects (for insert).
  • A parameter goes wherever its literal could: limit $n, near embedding, $vector, fill … from $start to $end.
  • An unbound $name fails the request (variable $name is not bound; …); unused parameters are ignored.
  • From a terminal: ogcli --param min=18 --param 'cities=["Paris","Lyon"]' '…' (a value is JSON when it parses, else a string).
  • Each distinct set of values is planned (and cached) on its own.

7.2 Variables: let

let <$name> = <expression> [, <$name> = <expression>]* | … | <source> | …
let <$name> ?= <expression> | …
let <$name> = ( <query> ) | …

Definition. Names a value computed once per query, before it runs.

let $threshold = 50, $since = parse_date("2026-02-01")
| on orders
| where price * qty > $threshold and parse_date(month) >= $since
| derive margin = price * qty - $threshold

Behavior

  • Evaluated once per query, before planning, then used wherever $name appears. let $now = now() gives every row the same instant.
  • A value may use any function, request parameters, and variables declared before it (let $max = $min * 2, or a later let header). It cannot read document fields: let $x = qty is refused (cannot depend on documents).
  • A name is bound once: redeclaring a variable, or declaring a name also given in params, is an error.
  • ?= binds a default: only when the name is not bound already (by params, an earlier variable, or the query reading the view). This is how a view gives its parameters default values: let $gran ?= "month" | ….
  • Variables are bound like parameters, as escaped literals: explain let $n = 2 | on orders | limit $n shows limit 2.

Query variables

A value written as a query in parentheses is the array of its rows, read once in the scope of the request:

let $settings = (on settings | limit 1)
| let $opening = get(at($settings, 0), "opening")
| on ledger | where month >= $opening
  • The query may use the variables before it and read views.
  • It must only read, and returns at most 1,000 rows (a query in let returns at most 1000 rows).
  • It runs through query.execute (in a Place), like on view.

7.3 explain

explain <query>

Definition. Plans a query without running it and returns one document describing the plan. Authorization is the same as for the query itself.

explain on orders | where qty > 1 | sort price * qty desc | limit 3
{"access":"collection_scan","collection":"orders","executor":"governed_blocking","mode":"governed_blocking",
 "operators":[{"detail":"qty > 1","stage":"filter"},{"detail":"__og_sort_0 = price * qty","stage":"derive"},
 {"detail":"__og_sort_0 desc","stage":"sort"},{"detail":"__og_sort_0","stage":"drop"},{"detail":"3","stage":"limit"}],
 "read_only":true}
FieldMeaning
accesscollection_scan or primary_key_lookup
executorstreaming, governed_blocking, transactional (writes), or rejected when no bounded executor fits
modeThe memory contract of the plan
operatorsThe physical operators in order, shorthand forms expanded, filters where the planner moved them
read_onlyWhether the plan writes

explain define view … checks a view definition without writing it. explain shows views expanded and parameters bound, so it is the tool to see what a view really runs.