You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: add inline givens and in $array to the givens experiment page (#313)
Covers the two extensions landing alongside the givens MVP: array-typed
givens used with `expr in $arrayGiven`, and the `inline` modifier that
eager-evaluates a given's default at bind time (the RLAC capability-gate
pattern). Introspection section notes inline givens are excluded from
the public surfacing APIs.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: src/documentation/experiments/givens.malloynb
+62Lines changed: 62 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -68,6 +68,66 @@ A given's name appears in four places:
68
68
69
69
`$` appears **only** at expression references. The other three sites use the bare name. The disambiguation problem the sigil solves only exists inside expressions, where given names compete with field names, source names, and other identifiers; declarations, imports, and supply sites already sit in syntactic positions where only a given makes sense.
70
70
71
+
## Array givens and `in`
72
+
73
+
When a given has array type, an expression `expr in $ARR` tests `expr` against the runtime-bound array. `not in $ARR` is the standard negation.
74
+
75
+
```malloy
76
+
given:
77
+
ALLOWED_STATES :: string[]
78
+
URGENT_STATUSES :: string[]
79
+
80
+
source: orders extend {
81
+
where: state in $ALLOWED_STATES
82
+
dimension: is_urgent is order_status in $URGENT_STATUSES
83
+
}
84
+
```
85
+
86
+
The left-hand side must have the same basic type as the array's element type — `string in $string[]`, `number in $number[]`, etc. Mismatches are translate-time errors.
87
+
88
+
The array's contents reach SQL embedded in a generated `IN (...)` clause. An empty array, or one bound to `null`, collapses to the obvious result: `IN` becomes `FALSE`, `NOT IN` becomes `TRUE`.
89
+
90
+
To *derive* a value from an array — typically a boolean gate — without embedding the array in row-position SQL, see [Inline givens](#inline-givens) below.
91
+
92
+
## Inline givens
93
+
94
+
An **inline** given is evaluated at bind time, before SQL is emitted. Its default expression runs against the resolved given values and produces a literal — boolean, number, string — and that literal is what reaches SQL.
95
+
96
+
```malloy
97
+
given:
98
+
CAPABILITIES :: string[]
99
+
inline CAN_READ_ORDERS :: boolean is 'read_orders' in $CAPABILITIES
100
+
inline CAN_MUTATE :: boolean
101
+
is 'write_orders' in $CAPABILITIES or 'admin' in $CAPABILITIES
102
+
103
+
source: orders extend {
104
+
where: $CAN_READ_ORDERS // SQL sees: WHERE ... AND TRUE (or FALSE)
105
+
}
106
+
```
107
+
108
+
This is the **row-level access control gate** pattern. The host supplies a capability list as a regular given; an inline given derives a boolean from that list; the boolean — not the list — is what reaches SQL. The query planner sees a constant predicate, and the underlying capability list never crosses into row-position SQL.
109
+
110
+
`inline` is a modifier on the declaration. An inline given is computed, not supplied — its derived value is a translation-time intermediate and isn't surfaced as a public API. It does not appear in `Model.givens` or `PreparedQuery.givens` (a caller shouldn't be invited to override a derived value), and the host doesn't bind it through `Runtime` either.
111
+
112
+
### Rules
113
+
114
+
- An inline given must have a default. A modifier with no `is` clause is a translate-time error.
- The [`in $array`](#array-givens-and-in) test against another given
118
+
- Literals (string, number, boolean, null, array) and references to other givens
119
+
- The default cannot call SQL functions, reference fields, or use any operator outside the list above. Disallowed operators are reported at translate time.
120
+
121
+
The allowed operator surface intentionally covers the capability/role-gate use case and will grow as concrete needs appear.
122
+
123
+
### When to reach for inline
124
+
125
+
| You have | Use |
126
+
|---|---|
127
+
| A value the host computes per request that reaches SQL as-is | A regular given |
128
+
| An array the host supplies, tested per row | A regular array given with [`in $array`](#array-givens-and-in) |
129
+
| A value derived from other givens that should reach SQL as a literal | An inline given |
130
+
71
131
## Imports and surfacing
72
132
73
133
Each model has a flat **given namespace** — the names its caller uses to supply values. Givens behave like every other top-level named thing under [import](../language/imports.malloynb):
@@ -292,6 +352,8 @@ class PreparedQuery {
292
352
293
353
`PreparedQuery.givens` returns the subset **this specific query** references — a strict subset of `Model.givens`. Drives "run this query" forms that prompt only for the givens this query touches, not every given in the model.
294
354
355
+
Both views exclude [inline givens](#inline-givens) — they're computed, not supplied.
0 commit comments