On Fri, 04 Sep 2026, Ewan Young <[email protected]> wrote:
> - Kahn's algorithm implementation looks right.

Not entirely, the implementation assumes that the graph is a DAG with
an assert, which unfortunately isn't the case:

At src/backend/commands/tablecmds.c:17958-17964 (ATExecAddInherit)

This is not completely bulletproof because of race conditions: in
multi-level inheritance trees, someone else could concurrently be
making another inheritance link that closes the loop but does not join
either of the rels we have locked. ...  find_all_inheritors() will
cope with circularity anyway, so don't sweat it too much."

This can be reproduced a parallel alter, e.g.:

With r->b, b->c, d->e already in place:
S1:  begin; alter table d inherit c;   -- AEL(d), SUE(c), AS(d,e)
S2:  begin; alter table b inherit e;   -- AEL(b), SUE(e), AS(b,c)
S1:  commit;
S2:  commit;

And then alters can either hit the

Assert(list_length(ordered) == list_length(agenda));

assertion in debug builds or end up with a inconsistent results in
release builds.


Reply via email to