From fc1d68953aae07a0eddd35283ec13eda95160c0c Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Fri, 24 Apr 2026 10:55:58 +0800
Subject: [PATCH v6 1/1] FOR PORTION OF move TargetRange check to
 ExecInitModifyTable

While at it, add errcode to surrounding code

discussion: https://postgr.es/m/626986.1776785090%40sss.pgh.pa.us
commitfest entry: https://commitfest.postgresql.org/patch/
---
 src/backend/executor/nodeModifyTable.c | 6 ++++++
 src/backend/parser/analyze.c           | 3 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 4cb057ca4f9..4c4eff10b20 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -5591,6 +5591,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 			ExecAssignExprContext(estate, &mtstate->ps);
 		econtext = mtstate->ps.ps_ExprContext;
 
+		if (contain_volatile_functions_after_planning((Expr *) forPortionOf->targetRange))
+			ereport(ERROR,
+					errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+					errmsg("FOR PORTION OF bounds cannot contain volatile functions"));
+
 		exprState = ExecPrepareExpr((Expr *) forPortionOf->targetRange, estate);
 		targetRange = ExecEvalExpr(exprState, econtext, &isNull);
 
@@ -5600,6 +5605,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 		 */
 		if (isNull)
 			ereport(ERROR,
+					errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 					(errmsg("FOR PORTION OF target was null")),
 					executor_errposition(estate, forPortionOf->targetLocation));
 
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index ffcf25a6be7..216fbe2367c 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -1489,9 +1489,6 @@ transformForPortionOfClause(ParseState *pstate,
 													args,
 													InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
 	}
-	if (contain_volatile_functions_after_planning((Expr *) result->targetRange))
-		ereport(ERROR,
-				(errmsg("FOR PORTION OF bounds cannot contain volatile functions")));
 
 	/*
 	 * Build overlapsExpr to use as an extra qual. This means we only hit rows
-- 
2.34.1

