Skip to content

Commit

Permalink
Fix filter eval for cached queries (MID-5422)
Browse files Browse the repository at this point in the history
EqualFilter.match method was improved so that even if it encounters
raw value in object being matched it tries to apply the definition
from the filter (if known).
  • Loading branch information
mederly committed Jun 18, 2019
1 parent ab0f990 commit ade968d
Showing 1 changed file with 24 additions and 4 deletions.
Expand Up @@ -22,6 +22,7 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.EqualFilter;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.prism.xml.ns._public.types_3.RawType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -137,16 +138,35 @@ private void checkPrismPropertyValue(Object value) {
}
}

private boolean matches(PrismPropertyValue<?> value1, PrismPropertyValue<?> value2, MatchingRule<?> matchingRule) {
private <T1> boolean matches(PrismPropertyValue<?> filterValue, PrismPropertyValue<?> objectValue, MatchingRule<T1> matchingRule) {
Object filterRealValue = filterValue.getRealValue();
Object objectRealValue = objectValue.getRealValue();
try {
if (matchingRule.match(value1.getRealValue(), value2.getRealValue())) {
return true;
if (!(objectRealValue instanceof RawType)) {
//noinspection unchecked
if (matchingRule.match((T1) filterRealValue, (T1) objectRealValue)) {
return true;
}
} else {
PrismPropertyDefinition<?> definition = getDefinition();
if (definition != null) {
// We clone here to avoid modifying original data structure.
Object parsedObjectRealValue = ((RawType) objectRealValue).clone().getParsedRealValue(definition, definition.getName());
//noinspection unchecked
return matchingRule.match((T1) filterRealValue, (T1) parsedObjectRealValue);
} else {
throw new IllegalStateException("Couldn't compare raw value with definition-less filter value: " + filterRealValue);
}
}
} catch (SchemaException e) {
// At least one of the values is invalid. But we do not want to throw exception from
// a comparison operation. That will make the system very fragile. Let's fall back to
// ordinary equality mechanism instead.
if (Objects.equals(value1.getRealValue(), value2.getRealValue())) {
// TODO this can be quite dangerous, however. See MID-5459.
// For example, when comparing objects to determine the need for cache invalidation we should be 100% certain
// that we get the correct result. Otherwise we might keep outdated object in the cache.
// Matching during authorization evaluation is a similar theme.
if (Objects.equals(filterRealValue, objectRealValue)) {
return true;
}
}
Expand Down

0 comments on commit ade968d

Please sign in to comment.