@@ -1596,10 +1596,13 @@ ExecCreatePartitionPruneState(PlanState *planstate,
15961596/*
15971597 * ExecFindInitialMatchingSubPlans
15981598 *Identify the set of subplans that cannot be eliminated by initial
1599- *pruning (disregarding any pruning constraints involving PARAM_EXEC
1600- *Params). Also re-map the translation matrix which allows conversion
1601- *of partition indexes into subplan indexes to account for the unneeded
1602- *subplans having been removed.
1599+ *pruning, disregarding any pruning constraints involving PARAM_EXEC
1600+ *Params.
1601+ *
1602+ * If additional pruning passes will be required (because of PARAM_EXEC
1603+ * Params), we must also update the translation data that allows conversion
1604+ * of partition indexes into subplan indexes to account for the unneeded
1605+ * subplans having been removed.
16031606 *
16041607 * Must only be called once per 'prunestate', and only if initial pruning
16051608 * is required.
@@ -1613,17 +1616,18 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
16131616MemoryContext oldcontext ;
16141617int i ;
16151618
1619+ /* Caller error if we get here without do_initial_prune */
16161620Assert (prunestate -> do_initial_prune );
16171621
16181622/*
16191623 * Switch to a temp context to avoid leaking memory in the executor's
1620- * memory context.
1624+ *query-lifespan memory context.
16211625 */
16221626oldcontext = MemoryContextSwitchTo (prunestate -> prune_context );
16231627
16241628/*
1625- * For each hierarchy, do the pruning tests, and adddeletable subplans'
1626- * indexes to "result".
1629+ * For each hierarchy, do the pruning tests, and addnondeletable
1630+ *subplans' indexes to "result".
16271631 */
16281632for (i = 0 ;i < prunestate -> num_partprunedata ;i ++ )
16291633{
@@ -1640,22 +1644,27 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
16401644ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
16411645}
16421646
1647+ /* Add in any subplans that partition pruning didn't account for */
1648+ result = bms_add_members (result ,prunestate -> other_subplans );
1649+
16431650MemoryContextSwitchTo (oldcontext );
16441651
16451652/* Copy result out of the temp context before we reset it */
16461653result = bms_copy (result );
16471654
1648- /* Add in any subplans that partition pruning didn't account for */
1649- result = bms_add_members (result ,prunestate -> other_subplans );
1650-
16511655MemoryContextReset (prunestate -> prune_context );
16521656
16531657/*
1654- * If any subplans were pruned, we must re-sequence the subplan indexes so
1655- * that ExecFindMatchingSubPlans properly returns the indexes from the
1656- * subplans which will remain after execution of this function.
1658+ * If exec-time pruning is required and we pruned subplans above, then we
1659+ * must re-sequence the subplan indexes so that ExecFindMatchingSubPlans
1660+ * properly returns the indexes from the subplans which will remain after
1661+ * execution of this function.
1662+ *
1663+ * We can safely skip this when !do_exec_prune, even though that leaves
1664+ * invalid data in prunestate, because that data won't be consulted again
1665+ * (cf initial Assert in ExecFindMatchingSubPlans).
16571666 */
1658- if (bms_num_members (result )< nsubplans )
1667+ if (prunestate -> do_exec_prune && bms_num_members (result )< nsubplans )
16591668{
16601669int * new_subplan_indexes ;
16611670Bitmapset * new_other_subplans ;
@@ -1664,25 +1673,17 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
16641673
16651674/*
16661675 * First we must build a temporary array which maps old subplan
1667- * indexes to new ones.While we're at it, also recompute the
1668- *other_subplans set, since indexes init may change .
1676+ * indexes to new ones.For convenience of initialization, we use
1677+ *1-based indexes inthis array and leave pruned items as 0 .
16691678 */
1670- new_subplan_indexes = (int * )palloc (sizeof (int )* nsubplans );
1671- new_other_subplans = NULL ;
1672- newidx = 0 ;
1673- for ( i = 0 ; i < nsubplans ; i ++ )
1679+ new_subplan_indexes = (int * )palloc0 (sizeof (int )* nsubplans );
1680+ newidx = 1 ;
1681+ i = -1 ;
1682+ while (( i = bms_next_member ( result , i )) >= 0 )
16741683{
1675- if (bms_is_member (i ,result ))
1676- new_subplan_indexes [i ]= newidx ++ ;
1677- else
1678- new_subplan_indexes [i ]= -1 ;/* Newly pruned */
1679-
1680- if (bms_is_member (i ,prunestate -> other_subplans ))
1681- new_other_subplans = bms_add_member (new_other_subplans ,
1682- new_subplan_indexes [i ]);
1684+ Assert (i < nsubplans );
1685+ new_subplan_indexes [i ]= newidx ++ ;
16831686}
1684- bms_free (prunestate -> other_subplans );
1685- prunestate -> other_subplans = new_other_subplans ;
16861687
16871688/*
16881689 * Now we can update each PartitionedRelPruneInfo's subplan_map with
@@ -1699,7 +1700,7 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
16991700 * order so that we determine present_parts for the lowest-level
17001701 * partitioned tables first. This way we can tell whether a
17011702 * sub-partitioned table's partitions were entirely pruned so we
1702- * can excludethat from' present_parts' .
1703+ * can excludeit fromthe current level's present_parts.
17031704 */
17041705for (j = prunedata -> num_partrelprunedata - 1 ;j >=0 ;j -- )
17051706{
@@ -1728,9 +1729,9 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
17281729if (oldidx >=0 )
17291730{
17301731Assert (oldidx < nsubplans );
1731- pprune -> subplan_map [k ]= new_subplan_indexes [oldidx ];
1732+ pprune -> subplan_map [k ]= new_subplan_indexes [oldidx ]- 1 ;
17321733
1733- if (new_subplan_indexes [oldidx ] >= 0 )
1734+ if (new_subplan_indexes [oldidx ]> 0 )
17341735pprune -> present_parts =
17351736bms_add_member (pprune -> present_parts ,k );
17361737}
@@ -1748,6 +1749,19 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
17481749}
17491750}
17501751
1752+ /*
1753+ * We must also recompute the other_subplans set, since indexes in it
1754+ * may change.
1755+ */
1756+ new_other_subplans = NULL ;
1757+ i = -1 ;
1758+ while ((i = bms_next_member (prunestate -> other_subplans ,i )) >=0 )
1759+ new_other_subplans = bms_add_member (new_other_subplans ,
1760+ new_subplan_indexes [i ]- 1 );
1761+
1762+ bms_free (prunestate -> other_subplans );
1763+ prunestate -> other_subplans = new_other_subplans ;
1764+
17511765pfree (new_subplan_indexes );
17521766}
17531767
@@ -1768,15 +1782,22 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
17681782MemoryContext oldcontext ;
17691783int i ;
17701784
1785+ /*
1786+ * If !do_exec_prune, we've got problems because
1787+ * ExecFindInitialMatchingSubPlans will not have bothered to update
1788+ * prunestate for whatever pruning it did.
1789+ */
1790+ Assert (prunestate -> do_exec_prune );
1791+
17711792/*
17721793 * Switch to a temp context to avoid leaking memory in the executor's
1773- * memory context.
1794+ *query-lifespan memory context.
17741795 */
17751796oldcontext = MemoryContextSwitchTo (prunestate -> prune_context );
17761797
17771798/*
1778- * For each hierarchy, do the pruning tests, and adddeletable subplans'
1779- * indexes to "result".
1799+ * For each hierarchy, do the pruning tests, and addnondeletable
1800+ *subplans' indexes to "result".
17801801 */
17811802for (i = 0 ;i < prunestate -> num_partprunedata ;i ++ )
17821803{
@@ -1792,14 +1813,14 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
17921813ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
17931814}
17941815
1816+ /* Add in any subplans that partition pruning didn't account for */
1817+ result = bms_add_members (result ,prunestate -> other_subplans );
1818+
17951819MemoryContextSwitchTo (oldcontext );
17961820
17971821/* Copy result out of the temp context before we reset it */
17981822result = bms_copy (result );
17991823
1800- /* Add in any subplans that partition pruning didn't account for */
1801- result = bms_add_members (result ,prunestate -> other_subplans );
1802-
18031824MemoryContextReset (prunestate -> prune_context );
18041825
18051826return result ;