1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Track nesting depth correctly when drilling down into RECORD Vars.

expandRecordVariable() failed to adjust the parse nesting structure
correctly when recursing to inspect an outer-level Var.  This could
result in assertion failures or core dumps in corner cases.

Likewise, get_name_for_var_field() failed to adjust the deparse
namespace stack correctly when recursing to inspect an outer-level
Var.  In this case the likely result was a "bogus varno" error
while deparsing a view.

Per bug #18077 from Jingzhou Fu.  Back-patch to all supported
branches.

Richard Guo, with some adjustments by me

Discussion: https://postgr.es/m/18077-b9db97c6e0ab45d8@postgresql.org
This commit is contained in:
Tom Lane
2023-09-15 17:01:26 -04:00
parent 1988f8766e
commit ae13f8166d
4 changed files with 122 additions and 24 deletions

View File

@@ -1209,6 +1209,66 @@ select r, r is null as isnull, r is not null as isnotnull from r;
(,) | t | f
(6 rows)
--
-- Check parsing of indirect references to composite values (bug #18077)
--
explain (verbose, costs off)
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select * from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
QUERY PLAN
--------------------------------------------
CTE Scan on cte
Output: cte.c
Filter: ((SubPlan 3) IS NOT NULL)
CTE cte
-> Result
Output: '(1,2)'::record
SubPlan 3
-> Result
Output: cte.c
One-Time Filter: $2
InitPlan 2 (returns $2)
-> Result
Output: ((cte.c).f1 > 0)
(13 rows)
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select * from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
c
-------
(1,2)
(1 row)
-- Also check deparsing of such cases
create view composite_v as
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select 1 as one from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
select pg_get_viewdef('composite_v', true);
pg_get_viewdef
--------------------------------------------------------
WITH cte(c) AS MATERIALIZED ( +
SELECT ROW(1, 2) AS "row" +
), cte2(c) AS ( +
SELECT cte.c +
FROM cte +
) +
SELECT 1 AS one +
FROM cte2 t +
WHERE (( SELECT s.c1 +
FROM ( SELECT t.c AS c1) s +
WHERE ( SELECT (s.c1).f1 > 0))) IS NOT NULL;
(1 row)
drop view composite_v;
--
-- Tests for component access / FieldSelect
--

View File

@@ -487,6 +487,31 @@ with r(a,b) as materialized
(null,row(1,2)), (null,row(null,null)), (null,null) )
select r, r is null as isnull, r is not null as isnotnull from r;
--
-- Check parsing of indirect references to composite values (bug #18077)
--
explain (verbose, costs off)
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select * from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select * from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
-- Also check deparsing of such cases
create view composite_v as
with cte(c) as materialized (select row(1, 2)),
cte2(c) as (select * from cte)
select 1 as one from cte2 as t
where (select * from (select c as c1) s
where (select (c1).f1 > 0)) is not null;
select pg_get_viewdef('composite_v', true);
drop view composite_v;
--
-- Tests for component access / FieldSelect