diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 9ff80b8b40..255f485494 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -184,8 +184,10 @@ setTargetTable(ParseState *pstate, RangeVar *relation, RangeTblEntry *rte; int rtindex; - /* So far special relations are immutable; so they cannot be targets. */ + /* Check if it's a CTE or tuplestore reference */ rte = getRTEForSpecialRelationTypes(pstate, relation); + + /* So far special relations are immutable; so they cannot be targets. */ if (rte != NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1072,6 +1074,12 @@ transformRangeTableSample(ParseState *pstate, RangeTableSample *rts) } +/* + * getRTEForSpecialRelationTypes + * + * If given RangeVar if a CTE reference or an EphemeralNamedRelation, return + * the transformed RangeVar otherwise return NULL + */ static RangeTblEntry * getRTEForSpecialRelationTypes(ParseState *pstate, RangeVar *rv) { @@ -1079,6 +1087,13 @@ getRTEForSpecialRelationTypes(ParseState *pstate, RangeVar *rv) Index levelsup; RangeTblEntry *rte = NULL; + /* + * if it is a qualified name, it can't be a CTE or tuplestore + * reference + */ + if (rv->schemaname) + return NULL; + cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup); if (cte) rte = transformCTEReference(pstate, rv, cte, levelsup); @@ -1119,15 +1134,11 @@ transformFromClauseItem(ParseState *pstate, Node *n, /* Plain relation reference, or perhaps a CTE reference */ RangeVar *rv = (RangeVar *) n; RangeTblRef *rtr; - RangeTblEntry *rte = NULL; + RangeTblEntry *rte; int rtindex; - /* - * if it is an unqualified name, it might be a CTE or tuplestore - * reference - */ - if (!rv->schemaname) - rte = getRTEForSpecialRelationTypes(pstate, rv); + /* Check if it's a CTE or tuplestore reference */ + rte = getRTEForSpecialRelationTypes(pstate, rv); /* if not found above, must be a table reference */ if (!rte) diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out index c32a490580..53ea9991b2 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -2275,3 +2275,7 @@ with ordinality as (select 1 as x) select * from ordinality; -- check sane response to attempt to modify CTE relation WITH d AS (SELECT 42) INSERT INTO d VALUES (1); ERROR: relation "d" cannot be the target of a modifying statement +-- check qualified relation name doesn't conflict with CTE name +CREATE TABLE public.self (id integer); +WITH self AS (SELECT 42) INSERT INTO public.self SELECT * from self; +DROP TABLE public.self; diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index 8ae5184d0f..17f32c3c87 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -1031,3 +1031,8 @@ with ordinality as (select 1 as x) select * from ordinality; -- check sane response to attempt to modify CTE relation WITH d AS (SELECT 42) INSERT INTO d VALUES (1); + +-- check qualified relation name doesn't conflict with CTE name +CREATE TABLE public.self (id integer); +WITH self AS (SELECT 42) INSERT INTO public.self SELECT * from self; +DROP TABLE public.self;