mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
planner: Add not-body support to planner (#8458)
Fixes: #8392 Signed-off-by: Johan Fylling <johan.dev@fylling.se>
This commit is contained in:
@@ -637,7 +637,7 @@ func (p *Planner) planQuery(q ast.Body, index int, iter planiter) error {
|
||||
func (p *Planner) planExpr(e *ast.Expr, iter planiter) error {
|
||||
|
||||
switch {
|
||||
case e.Negated:
|
||||
case e.IsNegated():
|
||||
return p.planNot(e, iter)
|
||||
|
||||
case len(e.With) > 0:
|
||||
@@ -661,8 +661,16 @@ func (p *Planner) planNot(e *ast.Expr, iter planiter) error {
|
||||
prev := p.curr
|
||||
p.curr = not.Block
|
||||
|
||||
if err := p.planExpr(e.Complement(), func() error { return nil }); err != nil {
|
||||
return err
|
||||
if n, ok := e.Terms.(*ast.Not); ok {
|
||||
for _, be := range n.Body {
|
||||
if err := p.planExpr(be, func() error { return nil }); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := p.planExpr(e.Complement(), func() error { return nil }); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
p.curr = prev
|
||||
|
||||
@@ -66,6 +66,15 @@ func TestPlannerHelloWorld(t *testing.T) {
|
||||
note: "negation",
|
||||
queries: []string{"not input.x.y = 1"},
|
||||
},
|
||||
{
|
||||
note: "negation, not-body",
|
||||
queries: []string{"data.test.p = x"},
|
||||
modules: []string{`
|
||||
package test
|
||||
import future.keywords.not
|
||||
p if { not input.x.y = 1 }
|
||||
`},
|
||||
},
|
||||
{
|
||||
note: "not and known vars", // https://github.com/open-policy-agent/opa/issues/3279
|
||||
queries: []string{`x = "foo"; not data.tenants[x]`},
|
||||
@@ -396,7 +405,16 @@ q = 2`,
|
||||
modules := make([]*ast.Module, len(tc.modules))
|
||||
for i := range modules {
|
||||
file := fmt.Sprintf("module-%d.rego", i)
|
||||
opts := ast.ParserOptions{AllFutureKeywords: true}
|
||||
|
||||
// TODO: drop once future.keywords.not is enabled by default
|
||||
caps := ast.CapabilitiesForThisVersion()
|
||||
caps.FutureKeywords = append(caps.FutureKeywords, "not")
|
||||
|
||||
opts := ast.ParserOptions{
|
||||
AllFutureKeywords: true,
|
||||
Capabilities: caps,
|
||||
}
|
||||
|
||||
m, err := ast.ParseModuleWithOpts(file, tc.modules[i], opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
# Exception Format is <test name>: <reason>
|
||||
"data/toplevel integer": "https://github.com/open-policy-agent/opa/issues/3711"
|
||||
"data/nested integer": "https://github.com/open-policy-agent/opa/issues/3711"
|
||||
"negation/not-body: negated call with vars, call succeeds": "No planner support"
|
||||
"negation/not-body: negated call with vars, call fails": "No planner support"
|
||||
"negation/not-body: negated call with vars, undefined operands": "No planner support"
|
||||
"negation/not-body: negated call with vars, inside comprehension, call succeeds": "No planner support"
|
||||
"negation/not-body: negated call with vars, inside comprehension, undefined operands": "No planner support"
|
||||
"negation/not-body: negated call with vars, inside every, call succeeds": "No planner support"
|
||||
"negation/not-body: negated call with vars, inside every, undefined operands": "No planner support"
|
||||
"negation/not-body: negated and non-negated unification on same var, calls, rearranged": "No planner support"
|
||||
|
||||
@@ -74,9 +74,13 @@ func TestWasmE2E(t *testing.T) {
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
|
||||
caps := ast.CapabilitiesForThisVersion()
|
||||
caps.FutureKeywords = append(caps.FutureKeywords, "not")
|
||||
|
||||
opts := []func(*rego.Rego){
|
||||
rego.Query(tc.Query),
|
||||
rego.SetRegoVersion(regoVersion),
|
||||
rego.Capabilities(caps),
|
||||
}
|
||||
for i := range tc.Modules {
|
||||
opts = append(opts, rego.Module(fmt.Sprintf("module-%d.rego", i), tc.Modules[i]))
|
||||
|
||||
Reference in New Issue
Block a user