1818CREATE OR REPLACE FUNCTION topology.FixCorruptTopoGeometryColumn(layerSchema name, layerTable name, layerColumn name)
1919RETURNS text AS
2020$$
21- DECLARE var_sql text; var_row_count bigint; result text;
21+ DECLARE var_sql text; var_row_count bigint; result text; var_create_index_sql text; var_drop_index_sql text;
2222BEGIN
23+ result = '';
2324 -- if topogeometry is bigint, then fix damaged integer, need to upgrade to bigint
2425 IF EXISTS ( SELECT 1
2526 FROM pg_catalog.pg_type AS pg_type
2627 JOIN pg_catalog.pg_class AS pg_class ON pg_class.oid = pg_type.typrelid
2728 JOIN pg_catalog.pg_attribute AS pga ON pga.attrelid = pg_class.oid
2829 JOIN pg_catalog.pg_type AS pg_attr_type on pg_attr_type.oid = pga.atttypid
29- WHERE pg_type.typname::regtype::text = 'topogeometry' AND pga.attname = 'id'
30+ WHERE pg_type.typname = 'topogeometry' AND pga.attname = 'id'
3031 AND
3132 pg_type.typnamespace::regnamespace::text = 'topology' AND pga.atttypid::regtype::text = 'bigint' ) THEN
33+
34+ -- generate index scripts to create and drop indexes that are based on the column
35+ IF EXISTS( SELECT 1 FROM pg_indexes WHERE schemaname = layerSchema AND tablename = layerTable AND indexdef LIKE '%(' || layerColumn || ')%' ) THEN
36+ SELECT string_agg(indexdef, ';'), string_agg('DROP INDEX ' || quote_ident(schemaname) || '.' || quote_ident(indexname), ';') INTO var_create_index_sql, var_drop_index_sql
37+ FROM pg_indexes
38+ WHERE schemaname = layerSchema
39+ AND tablename = layerTable AND indexdef LIKE ('%(' || layerColumn || ')%');
40+ END IF;
41+
42+ IF var_drop_index_sql > '' THEN
43+ EXECUTE var_drop_index_sql;
44+ END IF;
45+
46+ -- correct any corrupt topogeometries and fix
3247 var_sql = format('UPDATE %1$I.%2$I
3348 SET
3449 %3$I = (
3550 (%3$I).topology_id,
3651 (%3$I).layer_id,
37- (%3$I).id & 0xFFFFFFFF,
38- (%3$I).id >> 32
52+ (( %3$I).id & 0xFFFFFFFF)::bigint ,
53+ (( %3$I).id >> 32)::integer
3954 )::topology.topogeometry
40- WHERE ( (%3$I).id & 0xFFFFFFFF ) <> (%3$I).id OR ( (%3$I).id >> 32 ) = (%3$I).type ', layerSchema, layerTable, layerColumn);
55+ WHERE ( (%3$I).id & 0xFFFFFFFF )::bigint <> (%3$I).id OR ( (%3$I).id >> 32 )::integer = (%3$I).type ', layerSchema, layerTable, layerColumn);
4156
4257 EXECUTE var_sql;
4358 GET DIAGNOSTICS var_row_count = ROW_COUNT;
44- result = format('%s rows updated for %s.%s.%s column to bigint id type', var_row_count, layerSchema, layerTable, layerColumn);
59+
60+ IF var_create_index_sql > '' THEN
61+ EXECUTE var_create_index_sql;
62+ result = result || E'\n' || 'Recreating indexes';
63+ END IF;
64+ result = result || E'\n' || format('%s rows updated for %s.%s.%s column to bigint id type', var_row_count, layerSchema, layerTable, layerColumn);
4565 ELSE --we are coming from bigint and going back to integer
4666 var_sql = format('UPDATE %1$I.%2$I
4767 SET
@@ -55,7 +75,7 @@ WHERE pg_type.typname::regtype::text = 'topogeometry' AND pga.attname = 'id'
5575 WHERE l.topology_id = (%3$I).topology_id AND l.layer_id = (%3$I).layer_id AND (%3$I).type <> l.feature_type ', topo_schema, topo_table, topo_column);
5676 EXECUTE var_sql;
5777 GET DIAGNOSTICS var_row_count = ROW_COUNT;
58- result = format('%s rows updated for %s.%s.%s column back to integer id type', var_row_count, topo_schema, topo_table, topo_column);
78+ result = result || format('%s rows updated for %s.%s.%s column back to integer id type', var_row_count, topo_schema, topo_table, topo_column);
5979 END IF;
6080 RETURN result;
6181END
0 commit comments