Skip to content

rego: Allow per-eval GenerateJSON function#8690

Merged
anderseknert merged 1 commit into
open-policy-agent:mainfrom
anderseknert:eval-generatejson
May 26, 2026
Merged

rego: Allow per-eval GenerateJSON function#8690
anderseknert merged 1 commit into
open-policy-agent:mainfrom
anderseknert:eval-generatejson

Conversation

@anderseknert
Copy link
Copy Markdown
Member

The Rego API's GenerateJSON function allows clients to provide custom logic for transforming an original AST result into whatever format they may need. Previously this could only be set on the Rego object directly, meaning that a single prepared query would have to use the same function for all evaluations. This change adds the option to additionally set an `EvalGenerateJSON function scoped to individual evaluations, making it easier to reuse a single prepared query even when the shape of the result is determined dynamically, by input data, in-policy routing, etc.

The Rego API's `GenerateJSON` function allows clients to provide custom logic
for transforming an original AST result into whatever format they may need. Previously
this could only be set on the Rego object directly, meaning that a single prepared query
would have to use the same function for all evaluations. This change adds the option to
additionally set an `EvalGenerateJSON function scoped to individual evaluations, making
it easier to reuse a single prepared query even when the shape of the result is determined
dynamically, by input data, in-policy routing, etc.

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
Comment thread v1/rego/rego.go
Comment on lines +2478 to +2481
generateJSON := r.generateJSON
if ectx.generateJSON != nil {
generateJSON = ectx.generateJSON
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as

generateJSON = cmp.Or(ectx.generateJSON, r.generateJSON)

but it doesn't matter

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, functions are not comparable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh! I thought these would be treated as pointers. I see.

Comment thread v1/rego/rego_test.go
assertResultSet(t, rs, `[["prepare-generate"]]`)
}

func generateJSONResult(s string) func(*ast.Term, *EvalContext) (any, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have put it into TestEvalGenerateJSON as a function literal, but it won't hurt anyone here either

@anderseknert anderseknert merged commit e07e1ec into open-policy-agent:main May 26, 2026
40 checks passed
@anderseknert anderseknert deleted the eval-generatejson branch May 26, 2026 14:25
@github-actions
Copy link
Copy Markdown

Benchmark Regression Detected

Commit e07e1ec86099aad12362c454e76490169b275a6d introduced benchmark regressions (threshold: >25% ns/op increase).

Package Benchmark Regression
v1/ast BenchmarkValueName-4 +422%
v1/ast BenchmarkFromBuiltinNames/two_parts-4 +189%
v1/ast BenchmarkNoASTTypeAllocatesOnAppendToBufferOfStringLength/number-4 +102%

Notable Improvements 🎉

Commit e07e1ec86099aad12362c454e76490169b275a6d delivered big speedups (>35% ns/op decrease). Nice work!

Package Benchmark Improvement
v1/ast BenchmarkSetMembership/50-4 -53%
v1/types BenchmarkAnyMergeOne/10000-4 -41%
v1/ast BenchmarkFromBuiltinNames/no_match-4 -37%
v1/ast BenchmarkFromBuiltinNames/three_parts-4 -35%

Benchmarks Dashboard

This comment was automatically generated by the benchmarks workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants