PL/pgSQL
This should be a valid translation to plpgsql:
CREATE OR REPLACE FUNCTION f_near(_middlesystemname text, _jumpsaway int)
RETURNS TABLE(fromid int, toid int, jumps int, name text, security text) AS
$func$
DECLARE
_jumps integer;
BEGIN
CREATE TEMP TABLE map AS
SELECT -1 AS "fromSolarSystemID"
,m."solarSystemID" AS "toSolarSystemID"
,0 AS level
FROM "mapSolarSystems" m
WHERE "solarSystemName" = _middlesystemname;
-- potentially add indexes on the temp table and ANALYZE if it gets big
FOR _jumps IN 1 .. _jumpsaway LOOP
INSERT INTO map ("fromSolarSystemID", "toSolarSystemID", level)
SELECT sj."fromSolarSystemID", sj."toSolarSystemID", _jumps AS level
FROM "mapSolarSystemJumps" sj
JOIN map m ON m."toSolarSystemID" = sj."fromSolarSystemID"
AND m."level" = _jumps - 1
LEFT JOIN map mx ON mx."fromSolarSystemID" = sj."fromSolarSystemID"
WHERE mx."fromSolarSystemID" IS NULL;
END LOOP;
RETURN QUERY
SELECT m.*, s."solarSystemName", s."security"
FROM map m
JOIN "mapSolarSystems" s ON m."toSolarSystemID" = s."solarSystemID";
END
$func$ LANGUAGE plpgsql;
RECURSIVE CTE - doesn't seem to work
This short SQL query with a recursive CTE should have done it:
WITH RECURSIVE map AS (
SELECT -1 AS fromsolarsystemid, m.solarsystemid, 0 AS level
FROM mapsolarsystems m
WHERE m.solarsystemname = from_id
UNION ALL
SELECT sj.fromsolarsystemid, sj.tosolarsystemid, level + 1
FROM mapsolarsystemjumps sj
JOIN map m USING (level)
LEFT JOIN map mx USING (fromsolarsystemid)
WHERE sj.fromsolarsystemid = m.tosolarsystemid
AND mx.fromsolarsystemid IS NULL
AND m.level < 10 -- jumpsAway
)
SELECT m.*, s.solarsystemname, s.security
FROM map m
JOIN mapsolarsystems s ON m.tosolarsystemid = s.solarsystemid
-- WHERE s.security < 0.45 -- uncomment to check all nearby lowsec system
However:
ERROR: recursive reference to query "map" must not appear within an outer join LINE 9: LEFT JOIN map mx USING (fromsolarsystemid)