Re: [PATCH] Allow multiple recursive self-references - Mailing list pgsql-hackers

From Denis Hirn
Subject Re: [PATCH] Allow multiple recursive self-references
Date
Msg-id D1A25F17-B840-4385-8371-7579200B9C11@uni-tuebingen.de
Whole thread Raw
In response to Re: [PATCH] Allow multiple recursive self-references  (Peter Eisentraut <peter.eisentraut@enterprisedb.com>)
Responses Re: [PATCH] Allow multiple recursive self-references  (Denis Hirn <denis.hirn@uni-tuebingen.de>)
List pgsql-hackers
>  This well-formedness check apparently needs to be enhanced to allow for more than two branches in the union.

The UNION operators' left associativity causes this problem. Currently, the recursive term
must be enclosed in parentheses to make this example work:

> WITH RECURSIVE nodes(x) AS (
>   SELECT 59
>   UNION
>   (SELECT aa FROM edge JOIN nodes ON bb=x
>   UNION
>   SELECT bb FROM edge JOIN nodes ON aa=x)
> )
> SELECT x FROM nodes;

The current well-formedness check assumes the left argument of the top most UNION [ALL]
to be the non-recursive term. This allows for arbitrarily many non-recursive terms, and
exactly one recursive term. This should not be changed because later stages expect this
structure. But this left-deep UNION [ALL] tree does not suffice anymore. Therefore, the
ctequery field of the CommonTableExpr must be rewritten –– I think.

Let's take a look at another example:

> WITH RECURSIVE nodes(x) AS (
>   SELECT 59
>   UNION
>   SELECT 42
>   UNION
>   SELECT aa FROM edge JOIN nodes ON bb=x
>   UNION -- Top most UNION operator
>   SELECT bb FROM edge JOIN nodes ON aa=x
> )
> SELECT x FROM nodes;

This would be parsed left-deep as:
((SELECT 59 UNION SELECT 42) UNION SELECT aa ...) UNION SELECT bb ...

The proposed rewriting should be able to detect that (SELECT 59 UNION SELECT 42) does
not contain any recursive references and therefore pull the term upwards in the tree,
leaving us with:

(SELECT 59 UNION SELECT 42) UNION (SELECT aa ... UNION SELECT bb ...)

Which would be the equivalent of:

> WITH RECURSIVE nodes(x) AS (
>   (SELECT 59
>   UNION
>   SELECT 42)
>   UNION -- Top most UNION operator
>   (SELECT aa FROM edge JOIN nodes ON bb=x
>   UNION
>   SELECT bb FROM edge JOIN nodes ON aa=x)
> )
> SELECT x FROM nodes;

I am not sure if this patch should introduce such a rewriting.
Any thoughts on this?

Best,
  –– Denis


pgsql-hackers by date:

Previous
From: David Rowley
Date:
Subject: Re: Avoid choose invalid number of partitions (src/backend/executor/nodeAgg.c)
Next
From: Ajin Cherian
Date:
Subject: Re: Failure of subscription tests with topminnow