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

(filter) expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none, has, !has, within], "match" found" #555

Closed
tordans opened this issue Mar 9, 2024 · 10 comments
Labels
help wanted Extra attention is needed

Comments

@tordans
Copy link

tordans commented Mar 9, 2024

Describe the bug

I am getting console error messages about filters which do work but still produce an error. I don't understand why they would be wrong or how to change them to prevent the error. I am merging filters in React (using react-map-gl) and only really have control over some of the filters but the external filters.

I can reproduce the error when adding a filter to the integration tests.

To Reproduce online

Steps to reproduce the behavior:

  1. Go to https://www.osm-verkehrswende.org/cqi/map/?map=12%2F13.39%2F52.518&anzeige=incompleteness
  2. Select any of the legend items to filter, eg. "Sehr unvollständig"
  3. See console: Error: layers.lane markings dashed.filter[2][0]: expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none, has, !has, within], "match" found

To Reproduce in tests

  1. Open test/integration/style-spec/tests/filters.input.json
  2. Append
        {
          "id": "mixing `match` with `==`",
          "type": "line",
          "source": "source",
          "source-layer": "source-layer",
          "filter": ["all", ["==", "Constructi", 1930], ["match", ["get", "Constructi"], [1930], true, false]]
        }
  3. Run npm run test-integration
    +   },
    +   ValidationError {
    +     "line": 166,
    +     "message": "layers[16].filter[2][0]: expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none, has, !has, within], \"match\" found",
        },

Expected behavior
I expect match filters to be valid filters the same as ==

Additional context

I was wondering it the issue is, that match has a return type of OutputType according to https://maplibre.org/maplibre-style-spec/expressions/#match whereas other listed "allowed" filter return boolean (eg in https://maplibre.org/maplibre-style-spec/expressions/#in) and all expect boolean https://maplibre.org/maplibre-style-spec/expressions/#all

@tordans
Copy link
Author

tordans commented Mar 9, 2024

Update:

When I change my test case like this

    {
      "id": "mixing `match` with `==`",
      "type": "line",
      "source": "source",
      "source-layer": "source-layer",
      "filter": ["all", ["==", "Constructi", 1930], ["match", "Constructi", [1930], true, false]]
    }

npm run test-integration works fine (AKA fails with unrelated errors).


I thing there are two things missing here …

  1. https://github.com/maplibre/maplibre-style-spec/blob/main/src/validate/validate_filter.ts#L46-L115 does not validate match, but I think it should.
  2. But more importantly https://github.com/maplibre/maplibre-style-spec/blob/main/src/reference/v8.json#L2627-L2672 does not list match as a filter_operator which is used by the validate method

However, both does not explain, why the test fails when using ['get', 'foo'] but work with just foo.
And I also don't understand why this is failing at all. Where they those changed added right after the fork and not added here?

@HarelM
Copy link
Collaborator

HarelM commented Mar 9, 2024

I haven't looked deeply into this, but the filter logic is complicated, especially with old and new syntax that do not work well together. This might be the case here, I'm not sure...

@tordans
Copy link
Author

tordans commented Mar 11, 2024

especially with old and new syntax that do not work well together.

@HarelM which part is old and which is new here? The error shows with both the get and without.

Also, is there a helper to transform old to new? I might be able to work around the whole some issues by updating the filter expressions on the fly before applying them…

@HarelM
Copy link
Collaborator

HarelM commented Mar 11, 2024

This library has a tool to migrate a style, it might not be the case in for this issue, but it's worth I shot I guess...

@HarelM
Copy link
Collaborator

HarelM commented Apr 25, 2024

@tordans is this still relevant?

@HarelM HarelM added the help wanted Extra attention is needed label Apr 25, 2024
@tordans
Copy link
Author

tordans commented Apr 25, 2024

@tordans is this still relevant?

Yes, very much. I am getting those warning everywhere and I was not able to get any hints in OsmUS Slack or offline conversations on why they are happening or how to get rid of them.

I still think there is a bug that should treat match as a valid filter option and not raise console error message when used.

The details in my initial ticket on how to reproduce on the website and in the test are still valid.

