RETURN

RETURN is the FeatureQL evaluation statement. It defines output features, sends them to the caller, resolves persisted namespaces, binds inputs, filters rows, and controls presentation order. DEFINE names formulas that stay inside the statement. WITH and SELECT are SQL, not FeatureQL clause spellings.

Syntax

[CONST constant := expression [, ...]]
[DEFINE feature := expression [, ...]]
RETURN [TRACE] [DISTINCT]
    select_item [, ...]
[FROM namespace_or_relation [AS _alias] [, ...]]
[FOR [CROSS] [NESTED] input := binding [, ...]]
[WHERE boolean_expression]
[ORDER BY expression [ASC | DESC] [NULLS FIRST | NULLS LAST] [, ...]]
[LIMIT count [OFFSET offset]
 | LIMIT offset, count
 | OFFSET offset [ROW | ROWS] LIMIT count]

Clauses

  • CONST defines compile-time constants before feature inference. Each constant uses :=.
  • DEFINE creates local intermediate features that are available to the query but omitted from its output unless returned.
  • TRACE adds named upstream dependencies to the output in dependency order. RETURN DISTINCT is recognized only so it can be rejected (UE/QUERY-RETURN-DISTINCT-NOT-SUPPORTED on the query, UE/TRANSFORM-RETURN-DISTINCT-NOT-SUPPORTED inside TRANSFORM()).
  • FROM supplies namespaces or relations used by the query. A namespace may be unaliased or use an alias beginning with _.
  • FOR binds concrete values or tables to INPUT() features. Add CROSS when independent bindings intentionally form a Cartesian product. NESTED applies to a binding item used by nested evaluation.
  • WHERE filters presented rows at the RETURN grain. The predicate may use hidden features as long as they are evaluable on a presented row. It does not shrink aggregate inputs — use FILTER (WHERE …) on each aggregate for pre-aggregation row filters. WHILE occupies the same grammar position inside recursive evaluation and is documented with RECURSE() .
  • ORDER BY accepts multiple expressions, direction, and explicit null ordering.
  • LIMIT and OFFSET accept the three forms shown above. Counts and offsets are non-negative integer literals.

Bindings include BIND_VALUE(), BIND_VALUES(), BIND_COLUMNS(), BIND_SQL(), BIND_SQL_OR(), and @BIND_KEYSET(). Their arguments are function-specific; see Binding inputs .

Return items

A return item can reference an existing feature, define a named feature with := or AS, or return an expression. Properties such as WITH (DESCRIPTION = …) attach to a definition rather than to the statement.

An unaliased expression is stored internally as UNNAMED_FEATURE_*. The result column and EXPLAIN / validate output schema use a parenthesized inlined formula instead (RETURN 1 + 2 → (1 + 2)). Duplicate formulas get a _1, _2, … suffix; formulas longer than 32 characters keep the start and end with ... in the middle (1 + 2 + 3 + 4 +...+ 6 + 7 + 8 + 9). Those display names are not a stable contract — use AS or := when a caller, dashboard, or frame will read the column by name.

DEFINE
    PRICE := INPUT(BIGINT),
    QUANTITY := INPUT(BIGINT),
    TAX := INPUT(BIGINT),
    SUBTOTAL := PRICE * QUANTITY
RETURN
    SUBTOTAL,
    TOTAL := SUBTOTAL + TAX
FOR
    PRICE := BIND_VALUE(10),
    QUANTITY := BIND_VALUE(2),
    TAX := BIND_VALUE(4)
ORDER BY TOTAL DESC
LIMIT 10;

Unsupported SQL-shaped forms

Top-level SQL GROUP BY, HAVING, and RETURN DISTINCT are recognized only to produce a migration error. FeatureQL grouping belongs to feature expressions; see Grouping and unnesting . Deduplicate with GROUP BY on the presentation query, or ARRAY_DISTINCT() after TRANSFORM().

For a guided explanation, see Query structure .