Skip to content

Commit 6a92d32

Browse files
committed
planner: address ref head issue
When planning rules like these: ``` package authz allow[action][resource] if { action := "list"; "resource": "fruit"} allow.eat.veggies if true ``` and referencing them in a ref like ``` resp := allow[input.action][input.resource] ``` we ended up with a broken CallDynamic statement. Since the first ref rule is planned as `g0.data.authz.allow` and builds an object return value, and the second rule is planned as `g0.data.authz.allow.eat.veggies` with a boolean return value, we cannot dynamically dispatch their calls. With this change, the previously exising "unbalanced ruletrie" check now also hits before reaching the end of the ref. It'll catch this situation and avoid optimizing the dispatch. We'll end up with a longer, less efficient, but correct plan. Signed-off-by: Stephan Renatus <[email protected]>
1 parent 8ff85cb commit 6a92d32

File tree

2 files changed

+5
-14
lines changed

2 files changed

+5
-14
lines changed

internal/planner/planner.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -2491,11 +2491,9 @@ outer:
24912491

24922492
for _, node := range nodes {
24932493
// we're done with ref, check if there's only ruleset leaves; collect rules
2494-
if index == len(ref)-1 {
2495-
if len(node.Rules()) == 0 && node.ChildrenCount() > 0 {
2496-
p.debugf("no optimization of %s: unbalanced ruletrie", ref)
2497-
return dont()
2498-
}
2494+
if len(node.Rules()) == 0 && node.ChildrenCount() > 0 {
2495+
p.debugf("no optimization of %s: unbalanced ruletrie", ref)
2496+
return dont()
24992497
}
25002498
if rules := node.Rules(); len(rules) > 0 {
25012499
res = append(res, rules)

internal/planner/planner_test.go

+2-9
Original file line numberDiff line numberDiff line change
@@ -1088,18 +1088,11 @@ func TestOptimizeLookup(t *testing.T) {
10881088

10891089
p := planner()
10901090
p.vars.Put(ast.Var("x"), p.newLocal())
1091-
rulesets, _, _, opt := p.optimizeLookup(r, ast.MustParseRef("data[x].allow.see.something_else"))
1091+
_, _, _, opt := p.optimizeLookup(r, ast.MustParseRef("data[x].allow.see.something_else"))
10921092

1093-
if exp, act := true, opt; exp != act {
1093+
if exp, act := false, opt; exp != act {
10941094
t.Errorf("expected 'optimize' %v, got %v\n", exp, act)
10951095
}
1096-
if exp, act := 1, len(rulesets); exp != act {
1097-
t.Fatalf("expected %d rulesets, got %d\n", exp, act)
1098-
}
1099-
1100-
if exp, act := 2, len(rulesets[0]); exp != act {
1101-
t.Fatalf("expected %d rules in ruleset[0], got %d\n", exp, act)
1102-
}
11031096
})
11041097
}
11051098

0 commit comments

Comments
 (0)