Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Alexander Lakhin <exclusion(at)gmail(dot)com>, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs
Date: 2021-02-25 02:30:36
Message-ID: YDcLzKuQJmKOZYq+@paquier.xyz
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Wed, Feb 24, 2021 at 09:13:46PM -0500, Tom Lane wrote:
> Michael Paquier <michael(at)paquier(dot)xyz> writes:
>> WITH RECURSIVE outermost(x) AS (
>> SELECT 1
>> UNION (WITH innermost as (WITH innermost2 AS (SELECT 2) SELECT * FROM innermost2)
>> SELECT * FROM outermost
>> UNION SELECT * FROM innermost)
>> )
>> SELECT * FROM outermost ORDER BY 1;
>
> Hmm, I don't see any failure from that...

Perhaps because you are not compiling with -DUSE_VALGRIND which is why
this fails with only two nested levels? I get a failure once I do
that.

> In my understanding of the bug, you need at least half a dozen levels of
> WITH nesting to provoke a problem, because nothing will go wrong until the
> innerwiths list gets to be six entries long, causing list.c to move its
> elements array to somewhere else. If it is possible to fail without that
> then there's still something here that I don't get.

Anyway, I also get a failure without -DUSE_VALGRIND once I apply 6
nested levels:
#1 0x00007ff47eb5b537 in __GI_abort () at abort.c:79
#2 0x000055b24c7b340e in ExceptionalCondition
(conditionName=0x55b24c8e917a "cstate->innerwiths == NIL",
errorType=0x55b24c8e8803 "FailedAssertion",
fileName=0x55b24c8e8a08 "parse_cte.c", lineNumber=869) at
assert.c:69
#3 0x000055b24c2db9a5 in checkWellFormedRecursion
(cstate=0x7ffe2fce8a30) at parse_cte.c:869

Here you go with a test case:
WITH RECURSIVE outermost(x) AS (
SELECT 1
UNION (WITH innermost1 AS (
SELECT 2
UNION (WITH innermost2 AS (
SELECT 3
UNION (WITH innermost3 AS (
SELECT 4
UNION (WITH innermost4 AS (
SELECT 5
UNION (WITH innermost5 AS (
SELECT 6
UNION (WITH innermost6 AS (SELECT 7)
SELECT * FROM innermost6))
SELECT * FROM innermost5))
SELECT * FROM innermost4))
SELECT * FROM innermost3))
SELECT * FROM innermost2))
SELECT * FROM outermost
UNION SELECT * FROM innermost1)
)
SELECT * FROM outermost ORDER BY 1;

My previous patch and HEAD break on that in
checkWellFormedRecursionWalker(), not your patch.
--
Michael

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2021-02-25 02:48:03 Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs
Previous Message Michael Paquier 2021-02-25 02:17:09 Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs