Clean up side-effects of commits ab5fcf2b0 et al.
authorTom Lane
Sun, 7 Apr 2019 16:54:26 +0000 (12:54 -0400)
committerTom Lane
Sun, 7 Apr 2019 16:54:26 +0000 (12:54 -0400)
Before those commits, partitioning-related code in the executor could
assume that ModifyTableState.resultRelInfo[] contains only leaf partitions.
However, now a fully-pruned update results in a dummy ModifyTable that
references the root partitioned table, and that breaks some stuff.

In v11, this led to an assertion or core dump in the tuple routing code.
Fix by disabling tuple routing, since we don't need that anyway.
(I chose to do that in HEAD as well for safety, even though the problem
doesn't manifest in HEAD as it stands.)

In v10, this confused ExecInitModifyTable's decision about whether it
needed to close the root table.  But we can get rid of that altogether
by being smarter about where to find the root table.

Note that since the referenced commits haven't shipped yet, this
isn't fixing any bug the field has seen.

Amit Langote, per a report from me

Discussion: https://postgr.es/m/20710.1554582479@sss.pgh.pa.us

src/backend/optimizer/plan/planner.c
src/test/regress/expected/inherit.out
src/test/regress/sql/inherit.sql

index 60edaa8b0a364ffedff25f8cfd99c69235fe427c..94b962bb6eec9075224a49c350de494d386a26f2 100644 (file)
@@ -1599,6 +1599,15 @@ 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
    {
index f6d70e9f7a10f5b11186a209f750d2b820029d33..b78a84e83ea700fdf8f76787160d0ed5f2cafd32 100644 (file)
@@ -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);
index 30a45a20ae6bc50f1fdfa4e851de90192fe574e9..f97d7e5e4db22a8bcebbc0c0518b3e84f8057bd7 100644 (file)
@@ -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