PostgreSQL Source Code  git master
partprune.h File Reference
Include dependency graph for partprune.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PartitionPruneContext
 

Macros

#define PruneCxtStateIdx(partnatts, step_id, keyno)   ((partnatts) * (step_id) + (keyno))
 

Typedefs

typedef struct PartitionPruneContext PartitionPruneContext
 

Functions

PartitionPruneInfomake_partition_pruneinfo (struct PlannerInfo *root, struct RelOptInfo *parentrel, List *subpaths, List *partitioned_rels, List *prunequal)
 
Bitmapsetprune_append_rel_partitions (struct RelOptInfo *rel)
 
Bitmapsetget_matching_partitions (PartitionPruneContext *context, List *pruning_steps)
 

Macro Definition Documentation

◆ PruneCxtStateIdx

#define PruneCxtStateIdx (   partnatts,
  step_id,
  keyno 
)    ((partnatts) * (step_id) + (keyno))

Definition at line 68 of file partprune.h.

Referenced by ExecInitPruningContext(), and perform_pruning_base_step().

Typedef Documentation

◆ PartitionPruneContext

Function Documentation

◆ get_matching_partitions()

Bitmapset* get_matching_partitions ( PartitionPruneContext context,
List pruning_steps 
)

Definition at line 721 of file partprune.c.

References Assert, bms_add_member(), bms_add_range(), bms_next_member(), PruneStepResult::bound_offsets, PartitionPruneContext::boundinfo, PartitionBoundInfoData::default_index, elog, ERROR, i, PartitionBoundInfoData::indexes, lfirst, list_length(), nodeTag, PartitionPruneContext::nparts, PartitionBoundInfoData::null_index, palloc0(), partition_bound_accepts_nulls, partition_bound_has_default, PARTITION_STRATEGY_LIST, PARTITION_STRATEGY_RANGE, perform_pruning_base_step(), perform_pruning_combine_step(), PruneStepResult::scan_default, PruneStepResult::scan_null, PartitionPruneStep::step_id, PartitionPruneContext::strategy, T_PartitionPruneStepCombine, and T_PartitionPruneStepOp.

Referenced by find_matching_subplans_recurse(), and prune_append_rel_partitions().

