WITH RECURSIVE transitive_closure AS (
SELECT parent, child FROM things
UNION
SELECT tc.parent, t.child
FROM things t
JOIN transitive_closure tc ON tc.child = t.parent
)
SELECT * FROM transitive_closure;
where `transitive_closure` is a table that gets all the results of the computation. The engine will run the second part of the query repeatedly until no new rows are added to the `transitive_closure` table. (If you change `UNION` to `UNION ALL` and there's circular paths then this will not terminate.)Sounds a lot like whatever "tabling" is in Prolog.
I should probably read a bit about this again. I rarely used recursive queries in SQL when I worked with it, not least because a couple of times I did, I got into trouble because they went haywire :)
Must be. With UNION you can't end up with an infinite loop unless you have infinite data (or you're implementing a table-valued Ackermann function and so you have... not infinite results but for all practical intents, yeah).