Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x6PgT-000Dar-29 for pgsql-bugs@arkaria.postgresql.org; Tue, 15 Sep 2026 09:42:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1x6PgT-0016gc-01 for pgsql-bugs@arkaria.postgresql.org; Tue, 15 Sep 2026 09:42:37 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x6Mwe-0002oA-25 for pgsql-bugs@lists.postgresql.org; Tue, 15 Sep 2026 06:47:08 +0000 Received: from mahout.postgresql.org ([2001:4800:3e1:1::227]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1x6Mwc-0000000093Q-1pvq for pgsql-bugs@lists.postgresql.org; Tue, 15 Sep 2026 06:47:07 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Message-ID:Date:Reply-To:Cc:From:To:Subject: Content-Transfer-Encoding:MIME-Version:Content-Type:Sender:Content-ID: Content-Description:In-Reply-To:References; bh=m4cEE4KJ8X07e+/jhtVW8W774FcAK7LdqXHa3x2LsmQ=; b=0K9QtcHRVQats1aWcRnY3tRfly hv7xyAILj2ruoXp6sytja62si+cgZ/Ct/LyxUqmhr1SWPDcoiY7SBEaUrisSavE8qYC/G8rFeh45E +YlLi/pEIHW0ruX2dRkHNe2ywOhIexh+io6rCSHj7bdb1FZGftq5SE23gsSRWMVGNJL+jV7bNpBMr YP+BlqAUGkeZ5qBDv1nvPMPTBX5EwjKfhGg3OGuOxGd4uN29uogSIHfk8vAxHnHjfn4Ng71Z+x/j/ GlfYIUKK9sKMAOsxNdUcVOFZSPA1cCD938PQQgIb6udWnvHSp6RqiG5s7YCha6zPpS1L6pP+QlqVc qU34h2rg==; Received: from wrigleys.postgresql.org ([2a02:16a8:dc51::60]) by mahout.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x6Mwa-000Pv3-1l for pgsql-bugs@lists.postgresql.org; Tue, 15 Sep 2026 06:47:06 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1x6MwZ-00000003dep-0BG4 for pgsql-bugs@lists.postgresql.org; Tue, 15 Sep 2026 06:47:03 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19689: MERGE INSERT accepts a set-returning function during PREPARE but fails at EXECUTE To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: imchifan@163.com Reply-To: imchifan@163.com, pgsql-bugs@lists.postgresql.org Date: Tue, 15 Sep 2026 06:46:58 +0000 Message-ID: <19689-0a1b106035cd8a5b@postgresql.org> X-Auto-Response-Suppress: All Auto-Submitted: auto-generated List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk The following bug has been logged on the website: Bug reference: 19689 Logged by: Qifan Liu Email address: imchifan@163.com PostgreSQL version: 18.6 Operating system: Linux x86-64 Description: =20 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.