Skip to content
1 change: 1 addition & 0 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,7 @@ impl Interpreter {

let mut comps = self.eval_rule_ref(&rule_ref)?;
if let Some(ke) = &key_expr {
is_const_rule = is_const_rule && Self::is_simple_literal(ke)?;
comps.push(self.eval_expr(ke)?);
}
let output = if let Some(oe) = &output_expr {
Expand Down
2 changes: 1 addition & 1 deletion src/languages/rego/compiler/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl<'a> Compiler<'a> {
crate::ast::Expr::RefBrack { .. } if assign.is_some() => {
RuleType::PartialObject
}
crate::ast::Expr::RefBrack { .. } => RuleType::PartialSet,
crate::ast::Expr::RefBrack { .. } => RuleType::PartialObject,
_ => RuleType::Complete,
Comment on lines 58 to 63
},
_ => RuleType::Complete,
Expand Down
47 changes: 47 additions & 0 deletions tests/interpreter/cases/rule/partial_object_v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: constant_key_partial_object_v1
data: {}
input:
enabled: true
modules:
- |
package test
import rego.v1

p["fixed"] if {
input.enabled
}
Comment on lines +4 to +16
query: data.test
want_result:
p:
fixed: true

- note: multilevel_partial_object_v1
data: {}
input:
nested:
app:
read: 1
write: 2
ops:
deploy: 3
modules:
- |
package test
import rego.v1

p[a][b] if {
some a, obj in input.nested
some b, _ in obj
}
query: data.test
want_result:
p:
app:
read: true
write: true
ops:
deploy: true
160 changes: 160 additions & 0 deletions tests/rvm/rego/cases/partial_object_rules.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

cases:
- note: partial_object_variable_key_collects_all_bindings
data: {}
input:
items:
FOO: 1
BAR: 2
BAZ: 3
modules:
- |
package test

p[k] if {
some k, _ in input.items
}
query: data.test.p
want_result:
BAR: true
BAZ: true
FOO: true

- note: partial_object_explicit_value_collects_all_bindings
data: {}
input:
items:
FOO: 1
BAR: 2
BAZ: 3
modules:
- |
package test

p[k] := v if {
some k, v in input.items
}
query: data.test.p
want_result:
BAR: 2
BAZ: 3
FOO: 1

- note: partial_object_constant_key_still_works
skip: true # Existing constant-key rule path handling is tracked separately.
data: {}
input:
enabled: true
modules:
- |
package test

p["fixed"] if {
input.enabled
}
query: data.test.p
want_result:
fixed: true

- note: partial_object_multiple_bodies_collects_all_bindings
data: {}
input:
items:
FOO: 1
BAR: 2
BAZ: 3
modules:
- |
package test

p[k] if {
some k, _ in input.items
k in {"FOO", "BAR"}
}

p[k] if {
some k, _ in input.items
k == "BAZ"
}
query: data.test.p
want_result:
BAR: true
BAZ: true
FOO: true

- note: partial_set_contains_collects_all_bindings
data: {}
input:
items:
FOO: 1
BAR: 2
BAZ: 3
modules:
- |
package test

p contains k if {
some k, _ in input.items
}
query: data.test.p
want_result:
set!: ["BAR", "BAZ", "FOO"]

- note: partial_object_multilevel_key_collects_nested_bindings
skip: true # Existing multi-level bracket rule path handling is tracked separately.
data: {}
input:
nested:
app:
read: 1
write: 2
ops:
deploy: 3
modules:
- |
package test

p[a][b] if {
some a, obj in input.nested
some b, _ in obj
}
query: data.test.p
want_result:
app:
read: true
write: true
ops:
deploy: true

- note: partial_object_array_iteration_collects_all_bindings
data: {}
input:
items: ["FOO", "BAR", "BAZ"]
modules:
- |
package test

p[v] if {
some _, v in input.items
}
query: data.test.p
want_result:
BAR: true
BAZ: true
FOO: true

- note: partial_object_empty_input_is_empty_object
data: {}
input:
items: {}
modules:
- |
package test

p[k] if {
some k, _ in input.items
}
query: data.test.p
want_result: {}
Loading