vgc-excluded-fix.patch
application/octet-stream
Filename: vgc-excluded-fix.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/setrefs.c | 3 | 1 |
| src/test/regress/expected/generated_virtual.out | 52 | 0 |
| src/test/regress/sql/generated_virtual.sql | 29 | 0 |
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index ff0e875f..bb254079 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -167,6 +167,7 @@ static void set_param_references(PlannerInfo *root, Plan *plan);
static Node *convert_combining_aggrefs(Node *node, void *context);
static void set_dummy_tlist_references(Plan *plan, int rtoffset);
static indexed_tlist *build_tlist_index(List *tlist);
+static indexed_tlist *build_tlist_index_other_vars(List *tlist, int ignore_rel);
static Var *search_indexed_tlist_for_var(Var *var,
indexed_tlist *itlist,
int newvarno,
@@ -1168,7 +1169,8 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
{
indexed_tlist *itlist;
- itlist = build_tlist_index(splan->exclRelTlist);
+ itlist = build_tlist_index_other_vars(splan->exclRelTlist,
+ 0);
splan->onConflictSet =
fix_join_expr(root, splan->onConflictSet,
diff --git a/src/test/regress/expected/generated_virtual.out b/src/test/regress/expected/generated_virtual.out
index fc41c480..8f5ad91b 100644
--- a/src/test/regress/expected/generated_virtual.out
+++ b/src/test/regress/expected/generated_virtual.out
@@ -1723,3 +1723,55 @@ select * from gtest33 where b is null;
reset constraint_exclusion;
drop table gtest33;
+-- Ensure that EXCLUDED.<virtual-generated-column> in INSERT ... ON CONFLICT
+-- DO UPDATE is expanded to the generation expression, both for plain and
+-- partitioned target relations. Previously, the plan-time setrefs step
+-- would re-collapse the expanded expression into a Var referring to the
+-- virtual attnum of the EXCLUDED slot, producing either an "unexpected
+-- virtual generated column reference" error (plain table) or a silent NULL
+-- (partitioned table, via tuple routing's attribute remapping).
+create table gtest34 (id int primary key, a int,
+ c int generated always as (a * 10) virtual);
+insert into gtest34 values (1, 5);
+insert into gtest34 values (1, 7)
+ on conflict (id) do update set a = excluded.c returning *;
+ id | a | c
+----+----+-----
+ 1 | 70 | 700
+(1 row)
+
+insert into gtest34 values (1, 2)
+ on conflict (id) do update set a = gtest34.c + excluded.c returning *;
+ id | a | c
+----+-----+------
+ 1 | 720 | 7200
+(1 row)
+
+insert into gtest34 values (1, 3)
+ on conflict (id) do update set a = 999 where excluded.c > 20 returning *;
+ id | a | c
+----+-----+------
+ 1 | 999 | 9990
+(1 row)
+
+drop table gtest34;
+create table gtest34p (id int primary key, a int,
+ c int generated always as (a * 10) virtual)
+ partition by range (id);
+create table gtest34p_1 partition of gtest34p for values from (1) to (100);
+insert into gtest34p values (1, 5);
+insert into gtest34p values (1, 7)
+ on conflict (id) do update set a = excluded.c returning *;
+ id | a | c
+----+----+-----
+ 1 | 70 | 700
+(1 row)
+
+insert into gtest34p values (1, 2)
+ on conflict (id) do update set a = gtest34p.c + excluded.c returning *;
+ id | a | c
+----+-----+------
+ 1 | 720 | 7200
+(1 row)
+
+drop table gtest34p;
diff --git a/src/test/regress/sql/generated_virtual.sql b/src/test/regress/sql/generated_virtual.sql
index 9b32413e..6e958011 100644
--- a/src/test/regress/sql/generated_virtual.sql
+++ b/src/test/regress/sql/generated_virtual.sql
@@ -906,3 +906,32 @@ select * from gtest33 where b is null;
reset constraint_exclusion;
drop table gtest33;
+
+-- Ensure that EXCLUDED.<virtual-generated-column> in INSERT ... ON CONFLICT
+-- DO UPDATE is expanded to the generation expression, both for plain and
+-- partitioned target relations. Previously, the plan-time setrefs step
+-- would re-collapse the expanded expression into a Var referring to the
+-- virtual attnum of the EXCLUDED slot, producing either an "unexpected
+-- virtual generated column reference" error (plain table) or a silent NULL
+-- (partitioned table, via tuple routing's attribute remapping).
+create table gtest34 (id int primary key, a int,
+ c int generated always as (a * 10) virtual);
+insert into gtest34 values (1, 5);
+insert into gtest34 values (1, 7)
+ on conflict (id) do update set a = excluded.c returning *;
+insert into gtest34 values (1, 2)
+ on conflict (id) do update set a = gtest34.c + excluded.c returning *;
+insert into gtest34 values (1, 3)
+ on conflict (id) do update set a = 999 where excluded.c > 20 returning *;
+drop table gtest34;
+
+create table gtest34p (id int primary key, a int,
+ c int generated always as (a * 10) virtual)
+ partition by range (id);
+create table gtest34p_1 partition of gtest34p for values from (1) to (100);
+insert into gtest34p values (1, 5);
+insert into gtest34p values (1, 7)
+ on conflict (id) do update set a = excluded.c returning *;
+insert into gtest34p values (1, 2)
+ on conflict (id) do update set a = gtest34p.c + excluded.c returning *;
+drop table gtest34p;