3 ms·
An important limitation is that the reference to the recursive table is only a reference to the newly added tuples and you're only allowed to reference the sing
by maweki 7y ago
An important limitation is that the reference to the recursive table is only a reference to the newly added tuples and you're only allowed to reference the single recursive table once. This forbids, for example, having a NOT IN of the recursive table besides the join you wanted to do anyways and it has some unexpected behavior (as you may think you reference the whole recursive table but you don't).
Limiting to linear recursion makes it less powerful and harder to program than Datalog, but the algorithm is sufficiently fast. Which is probably necessary as the recursive table is not indexed.
Also you're not only allowed UNION but also UNION ALL without a duplicate check. There every new result has to be strictly smaller than the last or you lose termination. Together with the strange referencing method to only the new tuples, this is quite a footgun.
But not to be a spoilsport, we still teach it at our University for some problems that would have required external programs to calculate the fixpoint. You just have to know the limitations which the article does not explore.
- radiowave 7y agoIt's been a few years since I ran into this, but if memory serves you can work around the limitation of only referring to the recursive table once by joining a lateral subquery into the recursive part of the query. Inside the subquery you're then free of this limitation.
- maweki 7y agoThank you for this tip. This sounds horrendous in terms of maintainability but nice to see it's possible.
- radiowave 7y agoI just found it in my notes. I don't think it looks too bad - everything you were going to do in the recursive part, you just do inside the subquery instead. WITH RECURSIVE my_cte AS ( SELECT foo, bar FROM whatever UNION ALL SELECT (s).* FROM my_cte, LATERAL ( SELECT ... -- refer to my_cte multiple times here ) s )
- hansvm 7y agoYou can also use an inner cte to copy the original table and use it as often as you like.