@@ -1596,10 +1596,13 @@ ExecCreatePartitionPruneState(PlanState *planstate,
1596
1596
/*
1597
1597
* ExecFindInitialMatchingSubPlans
1598
1598
* 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.
1603
1606
*
1604
1607
* Must only be called once per 'prunestate', and only if initial pruning
1605
1608
* is required.
@@ -1613,17 +1616,18 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1613
1616
MemoryContext oldcontext ;
1614
1617
int i ;
1615
1618
1619
+ /* Caller error if we get here without do_initial_prune */
1616
1620
Assert (prunestate -> do_initial_prune );
1617
1621
1618
1622
/*
1619
1623
* Switch to a temp context to avoid leaking memory in the executor's
1620
- * memory context.
1624
+ * query-lifespan memory context.
1621
1625
*/
1622
1626
oldcontext = MemoryContextSwitchTo (prunestate -> prune_context );
1623
1627
1624
1628
/*
1625
- * For each hierarchy, do the pruning tests, and add deletable subplans'
1626
- * indexes to "result".
1629
+ * For each hierarchy, do the pruning tests, and add nondeletable
1630
+ * subplans' indexes to "result".
1627
1631
*/
1628
1632
for (i = 0 ; i < prunestate -> num_partprunedata ; i ++ )
1629
1633
{
@@ -1640,22 +1644,27 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1640
1644
ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
1641
1645
}
1642
1646
1647
+ /* Add in any subplans that partition pruning didn't account for */
1648
+ result = bms_add_members (result , prunestate -> other_subplans );
1649
+
1643
1650
MemoryContextSwitchTo (oldcontext );
1644
1651
1645
1652
/* Copy result out of the temp context before we reset it */
1646
1653
result = bms_copy (result );
1647
1654
1648
- /* Add in any subplans that partition pruning didn't account for */
1649
- result = bms_add_members (result , prunestate -> other_subplans );
1650
-
1651
1655
MemoryContextReset (prunestate -> prune_context );
1652
1656
1653
1657
/*
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).
1657
1666
*/
1658
- if (bms_num_members (result ) < nsubplans )
1667
+ if (prunestate -> do_exec_prune && bms_num_members (result ) < nsubplans )
1659
1668
{
1660
1669
int * new_subplan_indexes ;
1661
1670
Bitmapset * new_other_subplans ;
@@ -1664,25 +1673,17 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1664
1673
1665
1674
/*
1666
1675
* 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 in it may change .
1676
+ * indexes to new ones. For convenience of initialization, we use
1677
+ * 1-based indexes in this array and leave pruned items as 0 .
1669
1678
*/
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 )
1674
1683
{
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 ++ ;
1683
1686
}
1684
- bms_free (prunestate -> other_subplans );
1685
- prunestate -> other_subplans = new_other_subplans ;
1686
1687
1687
1688
/*
1688
1689
* Now we can update each PartitionedRelPruneInfo's subplan_map with
@@ -1699,7 +1700,7 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1699
1700
* order so that we determine present_parts for the lowest-level
1700
1701
* partitioned tables first. This way we can tell whether a
1701
1702
* sub-partitioned table's partitions were entirely pruned so we
1702
- * can exclude that from ' present_parts' .
1703
+ * can exclude it from the current level's present_parts.
1703
1704
*/
1704
1705
for (j = prunedata -> num_partrelprunedata - 1 ; j >= 0 ; j -- )
1705
1706
{
@@ -1728,9 +1729,9 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1728
1729
if (oldidx >= 0 )
1729
1730
{
1730
1731
Assert (oldidx < nsubplans );
1731
- pprune -> subplan_map [k ] = new_subplan_indexes [oldidx ];
1732
+ pprune -> subplan_map [k ] = new_subplan_indexes [oldidx ] - 1 ;
1732
1733
1733
- if (new_subplan_indexes [oldidx ] >= 0 )
1734
+ if (new_subplan_indexes [oldidx ] > 0 )
1734
1735
pprune -> present_parts =
1735
1736
bms_add_member (pprune -> present_parts , k );
1736
1737
}
@@ -1748,6 +1749,19 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1748
1749
}
1749
1750
}
1750
1751
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
+
1751
1765
pfree (new_subplan_indexes );
1752
1766
}
1753
1767
@@ -1768,15 +1782,22 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
1768
1782
MemoryContext oldcontext ;
1769
1783
int i ;
1770
1784
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
+
1771
1792
/*
1772
1793
* Switch to a temp context to avoid leaking memory in the executor's
1773
- * memory context.
1794
+ * query-lifespan memory context.
1774
1795
*/
1775
1796
oldcontext = MemoryContextSwitchTo (prunestate -> prune_context );
1776
1797
1777
1798
/*
1778
- * For each hierarchy, do the pruning tests, and add deletable subplans'
1779
- * indexes to "result".
1799
+ * For each hierarchy, do the pruning tests, and add nondeletable
1800
+ * subplans' indexes to "result".
1780
1801
*/
1781
1802
for (i = 0 ; i < prunestate -> num_partprunedata ; i ++ )
1782
1803
{
@@ -1792,14 +1813,14 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
1792
1813
ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
1793
1814
}
1794
1815
1816
+ /* Add in any subplans that partition pruning didn't account for */
1817
+ result = bms_add_members (result , prunestate -> other_subplans );
1818
+
1795
1819
MemoryContextSwitchTo (oldcontext );
1796
1820
1797
1821
/* Copy result out of the temp context before we reset it */
1798
1822
result = bms_copy (result );
1799
1823
1800
- /* Add in any subplans that partition pruning didn't account for */
1801
- result = bms_add_members (result , prunestate -> other_subplans );
1802
-
1803
1824
MemoryContextReset (prunestate -> prune_context );
1804
1825
1805
1826
return result ;
0 commit comments