summaryrefslogtreecommitdiff
path: root/src/test/regress
diff options
context:
space:
mode:
authorAlvaro Herrera2022-04-12 07:29:39 +0000
committerAlvaro Herrera2022-04-12 07:29:39 +0000
commitce4f46fdc814eb1b704d81640f6d8f03625d0f53 (patch)
tree782a82bc2a2a811751ea053ee9793d252d296011 /src/test/regress
parenta4b57543acfb52cc7c7e031501002563f536b929 (diff)
Change mechanism to set up source targetlist in MERGE
We were setting MERGE source subplan's targetlist by expanding the individual attributes of the source relation completely, early in the parse analysis phase. This failed to work when the condition of an action included a whole-row reference, causing setrefs.c to error out with ERROR: variable not found in subplan target lists because at that point there is nothing to resolve the whole-row reference with. We can fix this by having preprocess_targetlist expand the source targetlist for Vars required from the source rel by all actions. Moreover, by using this expansion mechanism we can do away with the targetlist expansion in transformMergeStmt, which is good because then we no longer pull in columns that aren't needed for anything. Add a test case for the problem. While at it, remove some redundant code in preprocess_targetlist(): MERGE was doing separately what is already being done for UPDATE/DELETE, so we can just rely on the latter and remove the former. (The handling of inherited rels was different for MERGE, but that was a no-longer- necessary hack.) Fix outdated, related comments for fix_join_expr also. Author: Richard Guo <guofenglinux@gmail.com> Author: Álvaro Herrera <alvherre@alvh.no-ip.org> Reported-by: Joe Wildish <joe@lateraljoin.com> Discussion: https://postgr.es/m/fab3b90a-914d-46a9-beb0-df011ee39ee5@www.fastmail.com
Diffstat (limited to 'src/test/regress')
-rw-r--r--src/test/regress/expected/merge.out13
-rw-r--r--src/test/regress/expected/with.out6
-rw-r--r--src/test/regress/sql/merge.sql9
3 files changed, 25 insertions, 3 deletions
diff --git a/src/test/regress/expected/merge.out b/src/test/regress/expected/merge.out
index 5954f10b8ff..0fd037b45a8 100644
--- a/src/test/regress/expected/merge.out
+++ b/src/test/regress/expected/merge.out
@@ -791,6 +791,19 @@ SELECT * FROM wq_target;
1 | 299
(1 row)
+-- check source-side whole-row references
+BEGIN;
+MERGE INTO wq_target t
+USING wq_source s ON (t.tid = s.sid)
+WHEN matched and t = s or t.tid = s.sid THEN
+ UPDATE SET balance = t.balance + s.balance;
+SELECT * FROM wq_target;
+ tid | balance
+-----+---------
+ 1 | 399
+(1 row)
+
+ROLLBACK;
-- check if subqueries work in the conditions?
MERGE INTO wq_target t
USING wq_source s ON t.tid = s.sid
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index 7c6de7cc07c..57e145b0f5a 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -2800,7 +2800,7 @@ WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v);
-> Result
Output: 1, 'cte_basic val'::text
-> Hash Right Join
- Output: (0), ('merge source SubPlan'::text), m.ctid
+ Output: m.ctid, (0), ('merge source SubPlan'::text)
Hash Cond: (m.k = (0))
-> Seq Scan on public.m
Output: m.ctid, m.k
@@ -2847,7 +2847,7 @@ WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v);
Output: (cte_init.b || ' merge update'::text)
Filter: (cte_init.a = 1)
-> Hash Right Join
- Output: (1), ('merge source InitPlan'::text), m.ctid
+ Output: m.ctid, (1), ('merge source InitPlan'::text)
Hash Cond: (m.k = (1))
-> Seq Scan on public.m
Output: m.ctid, m.k
@@ -2889,7 +2889,7 @@ WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text
-> CTE Scan on merge_source_cte merge_source_cte_2
Output: ((merge_source_cte_2.*)::text || ' merge insert'::text)
-> Hash Right Join
- Output: merge_source_cte.a, merge_source_cte.b, m.ctid
+ Output: m.ctid, merge_source_cte.a, merge_source_cte.b
Hash Cond: (m.k = merge_source_cte.a)
-> Seq Scan on public.m
Output: m.ctid, m.k
diff --git a/src/test/regress/sql/merge.sql b/src/test/regress/sql/merge.sql
index 6d05a2f39ca..8815e0cc498 100644
--- a/src/test/regress/sql/merge.sql
+++ b/src/test/regress/sql/merge.sql
@@ -527,6 +527,15 @@ WHEN MATCHED AND t.balance = 199 OR s.balance > 100 THEN
UPDATE SET balance = t.balance + s.balance;
SELECT * FROM wq_target;
+-- check source-side whole-row references
+BEGIN;
+MERGE INTO wq_target t
+USING wq_source s ON (t.tid = s.sid)
+WHEN matched and t = s or t.tid = s.sid THEN
+ UPDATE SET balance = t.balance + s.balance;
+SELECT * FROM wq_target;
+ROLLBACK;
+
-- check if subqueries work in the conditions?
MERGE INTO wq_target t
USING wq_source s ON t.tid = s.sid