@HarelM
Copy link
Collaborator

HarelM commented Apr 28, 2024

I think the problem is with the first comparison, as this is using old syntax, I think.
Can you please check if the following solves your issue:
["all", ["==", ["get", "Constructi"], 1930], ["match", "Constructi", [1930], true, false]]

The "new" syntax will need to use "get" in order to get the property from the feature, while the old one did not use it.
From my understanding, using ["==", "Constructi", 1930] is equivalent to "false" in the new syntax as "constructi" isn't 1930 (sting to number, and different values).

I hope this helps.

@HarelM HarelM removed the bug Something isn't working label Apr 28, 2024
@wipfli
Copy link
Contributor

wipfli commented May 9, 2024

Don't you have to do ["literal", [1930]]?

@tordans
Copy link
Author

tordans commented May 10, 2024

Thanks @HarelM that does work.
@wipfli the literal results in different errors, see below.
Below some details.

I am still having issues with the example app above but after testing the same conditions in a simplified environment visgl/react-map-gl#2386 there where no issues. I have no idea why those errors show up :-/.
Will give up for now…


One thing that would be ideal for the docs like https://maplibre.org/maplibre-style-spec/expressions/#_1 where to be more explicit in the examples about how to use the second array value. Would that be something that can be merged @HarelM and if so, where does this part of the docs live?

Current:

image

For example like this:

image

Initial

{json
  "id": "mixing `match` with `==`",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", "Constructi", 1930], ["match", "Constructi", [1930], true, false]]
},
+   },
+   ValidationError {
+     "line": 166,
+     "message": "layers[16].filter[2][0]: expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none, has, !has, within], \"match\" found",
    },

Adding one get

{
  "id": "mixing `match` with `==`+get",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", ["get", "Constructi"], 1930], ["match", "Constructi", [1930], true, false]]
},
+   },
+   ValidationError {
+     "line": 167,
+     "message": "layers[16].filter[2][1]: Expected number but found string instead.",
    },

Both with get ==> This works ✅ 🥳

{
  "id": "mixing `match`+get with `==`+get",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", ["get", "Constructi"], 1930], ["match", ["get", "Constructi"], [1930], true, false]]
},
// NO ERROR

Adding literal and get causes a different error

{
  "id": "mixing `match`+literal with `==`+get",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", ["get", "Constructi"], ["literal", [1930]]], ["match", "Constructi", [1930], true, false]]
},
+   },
+   ValidationError {
+     "line": 167,
+     "message": "layers[16].filter[1][2]: \"==\" comparisons are not supported for type 'array<number, 1>'.",
    },

Just adding literal on both, same error

{
  "id": "mixing `match`+literal with `==`",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", "Constructi", ["literal", [1930]]], ["match", "Constructi", ["literal", [1930]], true, false]]
}
+   },
+   ValidationError {
+     "line": 166,
+     "message": "layers[16].filter[1][2]: \"==\" comparisons are not supported for type 'array<number, 1>'.",
    },

literal + get on both, errors due to literal as before

{
  "id": "mixing `match`+literal with `==`#literal",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", ["get","Constructi"], ["literal", [1930]]], ["match", ["get","Constructi"], ["literal", [1930]], true, false]]
}
+   },
+   ValidationError {
+     "line": 167,
+     "message": "layers[16].filter[1][2]: \"==\" comparisons are not supported for type 'array<number, 1>'.",
    },

literal just on match still shows an error

{
  "id": "mixing `match`+literal with `==`",
  "type": "line",
  "source": "source",
  "source-layer": "source-layer",
  "filter": ["all", ["==", ["get","Constructi"], 1930], ["match", ["get","Constructi"], ["literal", [1930]], true, false]]
}
+   },
+   ValidationError {
+     "line": 166,
+     "message": "layers[16].filter[2][2]: Branch labels must be numbers or strings.",
    },

@tordans tordans closed this as completed May 10, 2024
@HarelM
Copy link
Collaborator

HarelM commented May 10, 2024

The examples for the expressions exist in the v8.json file in this repo.
It should be easy to change and test, let me know if you need more help to set this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants