diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 60edaa8b0a..0ae7b238e2 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -1599,6 +1599,14 @@ inheritance_planner(PlannerInfo *root)
 			withCheckOptionLists = list_make1(parse->withCheckOptions);
 		if (parse->returningList)
 			returningLists = list_make1(parse->returningList);
+		/*
+		 * Since no tuples will be updated, don't require ModifyTable to
+		 * create tuple-routing info that will be left unused.  In fact
+		 * it's necessary to do so, because we're cheating here by putting
+		 * the root table into resultRelations list, which the tuple-routing
+		 * code is not expecting to be there.
+		 */
+		root->partColsUpdated = false;
 	}
 	else
 	{
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index f6d70e9f7a..b78a84e83e 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -665,6 +665,15 @@ select tableoid::regclass::text as relname, parted_tab.* from parted_tab order b
  parted_tab_part3 | 3 | a
 (3 rows)
 
+-- modifies partition key, but no rows will actually be updated
+explain update parted_tab set a = 2 where false;
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Update on parted_tab  (cost=0.00..0.00 rows=0 width=0)
+   ->  Result  (cost=0.00..0.00 rows=0 width=0)
+         One-Time Filter: false
+(3 rows)
+
 drop table parted_tab;
 -- Check UPDATE with multi-level partitioned inherited target
 create table mlparted_tab (a int, b char, c text) partition by list (a);
diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql
index 30a45a20ae..f97d7e5e4d 100644
--- a/src/test/regress/sql/inherit.sql
+++ b/src/test/regress/sql/inherit.sql
@@ -168,6 +168,9 @@ from
 where parted_tab.a = ss.a;
 select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2;
 
+-- modifies partition key, but no rows will actually be updated
+explain update parted_tab set a = 2 where false;
+
 drop table parted_tab;
 
 -- Check UPDATE with multi-level partitioned inherited target
