summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/parser/parse_relation.c8
-rw-r--r--src/test/regress/expected/returning.out10
-rw-r--r--src/test/regress/sql/returning.sql6
3 files changed, 23 insertions, 1 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 679bf640c62..101fba34b18 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -125,7 +125,10 @@ static bool isQueryUsingTempRelation_walker(Node *node, void *context);
* that (a) has no alias and (b) is for the same relation identified by
* schemaname.refname. In this case we convert schemaname.refname to a
* relation OID and search by relid, rather than by alias name. This is
- * peculiar, but it's what SQL says to do.
+ * peculiar, but it's what SQL says to do. While processing a query's
+ * RETURNING list, there may be additional namespace items for OLD and NEW,
+ * with the same relation OID as the target namespace item. These are
+ * ignored in the search, since they don't match by schemaname.refname.
*/
ParseNamespaceItem *
refnameNamespaceItem(ParseState *pstate,
@@ -255,6 +258,9 @@ scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
/* If not inside LATERAL, ignore lateral-only items */
if (nsitem->p_lateral_only && !pstate->p_lateral_active)
continue;
+ /* Ignore OLD/NEW namespace items that can appear in RETURNING */
+ if (nsitem->p_returning_type != VAR_RETURNING_DEFAULT)
+ continue;
/* yes, the test for alias == NULL should be there... */
if (rte->rtekind == RTE_RELATION &&
diff --git a/src/test/regress/expected/returning.out b/src/test/regress/expected/returning.out
index 6bd36a811fc..d1394c67833 100644
--- a/src/test/regress/expected/returning.out
+++ b/src/test/regress/expected/returning.out
@@ -766,6 +766,16 @@ DELETE FROM zerocol
(1 row)
DROP TABLE zerocol;
+-- Test schema-qualified table name in RETURNING list
+CREATE TABLE public.tt(a int, b int);
+INSERT INTO public.tt VALUES (1, 10);
+UPDATE public.tt SET b = b * 2 RETURNING a, b, old.b, new.b, tt.b, public.tt.b;
+ a | b | b | b | b | b
+---+----+----+----+----+----
+ 1 | 20 | 10 | 20 | 20 | 20
+(1 row)
+
+DROP TABLE public.tt;
-- Test cross-partition updates and attribute mapping
CREATE TABLE foo_parted (a int, b float8, c text) PARTITION BY LIST (a);
CREATE TABLE foo_part_s1 PARTITION OF foo_parted FOR VALUES IN (1);
diff --git a/src/test/regress/sql/returning.sql b/src/test/regress/sql/returning.sql
index b7258a3d97e..54caf56244c 100644
--- a/src/test/regress/sql/returning.sql
+++ b/src/test/regress/sql/returning.sql
@@ -312,6 +312,12 @@ DELETE FROM zerocol
new.tableoid::regclass, new.ctid, ctid, *;
DROP TABLE zerocol;
+-- Test schema-qualified table name in RETURNING list
+CREATE TABLE public.tt(a int, b int);
+INSERT INTO public.tt VALUES (1, 10);
+UPDATE public.tt SET b = b * 2 RETURNING a, b, old.b, new.b, tt.b, public.tt.b;
+DROP TABLE public.tt;
+
-- Test cross-partition updates and attribute mapping
CREATE TABLE foo_parted (a int, b float8, c text) PARTITION BY LIST (a);
CREATE TABLE foo_part_s1 PARTITION OF foo_parted FOR VALUES IN (1);