722 {
723  Bitmapset *result;
724  int num_steps = list_length(pruning_steps),
725  i;
726  PruneStepResult **results,
727  *final_result;
728  ListCell *lc;
729  bool scan_default;
730 
731  /* If there are no pruning steps then all partitions match. */
732  if (num_steps == 0)
733  {
734  Assert(context->nparts > 0);
735  return bms_add_range(NULL, 0, context->nparts - 1);
736  }
737 
738  /*
739  * Allocate space for individual pruning steps to store its result. Each
740  * slot will hold a PruneStepResult after performing a given pruning step.
741  * Later steps may use the result of one or more earlier steps. The
742  * result of applying all pruning steps is the value contained in the slot
743  * of the last pruning step.
744  */
745  results = (PruneStepResult **)
746  palloc0(num_steps * sizeof(PruneStepResult *));
747  foreach(lc, pruning_steps)
748  {
749  PartitionPruneStep *step = lfirst(lc);
750 
751  switch (nodeTag(step))
752  {
754  results[step->step_id] =
756  (PartitionPruneStepOp *) step);
757  break;
758 
760  results[step->step_id] =
762  (PartitionPruneStepCombine *) step,
763  results);
764  break;
765 
766  default:
767  elog(ERROR, "invalid pruning step type: %d",
768  (int) nodeTag(step));
769  }
770  }
771 
772  /*
773  * At this point we know the offsets of all the datums whose corresponding
774  * partitions need to be in the result, including special null-accepting
775  * and default partitions. Collect the actual partition indexes now.
776  */
777  final_result = results[num_steps - 1];
778  Assert(final_result != NULL);
779  i = -1;
780  result = NULL;
781  scan_default = final_result->scan_default;
782  while ((i = bms_next_member(final_result->bound_offsets, i)) >= 0)
783  {
784  int partindex = context->boundinfo->indexes[i];
785 
786  if (partindex < 0)
787  {
788  /*
789  * In range partitioning cases, if a partition index is -1 it
790  * means that the bound at the offset is the upper bound for a
791  * range not covered by any partition (other than a possible
792  * default partition). In hash partitioning, the same means no
793  * partition has been defined for the corresponding remainder
794  * value.
795  *
796  * In either case, the value is still part of the queried range of
797  * values, so mark to scan the default partition if one exists.
798  */
799  scan_default |= partition_bound_has_default(context->boundinfo);
800  continue;
801  }
802 
803  result = bms_add_member(result, partindex);
804  }
805 
806  /* Add the null and/or default partition if needed and present. */
807  if (final_result->scan_null)
808  {
811  result = bms_add_member(result, context->boundinfo->null_index);
812  }
813  if (scan_default)
814  {
816  context->strategy == PARTITION_STRATEGY_RANGE);
818  result = bms_add_member(result, context->boundinfo->default_index);
819  }
820 
821  return result;
822 }
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1043
Bitmapset * bound_offsets
Definition: partprune.c:134
static PruneStepResult * perform_pruning_combine_step(PartitionPruneContext *context, PartitionPruneStepCombine *cstep, PruneStepResult **step_results)
Definition: partprune.c:3387
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:834
#define ERROR
Definition: elog.h:45
static PruneStepResult * perform_pruning_base_step(PartitionPruneContext *context, PartitionPruneStepOp *opstep)
Definition: partprune.c:3239
#define partition_bound_has_default(bi)
Definition: partbounds.h:75
void * palloc0(Size size)
Definition: mcxt.c:981
#define partition_bound_accepts_nulls(bi)
Definition: partbounds.h:74
#define Assert(condition)
Definition: c.h:792
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
#define PARTITION_STRATEGY_LIST
Definition: parsenodes.h:802
#define nodeTag(nodeptr)
Definition: nodes.h:533
#define PARTITION_STRATEGY_RANGE
Definition: parsenodes.h:803
PartitionBoundInfo boundinfo
Definition: partprune.h:53
#define elog(elevel,...)
Definition: elog.h:228
int i

◆ make_partition_pruneinfo()

PartitionPruneInfo* make_partition_pruneinfo ( struct PlannerInfo root,
struct RelOptInfo parentrel,
List subpaths,
List partitioned_rels,
List prunequal 
)

Definition at line 230 of file partprune.c.

References Assert, bms_add_range(), bms_del_members(), bms_join(), bms_num_members(), i, IS_SIMPLE_REL, lappend(), lfirst, list_length(), make_partitionedrel_pruneinfo(), makeNode, NIL, PartitionPruneInfo::other_subplans, palloc0(), Path::parent, pfree(), PartitionPruneInfo::prune_infos, RelOptInfo::relid, and PlannerInfo::simple_rel_array_size.

Referenced by create_append_plan(), and create_merge_append_plan().

