@@ -183,6 +183,11 @@ static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
183183 bool * isnull ,
184184 int maxfieldlen );
185185static 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 );
186191static void find_matching_subplans_recurse (PartitionPruningData * prunedata ,
187192 PartitionedRelPruningData * pprune ,
188193 bool initial_prune ,
@@ -1614,16 +1619,9 @@ ExecCreatePartitionPruneState(PlanState *planstate,
16141619 {
16151620 PartitionedRelPruneInfo * pinfo = lfirst_node (PartitionedRelPruneInfo , lc2 );
16161621 PartitionedRelPruningData * pprune = & prunedata -> partrelprunedata [j ];
1617- PartitionPruneContext * context = & pprune -> context ;
16181622 Relation partrel ;
16191623 PartitionDesc partdesc ;
16201624 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 );
16271625
16281626 /*
16291627 * We can rely on the copies of the partitioned table's partition
@@ -1643,6 +1641,7 @@ ExecCreatePartitionPruneState(PlanState *planstate,
16431641 * However, new partitions may have been added.
16441642 */
16451643 Assert (partdesc -> nparts >= pinfo -> nparts );
1644+ pprune -> nparts = partdesc -> nparts ;
16461645 pprune -> subplan_map = palloc (sizeof (int ) * partdesc -> nparts );
16471646 if (partdesc -> nparts == pinfo -> nparts )
16481647 {
@@ -1700,66 +1699,30 @@ ExecCreatePartitionPruneState(PlanState *planstate,
17001699 Assert (pd_idx == pinfo -> nparts );
17011700 }
17021701
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 );
17181704
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 )
17231710 {
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;
17511725 }
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 ;
17631726
17641727 /*
17651728 * Accumulate the IDs of all PARAM_EXEC Params affecting the
@@ -1776,6 +1739,71 @@ ExecCreatePartitionPruneState(PlanState *planstate,
17761739 return prunestate ;
17771740}
17781741
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+
17791807/*
17801808 * ExecFindInitialMatchingSubPlans
17811809 * Identify the set of subplans that cannot be eliminated by initial
@@ -1824,7 +1852,8 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
18241852 find_matching_subplans_recurse (prunedata , pprune , true, & result );
18251853
18261854 /* 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 );
18281857 }
18291858
18301859 /* Add in any subplans that partition pruning didn't account for */
@@ -1888,7 +1917,7 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
18881917 for (j = prunedata -> num_partrelprunedata - 1 ; j >= 0 ; j -- )
18891918 {
18901919 PartitionedRelPruningData * pprune = & prunedata -> partrelprunedata [j ];
1891- int nparts = pprune -> context . nparts ;
1920+ int nparts = pprune -> nparts ;
18921921 int k ;
18931922
18941923 /* We just rebuild present_parts from scratch */
@@ -1993,7 +2022,8 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
19932022 find_matching_subplans_recurse (prunedata , pprune , false, & result );
19942023
19952024 /* 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 );
19972027 }
19982028
19992029 /* Add in any subplans that partition pruning didn't account for */
@@ -2029,15 +2059,15 @@ find_matching_subplans_recurse(PartitionPruningData *prunedata,
20292059 check_stack_depth ();
20302060
20312061 /* 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 )
20332063 {
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 );
20412071 }
20422072 else
20432073 {
0 commit comments