]> granicus.if.org Git - postgresql/commitdiff
Fix executor prune failure when plan already pruned
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 16 Aug 2018 15:43:04 +0000 (12:43 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 16 Aug 2018 15:49:39 +0000 (12:49 -0300)
In a multi-layer partitioning setup, if at plan time all the
sub-partitions are pruned but the intermediate one remains, the executor
later throws a spurious error that there's nothing to prune.  That is
correct, but there's no reason to throw an error.  Therefore, don't.

Reported-by: Andreas Seltenreich <seltenreich@gmx.de>
Author: David Rowley <david.rowley@2ndquadrant.com>
Discussion: https://postgr.es/m/87in4h98i0.fsf@ansel.ydns.eu

src/backend/executor/execPartition.c
src/test/regress/expected/partition_prune.out
src/test/regress/sql/partition_prune.sql

index e1e100114cf4f8dd25723cd7898dcf13dd68ca6b..225aa12c3f6780ad9a8ee22bf96ec0df04c89811 100644 (file)
@@ -1887,8 +1887,13 @@ find_matching_subplans_recurse(PartitionPruningData *prunedata,
                                                                                           initial_prune, validsubplans);
                        else
                        {
-                               /* Shouldn't happen */
-                               elog(ERROR, "partition missing from subplans");
+                               /*
+                                * We get here if the planner already pruned all the sub-
+                                * partitions for this partition.  Silently ignore this
+                                * partition in this case.  The end result is the same: we
+                                * would have pruned all partitions just the same, but we
+                                * don't have any pruning steps to execute to verify this.
+                                */
                        }
                }
        }
index 1a784b2cede99bc6f835e19e3b368d753e736aee..79e29e762b6c9ac8ec86db34bf1b65efd4d9a5d9 100644 (file)
@@ -3400,3 +3400,21 @@ where s.a = 1 and s.b = 1 and s.c = (select 1);
 (1 row)
 
 drop table p, q;
+-- Ensure run-time pruning works correctly when we match a partitioned table
+-- on the first level but find no matching partitions on the second level.
+create table listp (a int, b int) partition by list (a);
+create table listp1 partition of listp for values in(1);
+create table listp2 partition of listp for values in(2) partition by list(b);
+create table listp2_10 partition of listp2 for values in (10);
+explain (analyze, costs off, summary off, timing off)
+select * from listp where a = (select 2) and b <> 10;
+                QUERY PLAN                 
+-------------------------------------------
+ Append (actual rows=0 loops=1)
+   InitPlan 1 (returns $0)
+     ->  Result (actual rows=1 loops=1)
+   ->  Seq Scan on listp1 (never executed)
+         Filter: ((b <> 10) AND (a = $0))
+(5 rows)
+
+drop table listp;
index aea8871fd87b06b5d4cc376bfb8f9443da81ad7f..6aecf25f467a9ba3674161866dad03d300160334 100644 (file)
@@ -888,3 +888,15 @@ from (
 where s.a = 1 and s.b = 1 and s.c = (select 1);
 
 drop table p, q;
+
+-- Ensure run-time pruning works correctly when we match a partitioned table
+-- on the first level but find no matching partitions on the second level.
+create table listp (a int, b int) partition by list (a);
+create table listp1 partition of listp for values in(1);
+create table listp2 partition of listp for values in(2) partition by list(b);
+create table listp2_10 partition of listp2 for values in (10);
+
+explain (analyze, costs off, summary off, timing off)
+select * from listp where a = (select 2) and b <> 10;
+
+drop table listp;