| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | imchifan(at)163(dot)com |
| Subject: | BUG #19689: MERGE INSERT accepts a set-returning function during PREPARE but fails at EXECUTE |
| Date: | 2026-09-15 06:46:58 |
| Message-ID: | 19689-0a1b106035cd8a5b@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19689
Logged by: Qifan Liu
Email address: imchifan(at)163(dot)com
PostgreSQL version: 18.6
Operating system: Linux x86-64
Description:
Description
-----------
A set-returning function can be placed in the VALUES expression of a MERGE
WHEN NOT MATCHED INSERT action. PREPARE accepts the statement, but EXECUTE
fails with "set-valued function called in context that cannot accept a set"
and inserts no rows. This violates the analysis/execution contract: an
expression that the MERGE action cannot execute should be rejected while the
statement is analyzed, rather than being accepted into a prepared plan that
deterministically fails only when executed.
Impact: Applications can successfully prepare an unusable MERGE statement
and encounter a localized execution failure later. The statement inserts no
rows. This was reproduced consistently on all tested versions.
Steps to reproduce
------------------
```sql
CREATE TABLE merge_target (id integer);
CREATE TABLE merge_source (id integer);
INSERT INTO merge_source VALUES (1);
PREPARE merge_srf AS
MERGE INTO merge_target AS t
USING merge_source AS s
ON false
WHEN NOT MATCHED THEN
INSERT VALUES (generate_series(1, 2));
EXECUTE merge_srf;
SELECT count(*) AS rows_after_execution
FROM merge_target;
```
Actual result
-------------
```text
ERROR: set-valued function called in context that cannot accept a set
rows_after_execution
----------------------
0
(1 row)
```
Expected result
---------------
PREPARE should reject the set-returning function because a MERGE INSERT
action cannot execute that expression in this context. It should not create
a prepared statement that is accepted successfully and then
deterministically fails during EXECUTE.
Additional information
----------------------
The issue was reproduced on PostgreSQL 20devel, PostgreSQL 18.6, and
PostgreSQL 17.11. Inference: the MERGE INSERT action's specialized
expression handling does not propagate or enforce the restriction on
set-returning functions during analysis, leaving the executor to detect the
unsupported context.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Alexandre Felipe | 2026-09-15 06:57:32 | Re: BUG #19687: ALTER SEQUENCE provokes error XX001 could not read blocks |
| Previous Message | Andrey Rachitskiy | 2026-09-15 04:26:02 | Re: Detaching a child table makes an expression using it unrestorable |