From 77631f90fd602692668713dd0115cff98e9ca394 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Sat, 4 May 2024 10:16:14 +0200 Subject: [PATCH] reindex postcodes that loose their parents When the parent place of a postcode is deleted, it needs to be reindexed to get a new parent. Otherwise displaying of results is broken. --- lib-sql/functions/placex_triggers.sql | 2 ++ lib-sql/indices.sql | 3 +++ nominatim/clicmd/index.py | 1 + nominatim/tools/migration.py | 13 ++++++++++++- nominatim/version.py | 2 +- test/bdd/db/update/postcode.feature | 22 ++++++++++++++++++++++ test/python/cli/test_cli.py | 2 ++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib-sql/functions/placex_triggers.sql b/lib-sql/functions/placex_triggers.sql index 681c302d57..a40923b04a 100644 --- a/lib-sql/functions/placex_triggers.sql +++ b/lib-sql/functions/placex_triggers.sql @@ -1399,6 +1399,8 @@ BEGIN {% if debug %}RAISE WARNING 'placex_delete:12 % %',OLD.osm_type,OLD.osm_id;{% endif %} + UPDATE location_postcode SET indexed_status = 2 WHERE parent_place_id = OLD.place_id; + RETURN OLD; END; diff --git a/lib-sql/indices.sql b/lib-sql/indices.sql index 9c31f55699..8c176fdf81 100644 --- a/lib-sql/indices.sql +++ b/lib-sql/indices.sql @@ -81,6 +81,9 @@ CREATE INDEX IF NOT EXISTS idx_postcode_postcode type TEXT, deferred BOOLEAN ); +--- + CREATE INDEX IF NOT EXISTS idx_location_postcode_parent_place_id + ON location_postcode USING BTREE (parent_place_id) {{db.tablespace.address_index}}; {% endif %} -- Indices only needed for search. diff --git a/nominatim/clicmd/index.py b/nominatim/clicmd/index.py index 16b5311c79..86a504e71f 100644 --- a/nominatim/clicmd/index.py +++ b/nominatim/clicmd/index.py @@ -56,6 +56,7 @@ def run(self, args: NominatimArgs) -> int: indexer.index_boundaries(args.minrank, args.maxrank) if not args.boundaries_only: indexer.index_by_rank(args.minrank, args.maxrank) + indexer.index_postcodes() if not args.no_boundaries and not args.boundaries_only \ and args.minrank == 0 and args.maxrank == 30: diff --git a/nominatim/tools/migration.py b/nominatim/tools/migration.py index e864ce5254..02b7d19a00 100644 --- a/nominatim/tools/migration.py +++ b/nominatim/tools/migration.py @@ -384,7 +384,7 @@ def add_improved_geometry_reverse_placenode_index(conn: Connection, **_: Any) -> """) @_migration(4, 4, 99, 0) -def create_postcode_ara_lookup_index(conn: Connection, **_: Any) -> None: +def create_postcode_area_lookup_index(conn: Connection, **_: Any) -> None: """ Create index needed for looking up postcode areas from postocde points. """ with conn.cursor() as cur: @@ -392,3 +392,14 @@ def create_postcode_ara_lookup_index(conn: Connection, **_: Any) -> None: ON placex USING BTREE (country_code, postcode) WHERE osm_type = 'R' AND class = 'boundary' AND type = 'postal_code' """) + + +@_migration(4, 4, 99, 1) +def create_postcode_parent_index(conn: Connection, **_: Any) -> None: + """ Create index needed for updating postcodes when a parent changes. + """ + if conn.table_exists('planet_osm_ways'): + with conn.cursor() as cur: + cur.execute("""CREATE INDEX IF NOT EXISTS + idx_location_postcode_parent_place_id + ON location_postcode USING BTREE (parent_place_id)""") diff --git a/nominatim/version.py b/nominatim/version.py index 76da1dbd97..9ef22a8792 100644 --- a/nominatim/version.py +++ b/nominatim/version.py @@ -34,7 +34,7 @@ def __str__(self) -> str: return f"{self.major}.{self.minor}.{self.patch_level}-{self.db_patch_level}" -NOMINATIM_VERSION = NominatimVersion(4, 4, 99, 0) +NOMINATIM_VERSION = NominatimVersion(4, 4, 99, 1) POSTGRESQL_REQUIRED_VERSION = (9, 6) POSTGIS_REQUIRED_VERSION = (2, 2) diff --git a/test/bdd/db/update/postcode.feature b/test/bdd/db/update/postcode.feature index c6696ddae8..393181012c 100644 --- a/test/bdd/db/update/postcode.feature +++ b/test/bdd/db/update/postcode.feature @@ -102,3 +102,25 @@ Feature: Update of postcode | country | postcode | geometry | | de | 01982 | country:de | And there are word tokens for postcodes 01982 + + Scenario: When a parent is deleted, the postcode gets a new parent + Given the grid with origin DE + | 1 | | 3 | 4 | + | | 9 | | | + | 2 | | 5 | 6 | + Given the places + | osm | class | type | name | admin | geometry | + | R1 | boundary | administrative | Big | 6 | (1,4,6,2,1) | + | R2 | boundary | administrative | Small | 6 | (1,3,5,2,1) | + Given the named places + | osm | class | type | addr+postcode | geometry | + | N9 | place | postcode | 12345 | 9 | + When importing + And updating postcodes + Then location_postcode contains exactly + | country | postcode | geometry | parent_place_id | + | de | 12345 | 9 | R2 | + When marking for delete R2 + Then location_postcode contains exactly + | country | postcode | geometry | parent_place_id | + | de | 12345 | 9 | R1 | diff --git a/test/python/cli/test_cli.py b/test/python/cli/test_cli.py index 998bccb434..12a58d075b 100644 --- a/test/python/cli/test_cli.py +++ b/test/python/cli/test_cli.py @@ -129,11 +129,13 @@ def test_index_command(self, mock_func_factory, table_factory, table_factory('import_status', 'indexed bool') bnd_mock = mock_func_factory(nominatim.indexer.indexer.Indexer, 'index_boundaries') rank_mock = mock_func_factory(nominatim.indexer.indexer.Indexer, 'index_by_rank') + postcode_mock = mock_func_factory(nominatim.indexer.indexer.Indexer, 'index_postcodes') assert self.call_nominatim('index', *params) == 0 assert bnd_mock.called == do_bnds assert rank_mock.called == do_ranks + assert postcode_mock.called == do_ranks def test_special_phrases_wiki_command(self, mock_func_factory):