v7-0001-FOR-PORTION-OF-guard-against-FDW.patch
text/x-patch
Filename: v7-0001-FOR-PORTION-OF-guard-against-FDW.patch
Type: text/x-patch
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: format-patch
Series: patch v7-0001
Subject: FOR PORTION OF guard against FDW
| File | + | − |
|---|---|---|
| contrib/postgres_fdw/expected/postgres_fdw.out | 17 | 2 |
| contrib/postgres_fdw/sql/postgres_fdw.sql | 19 | 2 |
| src/backend/commands/copyfrom.c | 1 | 1 |
| src/backend/executor/execMain.c | 8 | 1 |
| src/backend/executor/execPartition.c | 2 | 2 |
| src/backend/executor/nodeModifyTable.c | 1 | 1 |
| src/backend/parser/analyze.c | 0 | 6 |
| src/include/executor/executor.h | 1 | 1 |
From e47bf332d6620d2820e7a93b5475a2a1456bd1c7 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Fri, 24 Apr 2026 12:43:50 +0800
Subject: [PATCH v7 1/1] FOR PORTION OF guard against FDW
discussion: https://postgr.es/m/626986.1776785090%40sss.pgh.pa.us
commitfest entry: https://commitfest.postgresql.org/patch/
---
.../postgres_fdw/expected/postgres_fdw.out | 19 +++++++++++++++--
contrib/postgres_fdw/sql/postgres_fdw.sql | 21 +++++++++++++++++--
src/backend/commands/copyfrom.c | 2 +-
src/backend/executor/execMain.c | 9 +++++++-
src/backend/executor/execPartition.c | 4 ++--
src/backend/executor/nodeModifyTable.c | 2 +-
src/backend/parser/analyze.c | 6 ------
src/include/executor/executor.h | 2 +-
8 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 10e87acabef..a0b796a4a12 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -6334,9 +6334,20 @@ DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass;
(1 row)
-- Test UPDATE FOR PORTION OF
+CREATE TABLE ftpp (
+ c1 int4range NOT NULL,
+ c2 int NOT NULL,
+ c3 text,
+ c4 daterange NOT NULL
+) PARTITION BY RANGE (c2);
+ALTER TABLE ftpp ATTACH PARTITION ft8 FOR VALUES FROM (1) TO (150);
+UPDATE ftpp FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
+SET c2 = c2 + 1
+WHERE c1 = '[1,2)'; -- error
+ERROR: foreign tables don't support FOR PORTION OF
UPDATE ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
SET c2 = c2 + 1
-WHERE c1 = '[1,2)';
+WHERE c1 = '[1,2)'; -- error
ERROR: foreign tables don't support FOR PORTION OF
SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4;
c1 | c2 | c3 | c4
@@ -6345,8 +6356,12 @@ SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4;
(1 row)
-- Test DELETE FOR PORTION OF
+DELETE FROM ftpp FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
+WHERE c1 = '[2,3)'; -- error
+ERROR: foreign tables don't support FOR PORTION OF
+ALTER TABLE ftpp DETACH PARTITION ft8;
DELETE FROM ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
-WHERE c1 = '[2,3)';
+WHERE c1 = '[2,3)'; -- error
ERROR: foreign tables don't support FOR PORTION OF
SELECT * FROM ft8 WHERE c1 = '[2,3)' ORDER BY c1, c4;
c1 | c2 | c3 | c4
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 79ad5be8bf9..bf3f28c56a5 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -1577,14 +1577,31 @@ DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass;
DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass;
-- Test UPDATE FOR PORTION OF
+CREATE TABLE ftpp (
+ c1 int4range NOT NULL,
+ c2 int NOT NULL,
+ c3 text,
+ c4 daterange NOT NULL
+) PARTITION BY RANGE (c2);
+ALTER TABLE ftpp ATTACH PARTITION ft8 FOR VALUES FROM (1) TO (150);
+
+UPDATE ftpp FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
+SET c2 = c2 + 1
+WHERE c1 = '[1,2)'; -- error
+
UPDATE ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
SET c2 = c2 + 1
-WHERE c1 = '[1,2)';
+WHERE c1 = '[1,2)'; -- error
SELECT * FROM ft8 WHERE c1 = '[1,2)' ORDER BY c1, c4;
-- Test DELETE FOR PORTION OF
+DELETE FROM ftpp FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
+WHERE c1 = '[2,3)'; -- error
+
+ALTER TABLE ftpp DETACH PARTITION ft8;
+
DELETE FROM ft8 FOR PORTION OF c4 FROM '2005-01-01' TO '2006-01-01'
-WHERE c1 = '[2,3)';
+WHERE c1 = '[2,3)'; -- error
SELECT * FROM ft8 WHERE c1 = '[2,3)' ORDER BY c1, c4;
-- Test UPDATE/DELETE with RETURNING on a three-table join
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index 64ac3063c61..775b1b5a641 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -921,7 +921,7 @@ CopyFrom(CopyFromState cstate)
ExecInitResultRelation(estate, resultRelInfo, 1);
/* Verify the named relation is a valid target for INSERT */
- CheckValidResultRel(resultRelInfo, CMD_INSERT, ONCONFLICT_NONE, NIL);
+ CheckValidResultRel(resultRelInfo, CMD_INSERT, ONCONFLICT_NONE, NIL, NULL);
ExecOpenIndices(resultRelInfo, false);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 4b30f768680..06de3a4461c 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1063,7 +1063,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
*/
void
CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation,
- OnConflictAction onConflictAction, List *mergeActions)
+ OnConflictAction onConflictAction, List *mergeActions,
+ ModifyTable *mtnode)
{
Relation resultRel = resultRelInfo->ri_RelationDesc;
FdwRoutine *fdwroutine;
@@ -1126,6 +1127,12 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation,
RelationGetRelationName(resultRel))));
break;
case RELKIND_FOREIGN_TABLE:
+ /* We don't support FOR PORTION OF FDW queries. */
+ if (mtnode && mtnode->forPortionOf)
+ ereport(ERROR,
+ errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("foreign tables don't support FOR PORTION OF"));
+
/* Okay only if the FDW supports it */
fdwroutine = resultRelInfo->ri_FdwRoutine;
switch (operation)
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index d96d4f9947b..33ec5bfde4c 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -368,7 +368,7 @@ ExecFindPartition(ModifyTableState *mtstate,
/* Verify this ResultRelInfo allows INSERTs */
CheckValidResultRel(rri, CMD_INSERT,
node ? node->onConflictAction : ONCONFLICT_NONE,
- NIL);
+ NIL, node);
/*
* Initialize information needed to insert this and
@@ -594,7 +594,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
* required when the operation is CMD_UPDATE.
*/
CheckValidResultRel(leaf_part_rri, CMD_INSERT,
- node ? node->onConflictAction : ONCONFLICT_NONE, NIL);
+ node ? node->onConflictAction : ONCONFLICT_NONE, NIL, node);
/*
* Open partition indices. The user may have asked to check for conflicts
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 4cb057ca4f9..7ff7a3a17e5 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -5296,7 +5296,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* Verify result relation is a valid target for the current operation
*/
CheckValidResultRel(resultRelInfo, operation, node->onConflictAction,
- mergeActions);
+ mergeActions, node);
resultRelInfo++;
i++;
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index ffcf25a6be7..04bae9939b9 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -1335,12 +1335,6 @@ transformForPortionOfClause(ParseState *pstate,
ForPortionOfExpr *result;
Var *rangeVar;
- /* We don't support FOR PORTION OF FDW queries. */
- if (targetrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("foreign tables don't support FOR PORTION OF")));
-
result = makeNode(ForPortionOfExpr);
/* Look up the FOR PORTION OF name requested. */
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 33bbdbfeffb..c690b230b45 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -249,7 +249,7 @@ extern bool ExecCheckPermissions(List *rangeTable,
extern bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo);
extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation,
OnConflictAction onConflictAction,
- List *mergeActions);
+ List *mergeActions, ModifyTable *mtnode);
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
Relation resultRelationDesc,
Index resultRelationIndex,
--
2.34.1