233 {
234  PartitionPruneInfo *pruneinfo;
235  Bitmapset *allmatchedsubplans = NULL;
236  int *relid_subplan_map;
237  ListCell *lc;
238  List *prunerelinfos;
239  int i;
240 
241  /*
242  * Construct a temporary array to map from planner relids to subplan
243  * indexes. For convenience, we use 1-based indexes here, so that zero
244  * can represent an un-filled array entry.
245  */
246  relid_subplan_map = palloc0(sizeof(int) * root->simple_rel_array_size);
247 
248  /*
249  * relid_subplan_map maps relid of a leaf partition to the index in
250  * 'subpaths' of the scan plan for that partition.
251  */
252  i = 1;
253  foreach(lc, subpaths)
254  {
255  Path *path = (Path *) lfirst(lc);
256  RelOptInfo *pathrel = path->parent;
257 
258  Assert(IS_SIMPLE_REL(pathrel));
259  Assert(pathrel->relid < root->simple_rel_array_size);
260  /* No duplicates please */
261  Assert(relid_subplan_map[pathrel->relid] == 0);
262 
263  relid_subplan_map[pathrel->relid] = i++;
264  }
265 
266  /* We now build a PartitionedRelPruneInfo for each partitioned rel. */
267  prunerelinfos = NIL;
268  foreach(lc, partitioned_rels)
269  {
270  Relids partrelids = (Relids) lfirst(lc);
271  List *pinfolist;
272  Bitmapset *matchedsubplans = NULL;
273 
274  pinfolist = make_partitionedrel_pruneinfo(root, parentrel,
275  relid_subplan_map,
276  partrelids, prunequal,
277  &matchedsubplans);
278 
279  /* When pruning is possible, record the matched subplans */
280  if (pinfolist != NIL)
281  {
282  prunerelinfos = lappend(prunerelinfos, pinfolist);
283  allmatchedsubplans = bms_join(matchedsubplans,
284  allmatchedsubplans);
285  }
286  }
287 
288  pfree(relid_subplan_map);
289 
290  /*
291  * If none of the partition hierarchies had any useful run-time pruning
292  * quals, then we can just not bother with run-time pruning.
293  */
294  if (prunerelinfos == NIL)
295  return NULL;
296 
297  /* Else build the result data structure */
298  pruneinfo = makeNode(PartitionPruneInfo);
299  pruneinfo->prune_infos = prunerelinfos;
300 
301  /*
302  * Some subplans may not belong to any of the listed partitioned rels.
303  * This can happen for UNION ALL queries which include a non-partitioned
304  * table, or when some of the hierarchies aren't run-time prunable. Build
305  * a bitmapset of the indexes of all such subplans, so that the executor
306  * can identify which subplans should never be pruned.
307  */
308  if (bms_num_members(allmatchedsubplans) < list_length(subpaths))
309  {
310  Bitmapset *other_subplans;
311 
312  /* Create the complement of allmatchedsubplans */
313  other_subplans = bms_add_range(NULL, 0, list_length(subpaths) - 1);
314  other_subplans = bms_del_members(other_subplans, allmatchedsubplans);
315 
316  pruneinfo->other_subplans = other_subplans;
317  }
318  else
319  pruneinfo->other_subplans = NULL;
320 
321  return pruneinfo;
322 }
#define NIL
Definition: pg_list.h:65
static List * make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, int *relid_subplan_map, Relids partrelids, List *prunequal, Bitmapset **matchedsubplans)
Definition: partprune.c:343
#define IS_SIMPLE_REL(rel)
Definition: pathnodes.h:639
void pfree(void *pointer)
Definition: mcxt.c:1057
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:834
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:949
RelOptInfo * parent
Definition: pathnodes.h:1148
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:646
int simple_rel_array_size
Definition: pathnodes.h:198
Index relid
Definition: pathnodes.h:694
List * lappend(List *list, void *datum)
Definition: list.c:336
void * palloc0(Size size)
Definition: mcxt.c:981
#define makeNode(_type_)
Definition: nodes.h:576
Bitmapset * other_subplans
Definition: plannodes.h:1122
#define Assert(condition)
Definition: c.h:792
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
Bitmapset * Relids
Definition: pathnodes.h:28
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:928
int i
Definition: pg_list.h:50

◆ prune_append_rel_partitions()

Bitmapset* prune_append_rel_partitions ( struct RelOptInfo rel)

Definition at line 655 of file partprune.c.

