Puedes evitar la necesidad de una consulta recursiva adoptando el siguiente enfoque:
- De cada LineString de entrada, extraiga los puntos finales en un MultiPoint de dos puntos
- Ejecutar
ST_ClusterWithin
en los puntos finales extraídos
- Une espacialmente las agrupaciones de puntos finales a las geometrías originales.
He aquí un ejemplo:
CREATE TABLE test_lines (id serial, geom geometry);
INSERT INTO test_lines (geom)
VALUES
('LINESTRING (0 0, 1 1)'),
('LINESTRING (2 2, 1 1)'),
('LINESTRING (7 3, 0 0)'),
('LINESTRING (2 4, 2 3)'),
('LINESTRING (3 8, 1 5)'),
('LINESTRING (1 5, 2 5)'),
('LINESTRING (7 3, 0 7)');
WITH endpoints AS (SELECT ST_Collect(ST_StartPoint(geom), ST_EndPoint(geom)) AS geom FROM test_lines),
clusters AS (SELECT unnest(ST_ClusterWithin(geom, 1e-8)) AS geom FROM endpoints),
clusters_with_ids AS (SELECT row_number() OVER () AS cid, ST_CollectionHomogenize(geom) AS geom FROM clusters)
SELECT ST_Collect(test_lines.geom) AS geom
FROM test_lines
LEFT JOIN clusters_with_ids ON ST_Intersects(test_lines.geom, clusters_with_ids.geom)
GROUP BY cid;
El resultado son las tres MultiLineStrings siguientes: