# `WITH MUTUALLY RECURSIVE` ## Summary Progressively introduce support for `WITH MUTUALLY RECURSIVE` common table expressions, as demonstrated in https://github.com/MaterializeInc/database-issues/issues/3264. This alternate form of `WITH` requires column names and identifiers for each binding, but allows all bindings to reference each other bindings, and introduces support for recursion and mutual recursion. ## Goals Support for a correct implementation of `WITH MUTUALLY RECURSIVE`. There are likely several subgoals, corresponding to steps along the way. These include support in at least each of the following layers. 1. SQL parsing 2. SQL name resolution 3. SQL planning 4. HIR generalization 5. Lowering 6. MIR generalization 7. MIR optimization corrections 8. LIR generalization 9. Rendering The one intentional restriction is to avoid support for nested mutually recursive fragments. These are not likely to be renderable in the foreseeable future, as they cannot necessarily be flattened to a single mutually recursive scope. ## Non-Goals 1. Support for SQL's `WITH RECURSIVE`. This is a tortured construct with surprising semantics. Instead `WITH MUTUALLY RECURSIVE` be easier to parse, plan, optimize, and render. We should learn from this in ways that may inform whether we want to later support `WITH RECURSIVE`. 2. Optimization for recursive queries. There are several optimization patterns that recursive queries benefit from. For this design doc, we are only hoping to produce not-incorrect recursive queries. 3. Nested mutual recursion. There should either be at most one `WITH MUTUALLY RECURSIVE`, or appear so after query optimization. We are not able to render nested mutually recursive fragements. ## Description Much of this is taken from https://github.com/MaterializeInc/database-issues/issues/3264. We can extend SQL's `WITH` fragment with a new variant, not strictly more general, which looks like ```sql WITH MUTUALLY RECURSIVE name_1 (col1a type1a, col1b type1b, ... ) AS ( ), name_3 (col3a type3a, col3b type3b, ... ) AS (