@@ -183,6 +183,11 @@ static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
183
183
bool * isnull ,
184
184
int maxfieldlen );
185
185
static List * adjust_partition_tlist (List * tlist , TupleConversionMap * map );
186
+ static void ExecInitPruningContext (PartitionPruneContext * context ,
187
+ List * pruning_steps ,
188
+ PartitionDesc partdesc ,
189
+ PartitionKey partkey ,
190
+ PlanState * planstate );
186
191
static void find_matching_subplans_recurse (PartitionPruningData * prunedata ,
187
192
PartitionedRelPruningData * pprune ,
188
193
bool initial_prune ,
@@ -1614,16 +1619,9 @@ ExecCreatePartitionPruneState(PlanState *planstate,
1614
1619
{
1615
1620
PartitionedRelPruneInfo * pinfo = lfirst_node (PartitionedRelPruneInfo , lc2 );
1616
1621
PartitionedRelPruningData * pprune = & prunedata -> partrelprunedata [j ];
1617
- PartitionPruneContext * context = & pprune -> context ;
1618
1622
Relation partrel ;
1619
1623
PartitionDesc partdesc ;
1620
1624
PartitionKey partkey ;
1621
- int partnatts ;
1622
- int n_steps ;
1623
- ListCell * lc3 ;
1624
-
1625
- /* present_parts is also subject to later modification */
1626
- pprune -> present_parts = bms_copy (pinfo -> present_parts );
1627
1625
1628
1626
/*
1629
1627
* We can rely on the copies of the partitioned table's partition
@@ -1643,6 +1641,7 @@ ExecCreatePartitionPruneState(PlanState *planstate,
1643
1641
* However, new partitions may have been added.
1644
1642
*/
1645
1643
Assert (partdesc -> nparts >= pinfo -> nparts );
1644
+ pprune -> nparts = partdesc -> nparts ;
1646
1645
pprune -> subplan_map = palloc (sizeof (int ) * partdesc -> nparts );
1647
1646
if (partdesc -> nparts == pinfo -> nparts )
1648
1647
{
@@ -1700,66 +1699,30 @@ ExecCreatePartitionPruneState(PlanState *planstate,
1700
1699
Assert (pd_idx == pinfo -> nparts );
1701
1700
}
1702
1701
1703
- n_steps = list_length (pinfo -> pruning_steps );
1704
-
1705
- context -> strategy = partkey -> strategy ;
1706
- context -> partnatts = partnatts = partkey -> partnatts ;
1707
- context -> nparts = pinfo -> nparts ;
1708
- context -> boundinfo = partdesc -> boundinfo ;
1709
- context -> partcollation = partkey -> partcollation ;
1710
- context -> partsupfunc = partkey -> partsupfunc ;
1711
-
1712
- /* We'll look up type-specific support functions as needed */
1713
- context -> stepcmpfuncs = (FmgrInfo * )
1714
- palloc0 (sizeof (FmgrInfo ) * n_steps * partnatts );
1715
-
1716
- context -> ppccontext = CurrentMemoryContext ;
1717
- context -> planstate = planstate ;
1702
+ /* present_parts is also subject to later modification */
1703
+ pprune -> present_parts = bms_copy (pinfo -> present_parts );
1718
1704
1719
- /* Initialize expression state for each expression we need */
1720
- context -> exprstates = (ExprState * * )
1721
- palloc0 (sizeof (ExprState * ) * n_steps * partnatts );
1722
- foreach (lc3 , pinfo -> pruning_steps )
1705
+ /*
1706
+ * Initialize pruning contexts as needed.
1707
+ */
1708
+ pprune -> initial_pruning_steps = pinfo -> initial_pruning_steps ;
1709
+ if (pinfo -> initial_pruning_steps )
1723
1710
{
1724
- PartitionPruneStepOp * step = (PartitionPruneStepOp * ) lfirst (lc3 );
1725
- ListCell * lc4 ;
1726
- int keyno ;
1727
-
1728
- /* not needed for other step kinds */
1729
- if (!IsA (step , PartitionPruneStepOp ))
1730
- continue ;
1731
-
1732
- Assert (list_length (step -> exprs ) <= partnatts );
1733
-
1734
- keyno = 0 ;
1735
- foreach (lc4 , step -> exprs )
1736
- {
1737
- Expr * expr = (Expr * ) lfirst (lc4 );
1738
-
1739
- /* not needed for Consts */
1740
- if (!IsA (expr , Const ))
1741
- {
1742
- int stateidx = PruneCxtStateIdx (partnatts ,
1743
- step -> step .step_id ,
1744
- keyno );
1745
-
1746
- context -> exprstates [stateidx ] =
1747
- ExecInitExpr (expr , context -> planstate );
1748
- }
1749
- keyno ++ ;
1750
- }
1711
+ ExecInitPruningContext (& pprune -> initial_context ,
1712
+ pinfo -> initial_pruning_steps ,
1713
+ partdesc , partkey , planstate );
1714
+ /* Record whether initial pruning is needed at any level */
1715
+ prunestate -> do_initial_prune = true;
1716
+ }
1717
+ pprune -> exec_pruning_steps = pinfo -> exec_pruning_steps ;
1718
+ if (pinfo -> exec_pruning_steps )
1719
+ {
1720
+ ExecInitPruningContext (& pprune -> exec_context ,
1721
+ pinfo -> exec_pruning_steps ,
1722
+ partdesc , partkey , planstate );
1723
+ /* Record whether exec pruning is needed at any level */
1724
+ prunestate -> do_exec_prune = true;
1751
1725
}
1752
-
1753
- /* Array is not modified at runtime, so just point to plan's copy */
1754
- context -> exprhasexecparam = pinfo -> hasexecparam ;
1755
-
1756
- pprune -> pruning_steps = pinfo -> pruning_steps ;
1757
- pprune -> do_initial_prune = pinfo -> do_initial_prune ;
1758
- pprune -> do_exec_prune = pinfo -> do_exec_prune ;
1759
-
1760
- /* Record if pruning would be useful at any level */
1761
- prunestate -> do_initial_prune |= pinfo -> do_initial_prune ;
1762
- prunestate -> do_exec_prune |= pinfo -> do_exec_prune ;
1763
1726
1764
1727
/*
1765
1728
* Accumulate the IDs of all PARAM_EXEC Params affecting the
@@ -1776,6 +1739,71 @@ ExecCreatePartitionPruneState(PlanState *planstate,
1776
1739
return prunestate ;
1777
1740
}
1778
1741
1742
+ /*
1743
+ * Initialize a PartitionPruneContext for the given list of pruning steps.
1744
+ */
1745
+ static void
1746
+ ExecInitPruningContext (PartitionPruneContext * context ,
1747
+ List * pruning_steps ,
1748
+ PartitionDesc partdesc ,
1749
+ PartitionKey partkey ,
1750
+ PlanState * planstate )
1751
+ {
1752
+ int n_steps ;
1753
+ int partnatts ;
1754
+ ListCell * lc ;
1755
+
1756
+ n_steps = list_length (pruning_steps );
1757
+
1758
+ context -> strategy = partkey -> strategy ;
1759
+ context -> partnatts = partnatts = partkey -> partnatts ;
1760
+ context -> nparts = partdesc -> nparts ;
1761
+ context -> boundinfo = partdesc -> boundinfo ;
1762
+ context -> partcollation = partkey -> partcollation ;
1763
+ context -> partsupfunc = partkey -> partsupfunc ;
1764
+
1765
+ /* We'll look up type-specific support functions as needed */
1766
+ context -> stepcmpfuncs = (FmgrInfo * )
1767
+ palloc0 (sizeof (FmgrInfo ) * n_steps * partnatts );
1768
+
1769
+ context -> ppccontext = CurrentMemoryContext ;
1770
+ context -> planstate = planstate ;
1771
+
1772
+ /* Initialize expression state for each expression we need */
1773
+ context -> exprstates = (ExprState * * )
1774
+ palloc0 (sizeof (ExprState * ) * n_steps * partnatts );
1775
+ foreach (lc , pruning_steps )
1776
+ {
1777
+ PartitionPruneStepOp * step = (PartitionPruneStepOp * ) lfirst (lc );
1778
+ ListCell * lc2 ;
1779
+ int keyno ;
1780
+
1781
+ /* not needed for other step kinds */
1782
+ if (!IsA (step , PartitionPruneStepOp ))
1783
+ continue ;
1784
+
1785
+ Assert (list_length (step -> exprs ) <= partnatts );
1786
+
1787
+ keyno = 0 ;
1788
+ foreach (lc2 , step -> exprs )
1789
+ {
1790
+ Expr * expr = (Expr * ) lfirst (lc2 );
1791
+
1792
+ /* not needed for Consts */
1793
+ if (!IsA (expr , Const ))
1794
+ {
1795
+ int stateidx = PruneCxtStateIdx (partnatts ,
1796
+ step -> step .step_id ,
1797
+ keyno );
1798
+
1799
+ context -> exprstates [stateidx ] =
1800
+ ExecInitExpr (expr , context -> planstate );
1801
+ }
1802
+ keyno ++ ;
1803
+ }
1804
+ }
1805
+ }
1806
+
1779
1807
/*
1780
1808
* ExecFindInitialMatchingSubPlans
1781
1809
* Identify the set of subplans that cannot be eliminated by initial
@@ -1824,7 +1852,8 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1824
1852
find_matching_subplans_recurse (prunedata , pprune , true, & result );
1825
1853
1826
1854
/* Expression eval may have used space in node's ps_ExprContext too */
1827
- ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
1855
+ if (pprune -> initial_pruning_steps )
1856
+ ResetExprContext (pprune -> initial_context .planstate -> ps_ExprContext );
1828
1857
}
1829
1858
1830
1859
/* Add in any subplans that partition pruning didn't account for */
@@ -1888,7 +1917,7 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
1888
1917
for (j = prunedata -> num_partrelprunedata - 1 ; j >= 0 ; j -- )
1889
1918
{
1890
1919
PartitionedRelPruningData * pprune = & prunedata -> partrelprunedata [j ];
1891
- int nparts = pprune -> context . nparts ;
1920
+ int nparts = pprune -> nparts ;
1892
1921
int k ;
1893
1922
1894
1923
/* We just rebuild present_parts from scratch */
@@ -1993,7 +2022,8 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
1993
2022
find_matching_subplans_recurse (prunedata , pprune , false, & result );
1994
2023
1995
2024
/* Expression eval may have used space in node's ps_ExprContext too */
1996
- ResetExprContext (pprune -> context .planstate -> ps_ExprContext );
2025
+ if (pprune -> exec_pruning_steps )
2026
+ ResetExprContext (pprune -> exec_context .planstate -> ps_ExprContext );
1997
2027
}
1998
2028
1999
2029
/* Add in any subplans that partition pruning didn't account for */
@@ -2029,15 +2059,15 @@ find_matching_subplans_recurse(PartitionPruningData *prunedata,
2029
2059
check_stack_depth ();
2030
2060
2031
2061
/* Only prune if pruning would be useful at this level. */
2032
- if (initial_prune ? pprune -> do_initial_prune : pprune -> do_exec_prune )
2062
+ if (initial_prune && pprune -> initial_pruning_steps )
2033
2063
{
2034
- PartitionPruneContext * context = & pprune -> context ;
2035
-
2036
- /* Set whether we can evaluate PARAM_EXEC Params or not */
2037
- context -> evalexecparams = !initial_prune ;
2038
-
2039
- partset = get_matching_partitions (context ,
2040
- pprune -> pruning_steps );
2064
+ partset = get_matching_partitions ( & pprune -> initial_context ,
2065
+ pprune -> initial_pruning_steps );
2066
+ }
2067
+ else if ( !initial_prune && pprune -> exec_pruning_steps )
2068
+ {
2069
+ partset = get_matching_partitions (& pprune -> exec_context ,
2070
+ pprune -> exec_pruning_steps );
2041
2071
}
2042
2072
else
2043
2073
{
0 commit comments