Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ast/compile: use all vars from rule body for index candidates #3709

Merged

Conversation

srenatus
Copy link
Contributor

@srenatus srenatus commented Aug 5, 2021

Before, we'd only looked at the vars preceding the comprehension in the body
containing it. In the case of nested comprehensions, that would have excluded
the rule body OUTSIDE of the nested body.

Now, we'll accumulate candidates over multiple bodies -- capturing the ones
that had been missing before.

Fixes #3579.


I had a more involved fix first, but making it work with the query compiler, I realised that moving the candiates.Copy() does the trick, too.

The change to the existing tests also covers the issue underlying #3579, I believe.

@srenatus srenatus marked this pull request as ready for review August 5, 2021 11:59
@@ -3674,6 +3679,11 @@ func TestCompilerBuildComprehensionIndexKeySet(t *testing.T) {
]
}
`,
// Note: no comprehension index for line 7 (`z = [ ...`)
expected: exp{9: {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This expectation is new: the nested comprehension is now indexed because y, previously hidden in the surrounding body of the z comprehension, is no now taken into account.

Copy link
Member

Choose a reason for hiding this comment

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

This looks correct to me. We can index the inner comprehension but not the outer one. There was an issue in the original indexing implementation that resulted in this test case/fix: #2497

tsandall
tsandall previously approved these changes Aug 12, 2021
@@ -1772,8 +1772,8 @@ func (ci *ComprehensionIndex) String() string {

func buildComprehensionIndices(dbg debug.Debug, arity func(Ref) int, candidates VarSet, rwVars map[Var]Var, node interface{}, result map[*Term]*ComprehensionIndex) uint64 {
var n uint64
cpy := candidates.Copy()
Copy link
Member

Choose a reason for hiding this comment

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

I realized that nested bodies will see candidates from subsequent expressions because of how WalkBodies and the for-loop below interact... for example:

x = 7
y = {1 | ["foo" | ...]} # array comprehension nested inside set comprehension
z = 8

In this case, the candidate set will contain x and z when the nested array comprehension body is processed.

This shouldn't be a problem in practice because if the nested array comprehension does not close over z then it won't matter. If it does close over z then z = 8 will be reordered before the outer set comprehension by an earlier stage.

@@ -3661,7 +3666,7 @@ func TestCompilerBuildComprehensionIndexKeySet(t *testing.T) {
wantDebug: 1,
},
{
note: "skip: due to nested comprehension containing candidate",
note: "skip: due to nested comprehension containing candidate + indexed nested comprehension with key from rule body",
Copy link
Member

Choose a reason for hiding this comment

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

nit: "skip:" was intended for cases where no index gets built because it produce incorrect results, worsen performance, etc. Let's use a difference prefix ("mixed:"?) since an index is built now.

Copy link
Member

Choose a reason for hiding this comment

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

nit: I'd also update the comment in the module that says 'y' disqualifies indexing ... to be a bit less ambiguous... it disqualifies indexing of the outer comprehension.

@@ -3674,6 +3679,11 @@ func TestCompilerBuildComprehensionIndexKeySet(t *testing.T) {
]
}
`,
// Note: no comprehension index for line 7 (`z = [ ...`)
expected: exp{9: {
Copy link
Member

Choose a reason for hiding this comment

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

This looks correct to me. We can index the inner comprehension but not the outer one. There was an issue in the original indexing implementation that resulted in this test case/fix: #2497

Before, we'd only looked at the vars preceding the comprehension in the body
containing it. In the case of nested comprehensions, that would have excluded
the rule body OUTSIDE of the nested body.

Now, we'll accumulate candidates over multiple bodies -- capturing the ones
that had been missing before.

Fixes open-policy-agent#3579.

Signed-off-by: Stephan Renatus <[email protected]>
@srenatus
Copy link
Contributor Author

srenatus commented Aug 16, 2021

Addressed the test comments will rebase and merge.
⌛ will run some more local tests

@srenatus srenatus force-pushed the sr/issue-3579/comprehension-cache branch from f88c9cc to 7137b9a Compare August 16, 2021 11:47
@srenatus srenatus merged commit b02a36e into open-policy-agent:main Aug 17, 2021
@srenatus srenatus deleted the sr/issue-3579/comprehension-cache branch August 17, 2021 08:39
jgchn pushed a commit to jgchn/opa that referenced this pull request Aug 20, 2021
…olicy-agent#3709)

Before, we'd only looked at the vars preceding the comprehension in the body
containing it. In the case of nested comprehensions, that would have excluded
the rule body OUTSIDE of the nested body.

Now, we'll accumulate candidates over multiple bodies -- capturing the ones
that had been missing before.

Fixes open-policy-agent#3579.

Signed-off-by: Stephan Renatus <[email protected]>
dolevf pushed a commit to dolevf/opa that referenced this pull request Nov 4, 2021
…olicy-agent#3709)

Before, we'd only looked at the vars preceding the comprehension in the body
containing it. In the case of nested comprehensions, that would have excluded
the rule body OUTSIDE of the nested body.

Now, we'll accumulate candidates over multiple bodies -- capturing the ones
that had been missing before.

Fixes open-policy-agent#3579.

Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Dolev Farhi <[email protected]>
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.

Comprehension indexing picks wrong candidates
2 participants