Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Rewrite predicate/filter conversion #7548

Merged
merged 4 commits into from
Jan 4, 2017

Conversation

1ec5
Copy link
Contributor

@1ec5 1ec5 commented Dec 26, 2016

This PR rewrites the predicate-to-filter conversion code on iOS and macOS to support more of the predicate language without crashing and also adds comprehensive unit tests for this code.

When converting predicates to filters, symmetric comparison predicates can now compare a value to a key in addition to the usual key-to-value order. Added error checking for unhandled combinations like key-to-key. Fixed a crash converting a CONTAINS predicate into a filter. Added support for constant value expressions inside aggregate expressions. Allow sets as aggregate expressions just like arrays, except in BETWEEN predicates where order matters. Flatten NOT predicates into more specialized filters.

When converting filters to predicates, use constant value expressions inside aggregate expressions. Convert to a BETWEEN predicate when possible.

Removed the predicate integration tests, which tested round-tripping but didn’t ensure correct conversion and omitted many edge cases. Replaced the integration tests with systematic unit tests for converting in either direction, plus unit tests for round-tripping and symmetry.

The unit tests required the addition of == operators for all the classes associated with mbgl::style::Filter.

Fixes #7543, fixes #7544, fixes #7545, fixes #7547.

/cc @boundsj @jfirebaugh

@1ec5 1ec5 added Core The cross-platform C++ core, aka mbgl crash iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling labels Dec 26, 2016
@1ec5 1ec5 added this to the ios-v3.4.0 milestone Dec 26, 2016
@1ec5 1ec5 self-assigned this Dec 26, 2016
@1ec5 1ec5 requested a review from frederoni December 26, 2016 23:21
@mention-bot
Copy link

@1ec5, thanks for your PR! By analyzing this pull request, we identified @boundsj, @incanus and @friedbunny to be potential reviewers.

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 26, 2016

With the new unit tests, we have much better code coverage within the predicate-related categories:

@1ec5 1ec5 mentioned this pull request Dec 28, 2016
16 tasks
auto forwardFilter = forwardPredicate.mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
if (mustRoundTrip) {
// Aggregates should round-trip, but for some reason only their format strings do.
Copy link
Contributor

@frederoni frederoni Jan 2, 2017

Choose a reason for hiding this comment

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

The forwardPredicate rhs expression is a NSConstantValueExpression(NSArray) containing plain NSNumbers initialized with ints but the forwardPredicateAfter is a NSConstantValueExpression(NSArray) containing NSConstantValueExpression(NSNumber)s initialized with longs. The wrong data type could be another bug in -[NSExpression(MGLAdditions) mgl_constantMBGLValue]? Also, shouldn't FilterEvaluator::getValues() make use of +[NSExpression expressionForAggregate:] if necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the BETWEEN case, forwardPredicateAfter is already an aggregate expression under the hood, due to the use of braces here. For the IN case, I’ll add +[NSExpression expressionForAggregate:] for consistency with BETWEEN.

I’m comfortable with the SDK “upgrading” ints to longs and literal collections to aggregates when round-tripping. While it’s unfortunate that Foundation makes distinctions here, it’s basically Postel’s Law: accepting either collections or aggregates in input, but only outputting aggregates; accepting either ints or longs in input, but only outputting longs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All set.

@jfirebaugh
Copy link
Contributor

Could you cherry pick the filter operators from https://github.com/mapbox/mapbox-gl-native/compare/deref? I need both == and < for #6900.

@1ec5 1ec5 force-pushed the 1ec5-predicate-robustness branch from ba67c03 to ea4b63c Compare January 2, 2017 23:00
jfirebaugh and others added 4 commits January 3, 2017 22:19
When converting predicates to filters, symmetric comparison predicates can now compare a value to a key in addition to the usual key-to-value order. Added error checking for unhandled combinations like key-to-key. Fixed a crash converting a CONTAINS predicate into a filter. Added support for constant value expressions inside aggregate expressions. Allow sets as aggregate expressions just like arrays, except in BETWEEN predicates where order matters. Flatten NOT predicates into more specialized filters.

When converting filters to predicates, use constant value expressions inside aggregate expressions. Convert to a BETWEEN predicate when possible.

Replaced predicate round-tripping integration tests with systematic unit tests for converting in either direction, plus unit tests for round-tripping and symmetry.

Refined exception names and messages. Realphabetized files in groups.
There’s also an “l” operator for locale sensitivity.
@1ec5 1ec5 force-pushed the 1ec5-predicate-robustness branch from ea4b63c to 3d4305b Compare January 4, 2017 06:19
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl crash iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants