On Thu, Mar 27, 2025 at 12:02 PM Renan Alves Fonseca
<renanfons...@gmail.com> wrote:
> WITH RECURSIVE t1 AS ( SELECT 1 UNION  SELECT generate_series(2,3) FROM t1 
> ORDER BY  1 DESC) SELECT * FROM t1 ;
>
> The parser attaches the "order by" clause to the "union" operator, and then 
> we error out with the following message: "ORDER BY in a recursive query is 
> not implemented"
>
> The comment in the code (parser_cte.c:900) says "Disallow ORDER BY and 
> similar decoration atop the UNION". Then, if we wrap the recursive clause 
> around parentheses:
>
> WITH RECURSIVE t1 AS ( SELECT 1 UNION  (SELECT generate_series(2,3) FROM t1 
> ORDER BY  1 DESC)) SELECT * FROM t1 ;
>
> It works as expected. So, do we support the ORDER BY in a recursive query or 
> not?

A recursive CTE effectively takes two queries that will be run as
arguments. For some reason, instead of choosing syntax like WITH
RECURSIVE t1 AS BASE_CASE (initial_query) RECURSIVE_CASE
(iterated_query), somebody chose WITH RECURSIVE t1 AS (initial_query
UNION iterated_query) which really doesn't make it very clear that we
need to be able to break it apart into two separate queries, one of
which will be run once and one of which will be iterated.

It's not a problem if UNION ALL is used within the initial_query and
it's not a problem if UNION ALL is used within the iterated_query. But
you can't apply ORDER BY to the result of the UNION, because the UNION
is kind of fake -- we're not running the UNION as a single query,
we're running the two halves separately, the first once and the second
as many times as needed.

-- 
Robert Haas
EDB: http://www.enterprisedb.com


Reply via email to