Re: BUG #16801: Invalid memory access on WITH RECURSIVE with nested WITHs
Michael Paquier <michael@paquier.xyz>
From: Michael Paquier <michael@paquier.xyz>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alexander Lakhin <exclusion@gmail.com>, pgsql-bugs@lists.postgresql.org
Date: 2021-02-25T02:30:36Z
Lists: pgsql-bugs
On Wed, Feb 24, 2021 at 09:13:46PM -0500, Tom Lane wrote:
> Michael Paquier <michael@paquier.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
Commits
-
Fix list-manipulation bug in WITH RECURSIVE processing.
- 80ca8464fe02 14.0 landed
- 49076fd3ba6b 13.3 landed