Skip to content

CQL2 CASEI support for sqlalchemy backend? #135

@mikemahoney218-usgs

Description

@mikemahoney218-usgs

CQL2's CASEI function is supported in parsing, but is not supported by the sqlalchemy backend:

Python 3.12.8 (main, Jan  5 2025, 06:55:30) [Clang 19.1.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from sqlalchemy import Column, String
>>> from pygeofilter.parsers.cql2_text import parse
>>> from pygeofilter.backends.sqlalchemy.evaluate import to_filter
>>> to_filter(parse("road_class IN ('Οδος','Straße')"), { "road_class": Column(String) })
<sqlalchemy.sql.elements.BinaryExpression object at 0x12241bf80>
>>> to_filter(parse("CASEI(road_class) IN (CASEI('Οδος'),CASEI('Straße'))"), { "road_class": Column(String) })
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjmahoney/codebase/scratch/pygeofilter_test/.venv/lib/python3.12/site-packages/pygeofilter/backends/sqlalchemy/evaluate.py", line 148, in to_filter
    return SQLAlchemyFilterEvaluator(field_mapping, undefined_as_null).evaluate(ast)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/mjmahoney/codebase/scratch/pygeofilter_test/.venv/lib/python3.12/site-packages/pygeofilter/backends/evaluator.py", line 103, in evaluate
    sub_args = [self.evaluate(sub_node, False) for sub_node in subnodes]
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/mjmahoney/codebase/scratch/pygeofilter_test/.venv/lib/python3.12/site-packages/pygeofilter/backends/evaluator.py", line 111, in evaluate
    result = self.adopt(node, *sub_args)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/mjmahoney/codebase/scratch/pygeofilter_test/.venv/lib/python3.12/site-packages/pygeofilter/backends/evaluator.py", line 122, in adopt
    raise NotImplementedError(f"Failed to evaluate node of type {type(node)}")
NotImplementedError: Failed to evaluate node of type <class 'pygeofilter.ast.Function'>
# note that parse works fine, the error arises in the evaluation
>>> parse("CASEI(road_class) IN (CASEI('Οδος'),CASEI('Straße'))"), { "road_class": Column(String) }
(In(lhs=Function(name='lower', arguments=[ATTRIBUTE road_class]), sub_nodes=[Function(name='lower', arguments=['Οδος']), Function(name='lower', arguments=['Straße'])], not_=False), {'road_class': Column(None, String(), table=None)})

Is there any chance this could be supported by the sqlalchemy backend?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions