Strictness and canonical form

This page covers two related topics: how the compiler reacts to a problem, and how many ways there are to write the same thing.

Errors, warnings and trust

The compiler's reaction depends on what it can establish from the query text.

What the compiler can establishReaction
The query breaks a rule: a unit mismatch, a sum across a non-additive axis, a lookup through the wrong entityError
The result may be ambiguous or lossy, and the query cannot show which: a possible tie, a comparison on floating values without a stated precisionWarning. The query runs
A declaration made at a sourceTrusted

An error has a stable code (UE/...), a location, the feature it concerns and, where one exists, a repair that compiles. Cycles are reported with the cycle listed. The examples in Semantic contracts show several.

A warning carries an acknowledgment token, for example ACK-YLZJ. A persisted view does not accept unacknowledged warnings: CREATE VIEW fails unless the view body contains the token in a comment.

CREATE OR REPLACE VIEW FMV.DOCS.WARNED AS
-- ACK-MW54
DEFINE
    X := 1e0
RETURN
    FLAG := X > 0e0
;

An acknowledgment never hides an error.

One canonical syntax, a permissive surface

Each construct has one canonical spelling. DEFINE hides a formula, RETURN sends it to the caller, and PERSIST stores it on CREATE FEATURES. WITH and SELECT are SQL, so they are not FeatureQL clause spellings. Other permissive spellings below still compile during exploration, and only when that spelling has one meaning.

PermissiveCanonical
CAST(x AS T)x::T
ARRAY[1, 2]ARRAY(1, 2)
COUNT(*)COUNT()
GROUP BY kGROUP BY (k)
YEAR(d), EXTRACT(YEAR FROM d)DATE_PART(d, 'year')
SLICE(arr, i, n)SLICE_LEN(arr, i, n)
DISPLAYS ASIS [NOT] DISTINCT FROM
BIGINT[], LIST<T>ARRAY<BIGINT>

COUNT(x) is not accepted, see Absence, emptiness and errors .

Two tools move a query to the canonical form.

/* STRICT */ refuses permissive spellings and names each one:

FeatureQL
/* STRICT */
DEFINE
    XS := ARRAY[1, 2, 3],
RETURN N := XS.TRANSFORM(RETURN COUNT(*)).UNWRAP_ONE();
Result
ERROR UE/STRICT-SYNTAX Strict syntax: 2 issues found. 1. [USE-PARENS-ARRAY] Use ARRAY(...) instead of ARRAY[...] for array constructor syntax. Rewrite with FORMAT (FIX). (defining feature XS) (line 3, col 10) 2. [USE-COUNT-NULLARY] Write COUNT() for a row count; COUNT(*) and COUNT(constant) are compatibility spellings. (line 4, col 32) Remove the /* STRICT */ tag from your query.

FORMAT (FIX) rewrites them. Identifiers are case-insensitive, and the formatter writes them in lowercase.

FORMAT (FIX)
DEFINE
    XS := ARRAY[1, 2, 3],
RETURN N := XS.TRANSFORM(RETURN COUNT(*)).UNWRAP_ONE();

returns

DEFINE
    xs := ARRAY(1, 2, 3)
RETURN
    n := xs.TRANSFORM(RETURN COUNT()).UNWRAP_ONE()
;

The registry stores features in normalized form, so a stored definition does not depend on how it was typed. See Friendly syntax .

Naming conventions for weaker guarantees

A function or modifier that weakens a guarantee says so in its name.

FormMeaningExamples
UNSAFE_ prefixA contract check is bypassedUNSAFE_CAST
UNSAFE modifierThe additivity check is bypassed for one callUNSAFE SUM(...)
ANY_ prefixAn arbitrary selectionANY_VALUE
APPROX_ prefixAn approximate resultAPPROX_DISTINCT, APPROX_PERCENTILE
TRY modifierAn error in one call becomes NULLTRY LN(x)

A query that uses none of these stays within the checks described in this section.