References Assert, RelOptInfo::baserestrictinfo, bms_add_range(), PartitionPruneContext::boundinfo, RelOptInfo::boundinfo, GeneratePruningStepsContext::contradictory, CurrentMemoryContext, enable_partition_pruning, PartitionPruneContext::exprstates, gen_partprune_steps(), get_matching_partitions(), list_length(), NIL, PartitionPruneContext::nparts, RelOptInfo::nparts, palloc0(), RelOptInfo::part_scheme, PartitionPruneContext::partcollation, PartitionSchemeData::partcollation, PartitionPruneContext::partnatts, PartitionSchemeData::partnatts, PartitionPruneContext::partsupfunc, PartitionSchemeData::partsupfunc, PARTTARGET_PLANNER, PartitionPruneContext::planstate, PartitionPruneContext::ppccontext, PartitionPruneContext::stepcmpfuncs, GeneratePruningStepsContext::steps, PartitionPruneContext::strategy, and PartitionSchemeData::strategy.

Referenced by expand_partitioned_rtentry().

656 {
657  List *clauses = rel->baserestrictinfo;
658  List *pruning_steps;
660  PartitionPruneContext context;
661 
662  Assert(rel->part_scheme != NULL);
663 
664  /* If there are no partitions, return the empty set */
665  if (rel->nparts == 0)
666  return NULL;
667 
668  /*
669  * If pruning is disabled or if there are no clauses to prune with, return
670  * all partitions.
671  */
672  if (!enable_partition_pruning || clauses == NIL)
673  return bms_add_range(NULL, 0, rel->nparts - 1);
674 
675  /*
676  * Process clauses to extract pruning steps that are usable at plan time.
677  * If the clauses are found to be contradictory, we can return the empty
678  * set.
679  */
681  &gcontext);
682  if (gcontext.contradictory)
683  return NULL;
684  pruning_steps = gcontext.steps;
685 
686  /* If there's nothing usable, return all partitions */
687  if (pruning_steps == NIL)
688  return bms_add_range(NULL, 0, rel->nparts - 1);
689 
690  /* Set up PartitionPruneContext */
691  context.strategy = rel->part_scheme->strategy;
692  context.partnatts = rel->part_scheme->partnatts;
693  context.nparts = rel->nparts;
694  context.boundinfo = rel->boundinfo;
695  context.partcollation = rel->part_scheme->partcollation;
696  context.partsupfunc = rel->part_scheme->partsupfunc;
697  context.stepcmpfuncs = (FmgrInfo *) palloc0(sizeof(FmgrInfo) *
698  context.partnatts *
699  list_length(pruning_steps));
701 
702  /* These are not valid when being called from the planner */
703  context.planstate = NULL;
704  context.exprstates = NULL;
705 
706  /* Actual pruning happens here. */
707  return get_matching_partitions(&context, pruning_steps);
708 }
static void gen_partprune_steps(RelOptInfo *rel, List *clauses, PartClauseTarget target, GeneratePruningStepsContext *context)
Definition: partprune.c:619
#define NIL
Definition: pg_list.h:65
Definition: fmgr.h:56
FmgrInfo * partsupfunc
Definition: partprune.h:55
FmgrInfo * stepcmpfuncs
Definition: partprune.h:56
MemoryContext ppccontext
Definition: partprune.h:57
List * baserestrictinfo
Definition: pathnodes.h:728
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:834
ExprState ** exprstates
Definition: partprune.h:59
int nparts
Definition: pathnodes.h:744
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void * palloc0(Size size)
Definition: mcxt.c:981
struct PartitionBoundInfoData * boundinfo
Definition: pathnodes.h:747
bool enable_partition_pruning
Definition: costsize.c:149
#define Assert(condition)
Definition: c.h:792
struct FmgrInfo * partsupfunc
Definition: pathnodes.h:408
static int list_length(const List *l)
Definition: pg_list.h:149
PartitionBoundInfo boundinfo
Definition: partprune.h:53
Bitmapset * get_matching_partitions(PartitionPruneContext *context, List *pruning_steps)
Definition: partprune.c:721
PartitionScheme part_scheme
Definition: pathnodes.h:743
Definition: pg_list.h:50
PlanState * planstate
Definition: partprune.h:58