X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/b5c61e0b5b4e9f955d55c2368cdc904f9390b288..b2afe3ce3ec7df3691a85462802b547b3d34ce4a:/nominatim/db/sqlalchemy_functions.py?ds=sidebyside diff --git a/nominatim/db/sqlalchemy_functions.py b/nominatim/db/sqlalchemy_functions.py index 8b196738..f576d32f 100644 --- a/nominatim/db/sqlalchemy_functions.py +++ b/nominatim/db/sqlalchemy_functions.py @@ -55,7 +55,7 @@ class IntersectsReverseDistance(sa.sql.functions.GenericFunction[Any]): inherit_cache = True def __init__(self, table: sa.Table, geom: SaColumn) -> None: - super().__init__(table.c.geometry, # type: ignore[no-untyped-call] + super().__init__(table.c.geometry, table.c.rank_search, geom) self.tablename = table.name @@ -117,24 +117,12 @@ def sqlite_is_below_reverse_distance(element: IsBelowReverseDistance, compiler.process(rank, **kw)) -def select_index_placex_geometry_reverse_lookupplacenode(table: str) -> 'sa.TextClause': - """ Create an expression with the necessary conditions over a placex - table that the index 'idx_placex_geometry_reverse_lookupPlaceNode' - can be used. - """ - return sa.text(f"{table}.rank_address between 4 and 25" - f" AND {table}.type != 'postcode'" - f" AND {table}.name is not null" - f" AND {table}.linked_place_id is null" - f" AND {table}.osm_type = 'N'") - - class IsAddressPoint(sa.sql.functions.GenericFunction[Any]): name = 'IsAddressPoint' inherit_cache = True def __init__(self, table: sa.Table) -> None: - super().__init__(table.c.rank_address, # type: ignore[no-untyped-call] + super().__init__(table.c.rank_address, table.c.housenumber, table.c.name) @@ -200,6 +188,7 @@ def sqlite_json_array_each(element: JsonArrayEach, compiler: 'sa.Compiled', **kw return "json_each(%s)" % compiler.process(element.clauses, **kw) + class Greatest(sa.sql.functions.GenericFunction[Any]): """ Function to compute maximum of all its input parameters. """ @@ -210,3 +199,23 @@ class Greatest(sa.sql.functions.GenericFunction[Any]): @compiles(Greatest, 'sqlite') # type: ignore[no-untyped-call, misc] def sqlite_greatest(element: Greatest, compiler: 'sa.Compiled', **kw: Any) -> str: return "max(%s)" % compiler.process(element.clauses, **kw) + + + +class RegexpWord(sa.sql.functions.GenericFunction[Any]): + """ Check if a full word is in a given string. + """ + name = 'RegexpWord' + inherit_cache = True + + +@compiles(RegexpWord, 'postgresql') # type: ignore[no-untyped-call, misc] +def postgres_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str: + arg1, arg2 = list(element.clauses) + return "%s ~* ('\\m(' || %s || ')\\M')::text" % (compiler.process(arg2, **kw), compiler.process(arg1, **kw)) + + +@compiles(RegexpWord, 'sqlite') # type: ignore[no-untyped-call, misc] +def sqlite_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str: + arg1, arg2 = list(element.clauses) + return "regexp('\\b(' || %s || ')\\b', %s)" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))