pygeoapi icon indicating copy to clipboard operation
pygeoapi copied to clipboard

Inverting conditions in CQL expression with NOT() throws error

Open sebastianfrey opened this issue 4 months ago • 7 comments

Description Inverting conditions in a CQL filter expression with NOT throws an error.

{
  "code": "InvalidParameterValue",
  "type": "InvalidParameterValue",
  "description": "Bad CQL text"
}

Steps to Reproduce Try the to execute the following query:

~~https://demo.pygeoapi.io/master/collections/lakes/items?filter=NOT(%20LIKE%20%27%lake%%27)~~ https://demo.pygeoapi.io/master/collections/lakes/items?filter=NOT%20(name%20LIKE%20%27%lake%%27)

The URL decoded CQL expression is:

NOT(name LIKE '%lake%')

Expected behavior Inverting conditions with NOT() should not throw an error.

Environment

  • OS: -
  • Python version: -
  • pygeoapi version: 0.20-dev

Additional context Add any other context about the problem here.

sebastianfrey avatar Sep 10 '25 19:09 sebastianfrey

Might be related to #2015.

sebastianfrey avatar Sep 10 '25 19:09 sebastianfrey

Adding "name" and removing the parens seems to succeed:

https://demo.pygeoapi.io/master/collections/lakes/items?filter=name%20NOT%20LIKE%20%27%25lake%25%27

The lakes collection is backed by the geojson provider so the CQL doesn't actually filter anything, but it appears to me like it's parsed correctly

mikemahoney218-usgs avatar Sep 10 '25 19:09 mikemahoney218-usgs

Hi @mikemahoney218-usgs , thank you for your feedback.

Sorry for the wrong URL, the issue is updated now and contains the correct URL to reproduce the Bad CQL error.

Regarding the re-arranged query:

You are correct, name NOT LIKE 'lake' is parsed correctly.

But as I understand the CQL spec correctly, negating the whole LIKE expression with NOT should also work. At least there are multiple conformance tests for this case, e.g. https://docs.ogc.org/is/21-065r2/21-065r2.html#_conformance_test_14.

sebastianfrey avatar Sep 10 '25 19:09 sebastianfrey

After doing some more tests, it seems that inverting a condition with NOT is not supported at all. All of the following query's result in a Bad CQL error:

https://demo.pygeoapi.io/master/collections/lakes/items?filter=NOT%20(name=%27Lake%20Baikal%27) https://demo.pygeoapi.io/master/collections/lakes/items?filter=NOT%20(name%3C%3E%27Lake%20Baikal%27) https://demo.pygeoapi.io/master/collections/lakes/items?filter=NOT(scalerank%3E0)

sebastianfrey avatar Sep 10 '25 19:09 sebastianfrey

Given pygeoapi uses pygeofilter under the hood for filter handling, suggest moving this issue to the pygeofilter issue tracker.

Testing with pygeofilter CLI (main branch):

$ pygeofilter parse cql2_text "NOT(name LIKE '%lake%')"
Parsing cql2_text query into AST
Error: Unexpected token Token('LIKE', 'LIKE') at line 1, column 10.
Expected one of: 
	* RPAR

$ pygeofilter parse cql2_text "NOT(foo=0)"
Parsing cql2_text query into AST
Error: Unexpected token Token('EQUAL', '=') at line 1, column 8.
Expected one of: 
	* RPAR

$ pygeofilter parse cql2_text "NOT(foo>0)"
Parsing cql2_text query into AST
Error: Unexpected token Token('MORETHAN', '>') at line 1, column 8.
Expected one of: 
	* RPAR


tomkralidis avatar Sep 14 '25 15:09 tomkralidis

This Issue has been inactive for 90 days. As per RFC4, in order to manage maintenance burden, it will be automatically closed in 7 days.

github-actions[bot] avatar Dec 14 '25 04:12 github-actions[bot]

Bump

sebastianfrey avatar Dec 14 '25 07:12 sebastianfrey