Repository navigation
Conversation
ECQL keywords are case-insensitive, and the CQL2-text grammar already
matches them that way ("AND"i, ...), but the ECQL grammar only accepted
upper case: `attr like 'x'` or `a = 1 and b = 2` failed with
UnexpectedToken. Clients built against case-insensitive CQL
implementations (e.g. pycsw's cql2fes for CSW CQL_TEXT) send lowercase
keywords, which break when pycsw parses CQL_TEXT with pygeofilter.
Mark every ECQL keyword literal case-insensitive and upper-case the
spatial predicate name before looking it up, as the CQL2-text parser
does. Attribute names that start with a keyword (`notes`, `index`,
`orbit`) still lex as names.
Refs geopython#121
epifanio
force-pushed
the
ecql-case-insensitive-keywords
branch
from
October 13, 2026 13:52
f181b00 to
dde3644
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #121.
Problem
The ECQL grammar only matches keywords in upper case, so these fail with
UnexpectedToken:ECQL keywords are case-insensitive, and the CQL2-text grammar here already matches them that way (
"AND"i, …). As noted in #121, the ECQL grammar was left case-sensitive. That affects servers that parse user CQL with the ECQL parser. For example, pycsw parses CSWCQL_TEXTconstraints with it for repositories that don't use a database. Long-standing CSW clients sendapiso:Type like 'series', which pycsw's owncql2fespath accepts but this parser rejects.Change
ecql/grammar.lark: every keyword literal is now case-insensitive ("LIKE"→"LIKE"i, etc.), including the spatial and temporal predicates,ENVELOPE, andDOES-NOT-EXIST. Distance units and the shared WKT grammar are unchanged.ecql/parser.py: upper-case the spatial predicate name before theSPATIAL_PREDICATES_MAPlookup and theDWITHINcheck. Those rules keep the matched token, sointersects(...)would otherwise raise aKeyError. This matches what the CQL2-text parser does withop.lower().Tests
test_keywords_case_insensitive: each keyword form (boolean, comparison,LIKE/ILIKE/IN/IS NULL,EXISTS/DOES-NOT-EXIST,INCLUDE/EXCLUDE, temporal, spatial,RELATE,DWITHIN/BEYOND,BBOX,ENVELOPE), in lower case and title case, must parse to the same AST as upper case. Onmainthese 54 cases fail; with this change they pass.test_attribute_names_starting_with_keywords:notes,index,orbit,likes,isbn,androidandbetween_xstill lex as attribute names. These pass both before and after the change.tests/parsers: 369 passed.ruff checkandruff format --checkwith the pinned v0.11.13 are clean.