From: Alvaro Herrera Date: Thu, 16 Aug 2018 15:43:04 +0000 (-0300) Subject: Fix executor prune failure when plan already pruned X-Git-Tag: REL_11_BETA4~107 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6589a435d83ba0b22cb56381fc5b410eb0e27834;p=postgresql Fix executor prune failure when plan already pruned 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 Author: David Rowley Discussion: https://postgr.es/m/87in4h98i0.fsf@ansel.ydns.eu --- diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index e1e100114c..225aa12c3f 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -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. + */ } } } diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index 1a784b2ced..79e29e762b 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -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; diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index aea8871fd8..6aecf25f46 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -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;