From e309d471e847c34e144de06be3dc7c33b0571938 Mon Sep 17 00:00:00 2001 From: Derek Lieu Date: Thu, 25 Jul 2019 15:07:32 -0700 Subject: [PATCH] Fix #8504 remove duplicate match exp from filter conversion (#8542) * Demonstrate filter conversion outputting invalid match expression * Filter duplicate values when outputting match expressions * Use a sorting method less likely to blow up at big O * Tighten up sort expression --- src/style-spec/feature_filter/convert.js | 4 +++- test/unit/style-spec/feature_filter.test.js | 26 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/style-spec/feature_filter/convert.js b/src/style-spec/feature_filter/convert.js index 1998eabc87a..3a863bc6871 100644 --- a/src/style-spec/feature_filter/convert.js +++ b/src/style-spec/feature_filter/convert.js @@ -187,7 +187,9 @@ function convertInOp(property: string, values: Array, negate = false) { } if (uniformTypes && (type === 'string' || type === 'number')) { - return ['match', get, values, !negate, negate]; + // Match expressions must have unique values. + const uniqueValues = values.sort().filter((v, i) => i === 0 || values[i - 1] !== v); + return ['match', get, uniqueValues, !negate, negate]; } return [ negate ? 'all' : 'any' ].concat( diff --git a/test/unit/style-spec/feature_filter.test.js b/test/unit/style-spec/feature_filter.test.js index 3cf91545f40..1eb86ba80f5 100644 --- a/test/unit/style-spec/feature_filter.test.js +++ b/test/unit/style-spec/feature_filter.test.js @@ -121,7 +121,7 @@ test('convert legacy filters to expressions', t => { [ "match", ["geometry-type"], - ["Polygon", "LineString", "Point"], + ["LineString", "Point", "Polygon"], true, false ], @@ -139,6 +139,30 @@ test('convert legacy filters to expressions', t => { t.end(); }); + t.test('removes duplicates when outputting match expressions', (t) => { + const filter = [ + "in", + "$id", + 1, + 2, + 3, + 2, + 1 + ]; + + const expected = [ + "match", + ["id"], + [1, 2, 3], + true, + false + ]; + + const converted = convertFilter(filter); + t.same(converted, expected); + t.end(); + }); + t.end(); });