diff --git a/src/common/backend/parser/parse_expr.cpp b/src/common/backend/parser/parse_expr.cpp index 4c28146a3..c8a07513f 100644 --- a/src/common/backend/parser/parse_expr.cpp +++ b/src/common/backend/parser/parse_expr.cpp @@ -1393,6 +1393,7 @@ static Node* transformAExprOp(ParseState* pstate, A_Expr* a) static Node* transformAExprAnd(ParseState* pstate, A_Expr* a) { + a->rexpr = (Node *)copyObject(a->rexpr); Node* lexpr = transformExprRecurse(pstate, a->lexpr); Node* rexpr = transformExprRecurse(pstate, a->rexpr); diff --git a/src/gausskernel/optimizer/plan/subselect.cpp b/src/gausskernel/optimizer/plan/subselect.cpp index 74a3cfcb2..80d2ea3f1 100644 --- a/src/gausskernel/optimizer/plan/subselect.cpp +++ b/src/gausskernel/optimizer/plan/subselect.cpp @@ -1925,12 +1925,6 @@ static void inline_cte(PlannerInfo *root, CommonTableExpr *cte) (void) inline_cte_walker((Node*)root->parse, &context); - /* - * We would expect the reference number to be zero after inline, however, the - * reference count of cte are not accurate for re-entry issues at parsing stage - * Until fixed, we only check for non-negative refcnt result. - */ - Assert(context.refcount >= 0); /* Mark this CTE as inlined */ cte->cterefcount = -1; } diff --git a/src/test/regress/expected/with_002.out b/src/test/regress/expected/with_002.out new file mode 100644 index 000000000..8db53b931 --- /dev/null +++ b/src/test/regress/expected/with_002.out @@ -0,0 +1,81 @@ +-- create table +create table t_cte(a int, b int); +insert into t_cte select generate_series(1,5), generate_series(1,5); +create table int8_tbl (q1 int8, q2 int8); +INSERT INTO INT8_TBL VALUES + (' 123 ',' 456'); +-- check case where CTE reference is removed due to optimization +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + QUERY PLAN +--------------------------------------------- + Subquery Scan on ss + Output: ss.q1 + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, (SubPlan 2) + CTE t_cte + -> Seq Scan on public.int8_tbl t + Output: t.q1, t.q2 + SubPlan 2 + -> CTE Scan on t_cte + Output: t_cte.q2 + Filter: (t_cte.q1 = i8.q1) +(11 rows) + +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + q1 +----- + 123 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + QUERY PLAN +--------------------------------------------- + Subquery Scan on ss + Output: ss.q1 + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, (SubPlan 2) + CTE t_cte + -> Seq Scan on public.int8_tbl t + Output: t.q1, t.q2 + SubPlan 2 + -> CTE Scan on t_cte + Output: t_cte.q2 + Filter: (t_cte.q1 = i8.q1) +(11 rows) + +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + q1 +----- + 123 +(1 row) + +SELECT ( WITH table2 AS NOT MATERIALIZED ( SELECT 1 ) SELECT 1 FROM ( SELECT ( SELECT 1 FROM table2 ) BETWEEN 1 AND 1 ) AS alias6 ) ; + ?column? +---------- + 1 +(1 row) + +drop table t_cte; +drop table int8_tbl cascade; diff --git a/src/test/regress/parallel_schedule0B b/src/test/regress/parallel_schedule0B index ca26dd1ef..3c20d4eba 100644 --- a/src/test/regress/parallel_schedule0B +++ b/src/test/regress/parallel_schedule0B @@ -328,6 +328,7 @@ test: hw_pct_type_and_rowtype #test: create_basetype #test: tabletype #test with recursive +test: with_002 test: recursive_ref_recursive #test: recursive_prepare #test: recursive_cte diff --git a/src/test/regress/sql/with_002.sql b/src/test/regress/sql/with_002.sql new file mode 100644 index 000000000..467ecae9d --- /dev/null +++ b/src/test/regress/sql/with_002.sql @@ -0,0 +1,45 @@ +-- create table +create table t_cte(a int, b int); +insert into t_cte select generate_series(1,5), generate_series(1,5); + +create table int8_tbl (q1 int8, q2 int8); +INSERT INTO INT8_TBL VALUES + (' 123 ',' 456'); + + +-- check case where CTE reference is removed due to optimization +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +SELECT q1 FROM +( + WITH t_cte AS (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + +SELECT q1 FROM +( + WITH t_cte AS MATERIALIZED (SELECT * FROM int8_tbl t) + SELECT q1, (SELECT q2 FROM t_cte WHERE t_cte.q1 = i8.q1) AS t_sub + FROM int8_tbl i8 +) ss; + + +SELECT ( WITH table2 AS NOT MATERIALIZED ( SELECT 1 ) SELECT 1 FROM ( SELECT ( SELECT 1 FROM table2 ) BETWEEN 1 AND 1 ) AS alias6 ) ; + +drop table t_cte; +drop table int8_tbl cascade;