-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ensure in-memory evaluation of QualifierOperatorContains selector has…
… the same result as generated SQL fetch. When using EOQualifier.QualifierOperatorContains selector with a keyPath that has multiple manyToMany and/or toMany keys the in-Memory evaluation will incorrectly return false in the cases where the result of the keyPath is nested arrays rather than a flattened array that represents the effective SQL evaluation for the same qualifier. Thus in-Memory evaluation does not match the behavior of SQL evaluation in this scenario. This fix flattens the array object resulting from the valueForKeyPath so that the qualifier will correctly evaluate to true when checking if the flattened array contains the object being evaluated.
- Loading branch information
1 parent
58ddfea
commit ea23f97
Showing
1 changed file
with
40 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ea23f97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Kieran,
I have a new solution for this issue and it's more general (not only for QualifierOperatorContains).
With this fix we can evaluate this kind of qualifier in-memory: A.QualY.dot(B.QualX).dot(C.QualW).eq(1)
Can you give me your feedback on it?
thanks
@OverRide
public boolean evaluateWithObject(Object object){
if(super.evaluateWithObject(object)){
return true;
}
Object objectValue = NSKeyValueCodingAdditions.Utility.valueForKeyPath(object, _key);
if (objectValue instanceof NSArray) { for (Object value : (NSArray) objectValue) {
NSDictionary<String, Object> newObject = new NSDictionary<String, Object>(value, _key);
if(evaluateWithObject(newObject)){
return true;
}
}
}
return false;
}
ea23f97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm .... not sure if your logic is something that is desired with the end result of the key-path is a toMany. At first glance I don't feel comfortable with such a general change since it seems to me it is changing fundamentally how EOKeyValueQualifier, which is used ubiquitously, functions and could introduce all kinds of unexpected problems. A general, aka large impact, change like this needs serious testing to guarantee backwards compatability, hence why the original change was so very very specific. My vote would be no since I don't see advantage to it or need it.
ea23f97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your feedback. I will try to better explain my solution.
Advantages and need
Effectively your solution is good and I’m not trying to find a better way to solve the problem, but actually if you try to evaluate qualifier in-memory like this: A.QualB.dot(B.QualX).eq(1), it’s impossible because WebObjects returns an empty array. So I tried to find a way to solve the problem. After I found the solution, I realize that my Wonder was not up-to-date and I saw your solution. I made a few tests and realized that my solution worked with QualifierOperatorContains in-memory too. Can you just confirm that my fix could replace yours, wherever you used it?
Risks
To evaluate the risks that could possibly introduce all kinds of unexpected problems, I will comment each line of my solution.
I don’t think that I changed how EOKeyValueQualifier works fundamentally. I used exactly the code of WebObjects without a copy. To guarantee backwards compatibility, we can add a property to isolate the new code, but I think that my solution opens a new path that never worked before.
Logic
When we are with a key-path toMany, we try finding an object in a list. This is exactly what my solution does.
ea23f97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.