If a negative array index was hardcoded in the policy it would cause a
panic (e.g., arr[-1]). This patch just fixes the select function to
return nil like it does for out-of-bounds.
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
Previously, if callers omitted output terms from call expressions, the
result would be ignored. This was fine for most calls which would only
return true if they were defined, however, for functions could return
false this became confusing because an expression like "f(1)" where f(1)
= false would be succeed and yield a result.
With these changes, built-in functions that used to only return true
always return true or false and the eval engine takes care to check if
the result is false when the the caller omits the output term.
This provides consistent behaviour across cases like...
f(1) => undefined (previously {})
f(1,x) => {x:false} (previously {x:false})
neq(1,1,x) => {x:false} (previously undefined)
neq(1,1,false) => {} (previously undefined)
neq(1,1,true) => undefined (previously undefined)
In the next set of changes, the Rego package will be updated to capture
values for expressions like the first one above so that function calls
behave like refs (i.e., their values are returned).
These changes modify topdown evaluation to use a binding list that
namespaces variables. This allows topdown to propagate partially ground
ref operands into child query evaluation.
These changes also prepare topdown evaluation to support a partial
evaluation mode.
With these changes, evaluation is no longer performed in two steps
(i.e., first pass of evaluating individual terms, second pass of
evaluating built-in expressions.) Instead, evaluation assumes queries
have been rewritten to eagerly evaluate refs and comprehension. This
way, ref and comprehension bindings do not have to be maintained
separately: they are handled by the normal variable binding list.
This commit contains some breaking changes to the topdown APIs,
namely...
1. Truth explanation has been removed. This feature was not used and the
tracing changes broke it. We can revisit in future if necessary.
2. Data indexing has been removed. Data indexing can be re-added in
future if necessary however it should be handled outside of topdown to
avoid potential memory leaks.
3. Built-in functions produce at-most-one output now. Functions that
used to produce multiple outputs (e.g., io.jwt.decode) can produce a
composite value if they need to.
Fixes#131
These changes introduce functions into the type layer. With functions in
the type layer, we can begin treating functions as a first-class
construct within OPA.
The types package defines the data types in OPA. The types themselves
are comparable. The Any type represents a set of types for cases where a
static value cannot be assigned. An empty Any type is the superset of
all types (and sets of types).