From 55c56c7bb429202774e34dca9d2c26ae325e3043 Mon Sep 17 00:00:00 2001 From: Vyacheslav Kompan Date: Tue, 7 Nov 2023 20:50:04 +0500 Subject: [PATCH] Fix potential memleak with singleton CTE subplan --- src/backend/optimizer/path/allpaths.c | 17 ++++++++++++++--- src/test/regress/expected/with.out | 4 ++-- src/test/regress/sql/with.sql | 4 ++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 7b7855985ad8..1ad8b2d8b369 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -2140,9 +2140,20 @@ set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) * shared plan with another SegmentGeneral node. Thus, we should avoid * sharing SegmentGeneral subplans. */ - subplan = (cteplaninfo->subplan->flow->locustype != CdbLocusType_SegmentGeneral) ? - share_prepared_plan(cteroot, cteplaninfo->subplan) : - (Plan *) copyObject(cteplaninfo->subplan); + if (cteplaninfo->subplan->flow->locustype != CdbLocusType_SegmentGeneral) + { + subplan = share_prepared_plan(cteroot, cteplaninfo->subplan); + } + else + { + /* + * If we are not sharing and subplan was created just now, use it. + * Otherwise, make a copy of it to avoid construction of DAG + * instead of a tree. + */ + if (subplan == NULL) + subplan = (Plan *) copyObject(cteplaninfo->subplan); + } subroot = cteplaninfo->subroot; } diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out index aa9f4d078c40..13a1f36fa30e 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -2290,9 +2290,9 @@ DROP TABLE IF EXISTS r; NOTICE: table "r" does not exist, skipping --end_ignore CREATE TABLE d (a int, b int) DISTRIBUTED BY (a); -INSERT INTO d VALUES (1,2),(2,3); +INSERT INTO d VALUES ( 1, 2 ),( 2, 3 ); CREATE TABLE r (a int, b int) DISTRIBUTED REPLICATED; -INSERT INTO r VALUES (1,2),(3,4); +INSERT INTO r VALUES ( 1, 2 ),( 3, 4 ); EXPLAIN (COSTS off) WITH cte AS ( SELECT count(*) a FROM r diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index fa50ff2c6905..0fe41e0860e6 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -1093,9 +1093,9 @@ DROP TABLE IF EXISTS r; --end_ignore CREATE TABLE d (a int, b int) DISTRIBUTED BY (a); -INSERT INTO d VALUES (1,2),(2,3); +INSERT INTO d VALUES ( 1, 2 ),( 2, 3 ); CREATE TABLE r (a int, b int) DISTRIBUTED REPLICATED; -INSERT INTO r VALUES (1,2),(3,4); +INSERT INTO r VALUES ( 1, 2 ),( 3, 4 ); EXPLAIN (COSTS off) WITH cte AS (