Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ast+topdown: exit-early for (constant) complete virtual docs and func…
…tions (#3898) If the following conditions hold for a set of rules returned by the indexer, it will set EarlyExit: true, and change how the complete virtual doc or function is evaluated: - all rule head values are ground - all rule head values match This implies that some cases where early exit would be possible will not be covered: p = x { x := true input.foo == "bar" } p = x { x := true input.baz == "quz" } To indicate that "early exit" is possible, the indexer result message is amended. Also, the "Exit" trace event will have a message of "early" when "early exit" actually happens in eval: $ echo '{"x":"x", "y":"y"}' | opa eval -I -fpretty --explain=full -d r.rego data.r.r query:1 Enter data.r.r = _ query:1 | Eval data.r.r = _ query:1 | Index data.r.r (matched 2 rules, early exit) r.rego:11 | Enter data.r.r r.rego:12 | | Eval input.y = "y" r.rego:11 | | Exit data.r.r query:1 | Exit data.r.r = _ query:1 Redo data.r.r = _ query:1 | Redo data.r.r = _ r.rego:11 | Redo data.r.r r.rego:12 | | Redo input.y = "y" r.rego:11 | Exit data.r.r early With `r.rego` as package r r { input.x = "x" } r = 2 { input.z = "z" } r { input.y = "y" } This is done in in a way such that early-exit will abort array/set/object iterations on data: r { data.i[_] = "one" data.j[_] = "four" } f(x, y) { data.i[_] = x data.j[_] = y } Complete rules (r) and functions (f) that iterate over sets, arrays, and objects from either data (evalTree) or a term that's returned by some other rule etc (evalTerm). The CLI and golang packages expose ways to disable 'early-exit': This is in line with how indexing can be disabled. It's supposed to be used as a debugging measure, so it's only exposed as a CLI flag to `opa eval`. Co-authored-by: Torin Sandall <[email protected]> Signed-off-by: Stephan Renatus <[email protected]>
- Loading branch information