1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
--
-- PostGIS - Spatial Types for PostgreSQL
-- http://postgis.net
--
-- Copyright (C) 2021 Sandro Santilli <strk@kbt.io>
--
-- This is free software; you can redistribute and/or modify it under
-- the terms of the GNU General Public Licence. See the COPYING file.
--
-- Author: Sandro Santilli <strk@kbt.io>
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- Invalidities are:
-- - Referenced element does not exist
-- - Same element listed twice
--
CREATE OR REPLACE FUNCTION topology.ValidateTopologyRelation(toponame varchar)
RETURNS TABLE(error text, layer_id int, topogeo_id int, element_id int)
AS
$BODY$
DECLARE
layerrec RECORD;
rel RECORD;
search_path_backup text;
BEGIN
IF NOT EXISTS (
SELECT oid
FROM pg_catalog.pg_namespace
WHERE nspname = toponame
)
THEN
RAISE EXCEPTION 'Topology schema % does not exist', toponame;
END IF;
IF NOT EXISTS (
SELECT id
FROM topology.topology
WHERE name = toponame
)
THEN
RAISE WARNING 'Topology % is not registered in topology.topology', toponame;
END IF;
EXECUTE 'SHOW search_path' INTO search_path_backup;
EXECUTE 'SET search_PATH TO ' || quote_ident(toponame) || ','
|| search_path_backup;
FOR layerrec IN SELECT * FROM topology.layer
LOOP --{
IF layerrec.child_id IS NULL
THEN --{ Layer is simple
-- Check that all referenced nodes exist
FOR rel IN
SELECT r.layer_id, r.topogeo_id, r.element_id
FROM relation r
WHERE r.layer_id = layerrec.layer_id
AND r.element_type = 1
AND r.element_id NOT IN (
SELECT node_id FROM node
)
LOOP
error := 'TopoGeometry references unexistent node';
layer_id := rel.layer_id;
topogeo_id := rel.topogeo_id;
element_id := rel.element_id;
RETURN NEXT;
END LOOP;
-- Check that all referenced edges exist
FOR rel IN
SELECT r.layer_id, r.topogeo_id, r.element_id
FROM relation r
WHERE r.layer_id = layerrec.layer_id
AND r.element_type = 2
AND abs(r.element_id) NOT IN (
SELECT edge_id FROM edge_data
)
LOOP
error := 'TopoGeometry references unexistent edge';
layer_id := rel.layer_id;
topogeo_id := rel.topogeo_id;
element_id := rel.element_id;
RETURN NEXT;
END LOOP;
-- Check that all referenced faces exist
FOR rel IN
SELECT r.layer_id, r.topogeo_id, r.element_id
FROM relation r
WHERE r.layer_id = layerrec.layer_id
AND r.element_type = 3
AND r.element_id NOT IN (
SELECT face_id FROM face
)
LOOP
error := 'TopoGeometry references unexistent face';
layer_id := rel.layer_id;
topogeo_id := rel.topogeo_id;
element_id := rel.element_id;
RETURN NEXT;
END LOOP;
ELSE -- }{ Layer is hierarchical
--RAISE DEBUG 'Checking hierarchical layer %', layerrec.layer_id;
FOR rel IN
SELECT r.layer_id, r.topogeo_id, r.element_id
FROM relation r
WHERE r.layer_id = layerrec.layer_id
AND abs(r.element_id) NOT IN (
SELECT r2.topogeo_id
FROM relation r2
WHERE r2.layer_id = layerrec.child_id
)
LOOP
error := 'TopoGeometry references unexistent child';
layer_id := rel.layer_id;
topogeo_id := rel.topogeo_id;
element_id := rel.element_id;
RETURN NEXT;
END LOOP;
END IF; --} Layer is hierarchical
END LOOP; --}
EXECUTE 'SET search_PATH TO ' || search_path_backup;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE STRICT;
|