PostgreSQL Source Code git master
Data Structures | Macros | Typedefs | Functions
partprune.h File Reference
#include "nodes/execnodes.h"
#include "partitioning/partdefs.h"
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

 

Macros

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

Typedefs

typedef struct PlannerInfo  PlannerInfo
 
typedef struct RelOptInfo  RelOptInfo
 
 

Functions

int  make_partition_pruneinfo (PlannerInfo *root, RelOptInfo *parentrel, List *subpaths, List *prunequal)
 
 
 

Macro Definition Documentation

PruneCxtStateIdx

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

Definition at line 70 of file partprune.h.

Typedef Documentation

PartitionPruneContext

PlannerInfo

typedef struct PlannerInfo PlannerInfo

Definition at line 20 of file partprune.h.

RelOptInfo

typedef struct RelOptInfo RelOptInfo

Definition at line 21 of file partprune.h.

Function Documentation

get_matching_partitions()

Bitmapset * get_matching_partitions ( PartitionPruneContextcontext,
Listpruning_steps 
)

Definition at line 846 of file partprune.c.

847{
848 Bitmapset *result;
849 int num_steps = list_length(pruning_steps),
850 i;
851 PruneStepResult **results,
852 *final_result;
853 ListCell *lc;
854 bool scan_default;
855
856 /* If there are no pruning steps then all partitions match. */
857 if (num_steps == 0)
858 {
859 Assert(context->nparts > 0);
860 return bms_add_range(NULL, 0, context->nparts - 1);
861 }
862
863 /*
864 * Allocate space for individual pruning steps to store its result. Each
865 * slot will hold a PruneStepResult after performing a given pruning step.
866 * Later steps may use the result of one or more earlier steps. The
867 * result of applying all pruning steps is the value contained in the slot
868 * of the last pruning step.
869 */
870 results = (PruneStepResult **)
871 palloc0(num_steps * sizeof(PruneStepResult *));
872 foreach(lc, pruning_steps)
873 {
874 PartitionPruneStep *step = lfirst(lc);
875
876 switch (nodeTag(step))
877 {
878 case T_PartitionPruneStepOp:
879 results[step->step_id] =
881 (PartitionPruneStepOp *) step);
882 break;
883
884 case T_PartitionPruneStepCombine:
885 results[step->step_id] =
888 results);
889 break;
890
891 default:
892 elog(ERROR, "invalid pruning step type: %d",
893 (int) nodeTag(step));
894 }
895 }
896
897 /*
898 * At this point we know the offsets of all the datums whose corresponding
899 * partitions need to be in the result, including special null-accepting
900 * and default partitions. Collect the actual partition indexes now.
901 */
902 final_result = results[num_steps - 1];
903 Assert(final_result != NULL);
904 i = -1;
905 result = NULL;
906 scan_default = final_result->scan_default;
907 while ((i = bms_next_member(final_result->bound_offsets, i)) >= 0)
908 {
909 int partindex;
910
911 Assert(i < context->boundinfo->nindexes);
912 partindex = context->boundinfo->indexes[i];
913
914 if (partindex < 0)
915 {
916 /*
917 * In range partitioning cases, if a partition index is -1 it
918 * means that the bound at the offset is the upper bound for a
919 * range not covered by any partition (other than a possible
920 * default partition). In hash partitioning, the same means no
921 * partition has been defined for the corresponding remainder
922 * value.
923 *
924 * In either case, the value is still part of the queried range of
925 * values, so mark to scan the default partition if one exists.
926 */
927 scan_default |= partition_bound_has_default(context->boundinfo);
928 continue;
929 }
930
931 result = bms_add_member(result, partindex);
932 }
933
934 /* Add the null and/or default partition if needed and present. */
935 if (final_result->scan_null)
936 {
939 result = bms_add_member(result, context->boundinfo->null_index);
940 }
941 if (scan_default)
942 {
946 result = bms_add_member(result, context->boundinfo->default_index);
947 }
948
949 return result;
950}
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:1019
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
Assert(PointerIsAligned(start, uint64))
i
int i
Definition: isn.c:77
void * palloc0(Size size)
Definition: mcxt.c:1395
#define nodeTag(nodeptr)
Definition: nodes.h:139
@ PARTITION_STRATEGY_LIST
Definition: parsenodes.h:900
@ PARTITION_STRATEGY_RANGE
Definition: parsenodes.h:901
#define partition_bound_has_default(bi)
Definition: partbounds.h:99
#define partition_bound_accepts_nulls(bi)
Definition: partbounds.h:98
static PruneStepResult * perform_pruning_base_step(PartitionPruneContext *context, PartitionPruneStepOp *opstep)
Definition: partprune.c:3444
static PruneStepResult * perform_pruning_combine_step(PartitionPruneContext *context, PartitionPruneStepCombine *cstep, PruneStepResult **step_results)
Definition: partprune.c:3592
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
PartitionBoundInfo boundinfo
Definition: partprune.h:54
bool scan_null
Definition: partprune.c:136
Bitmapset * bound_offsets
Definition: partprune.c:133
bool scan_default
Definition: partprune.c:135
Definition: pg_list.h:46

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, and PartitionPruneContext::strategy.

Referenced by find_matching_subplans_recurse(), and prune_append_rel_partitions().

make_partition_pruneinfo()

int make_partition_pruneinfo ( PlannerInforoot,
RelOptInfoparentrel,
Listsubpaths,
Listprunequal 
)

Definition at line 224 of file partprune.c.

227{
228 PartitionPruneInfo *pruneinfo;
229 Bitmapset *allmatchedsubplans = NULL;
230 List *allpartrelids;
231 List *prunerelinfos;
232 int *relid_subplan_map;
233 ListCell *lc;
234 int i;
235
236 /*
237 * Scan the subpaths to see which ones are scans of partition child
238 * relations, and identify their parent partitioned rels. (Note: we must
239 * restrict the parent partitioned rels to be parentrel or children of
240 * parentrel, otherwise we couldn't translate prunequal to match.)
241 *
242 * Also construct a temporary array to map from partition-child-relation
243 * relid to the index in 'subpaths' of the scan plan for that partition.
244 * (Use of "subplan" rather than "subpath" is a bit of a misnomer, but
245 * we'll let it stand.) For convenience, we use 1-based indexes here, so
246 * that zero can represent an un-filled array entry.
247 */
248 allpartrelids = NIL;
249 relid_subplan_map = palloc0(sizeof(int) * root->simple_rel_array_size);
250
251 i = 1;
252 foreach(lc, subpaths)
253 {
254 Path *path = (Path *) lfirst(lc);
255 RelOptInfo *pathrel = path->parent;
256
257 /* We don't consider partitioned joins here */
258 if (pathrel->reloptkind == RELOPT_OTHER_MEMBER_REL)
259 {
260 RelOptInfo *prel = pathrel;
261 Bitmapset *partrelids = NULL;
262
263 /*
264 * Traverse up to the pathrel's topmost partitioned parent,
265 * collecting parent relids as we go; but stop if we reach
266 * parentrel. (Normally, a pathrel's topmost partitioned parent
267 * is either parentrel or a UNION ALL appendrel child of
268 * parentrel. But when handling partitionwise joins of
269 * multi-level partitioning trees, we can see an append path whose
270 * parentrel is an intermediate partitioned table.)
271 */
272 do
273 {
274 AppendRelInfo *appinfo;
275
276 Assert(prel->relid < root->simple_rel_array_size);
277 appinfo = root->append_rel_array[prel->relid];
278 prel = find_base_rel(root, appinfo->parent_relid);
279 if (!IS_PARTITIONED_REL(prel))
280 break; /* reached a non-partitioned parent */
281 /* accept this level as an interesting parent */
282 partrelids = bms_add_member(partrelids, prel->relid);
283 if (prel == parentrel)
284 break; /* don't traverse above parentrel */
285 } while (prel->reloptkind == RELOPT_OTHER_MEMBER_REL);
286
287 if (partrelids)
288 {
289 /*
290 * Found some relevant parent partitions, which may or may not
291 * overlap with partition trees we already found. Add new
292 * information to the allpartrelids list.
293 */
294 allpartrelids = add_part_relids(allpartrelids, partrelids);
295 /* Also record the subplan in relid_subplan_map[] */
296 /* No duplicates please */
297 Assert(relid_subplan_map[pathrel->relid] == 0);
298 relid_subplan_map[pathrel->relid] = i;
299 }
300 }
301 i++;
302 }
303
304 /*
305 * We now build a PartitionedRelPruneInfo for each topmost partitioned rel
306 * (omitting any that turn out not to have useful pruning quals).
307 */
308 prunerelinfos = NIL;
309 foreach(lc, allpartrelids)
310 {
311 Bitmapset *partrelids = (Bitmapset *) lfirst(lc);
312 List *pinfolist;
313 Bitmapset *matchedsubplans = NULL;
314
315 pinfolist = make_partitionedrel_pruneinfo(root, parentrel,
316 prunequal,
317 partrelids,
318 relid_subplan_map,
319 &matchedsubplans);
320
321 /* When pruning is possible, record the matched subplans */
322 if (pinfolist != NIL)
323 {
324 prunerelinfos = lappend(prunerelinfos, pinfolist);
325 allmatchedsubplans = bms_join(matchedsubplans,
326 allmatchedsubplans);
327 }
328 }
329
330 pfree(relid_subplan_map);
331
332 /*
333 * If none of the partition hierarchies had any useful run-time pruning
334 * quals, then we can just not bother with run-time pruning.
335 */
336 if (prunerelinfos == NIL)
337 return -1;
338
339 /* Else build the result data structure */
340 pruneinfo = makeNode(PartitionPruneInfo);
341 pruneinfo->relids = bms_copy(parentrel->relids);
342 pruneinfo->prune_infos = prunerelinfos;
343
344 /*
345 * Some subplans may not belong to any of the identified partitioned rels.
346 * This can happen for UNION ALL queries which include a non-partitioned
347 * table, or when some of the hierarchies aren't run-time prunable. Build
348 * a bitmapset of the indexes of all such subplans, so that the executor
349 * can identify which subplans should never be pruned.
350 */
351 if (bms_num_members(allmatchedsubplans) < list_length(subpaths))
352 {
353 Bitmapset *other_subplans;
354
355 /* Create the complement of allmatchedsubplans */
356 other_subplans = bms_add_range(NULL, 0, list_length(subpaths) - 1);
357 other_subplans = bms_del_members(other_subplans, allmatchedsubplans);
358
359 pruneinfo->other_subplans = other_subplans;
360 }
361 else
362 pruneinfo->other_subplans = NULL;
363
364 root->partPruneInfos = lappend(root->partPruneInfos, pruneinfo);
365
366 return list_length(root->partPruneInfos) - 1;
367}
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:1161
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:751
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:1230
Bitmapset * bms_copy(const Bitmapset *a)
Definition: bitmapset.c:122
List * lappend(List *list, void *datum)
Definition: list.c:339
void pfree(void *pointer)
Definition: mcxt.c:1594
#define makeNode(_type_)
Definition: nodes.h:161
static List * add_part_relids(List *allpartrelids, Bitmapset *partrelids)
Definition: partprune.c:399
static List * make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, List *prunequal, Bitmapset *partrelids, int *relid_subplan_map, Bitmapset **matchedsubplans)
Definition: partprune.c:445
#define IS_PARTITIONED_REL(rel)
Definition: pathnodes.h:1121
@ RELOPT_OTHER_MEMBER_REL
Definition: pathnodes.h:879
#define NIL
Definition: pg_list.h:68
tree ctl root
Definition: radixtree.h:1857
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition: relnode.c:416
Index parent_relid
Definition: pathnodes.h:3121
Definition: pg_list.h:54
Bitmapset * other_subplans
Definition: plannodes.h:1642
Bitmapset * relids
Definition: plannodes.h:1640
List * prune_infos
Definition: plannodes.h:1641
Definition: pathnodes.h:1795
Relids relids
Definition: pathnodes.h:921
Index relid
Definition: pathnodes.h:967
RelOptKind reloptkind
Definition: pathnodes.h:915

References add_part_relids(), Assert(), bms_add_member(), bms_add_range(), bms_copy(), bms_del_members(), bms_join(), bms_num_members(), find_base_rel(), i, IS_PARTITIONED_REL, lappend(), lfirst, list_length(), make_partitionedrel_pruneinfo(), makeNode, NIL, PartitionPruneInfo::other_subplans, palloc0(), AppendRelInfo::parent_relid, pfree(), PartitionPruneInfo::prune_infos, RelOptInfo::relid, RelOptInfo::relids, PartitionPruneInfo::relids, RELOPT_OTHER_MEMBER_REL, RelOptInfo::reloptkind, and root.

Referenced by create_append_plan(), and create_merge_append_plan().

prune_append_rel_partitions()

Bitmapset * prune_append_rel_partitions ( RelOptInforel )

Definition at line 779 of file partprune.c.

780{
781 List *clauses = rel->baserestrictinfo;
782 List *pruning_steps;
784 PartitionPruneContext context;
785
786 Assert(rel->part_scheme != NULL);
787
788 /* If there are no partitions, return the empty set */
789 if (rel->nparts == 0)
790 return NULL;
791
792 /*
793 * If pruning is disabled or if there are no clauses to prune with, return
794 * all partitions.
795 */
796 if (!enable_partition_pruning || clauses == NIL)
797 return bms_add_range(NULL, 0, rel->nparts - 1);
798
799 /*
800 * Process clauses to extract pruning steps that are usable at plan time.
801 * If the clauses are found to be contradictory, we can return the empty
802 * set.
803 */
805 &gcontext);
806 if (gcontext.contradictory)
807 return NULL;
808 pruning_steps = gcontext.steps;
809
810 /* If there's nothing usable, return all partitions */
811 if (pruning_steps == NIL)
812 return bms_add_range(NULL, 0, rel->nparts - 1);
813
814 /* Set up PartitionPruneContext */
815 context.strategy = rel->part_scheme->strategy;
816 context.partnatts = rel->part_scheme->partnatts;
817 context.nparts = rel->nparts;
818 context.boundinfo = rel->boundinfo;
819 context.partcollation = rel->part_scheme->partcollation;
820 context.partsupfunc = rel->part_scheme->partsupfunc;
821 context.stepcmpfuncs = (FmgrInfo *) palloc0(sizeof(FmgrInfo) *
822 context.partnatts *
823 list_length(pruning_steps));
825
826 /* These are not valid when being called from the planner */
827 context.planstate = NULL;
828 context.exprcontext = NULL;
829 context.exprstates = NULL;
830
831 /* Actual pruning happens here. */
832 return get_matching_partitions(&context, pruning_steps);
833}
bool enable_partition_pruning
Definition: costsize.c:163
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
Bitmapset * get_matching_partitions(PartitionPruneContext *context, List *pruning_steps)
Definition: partprune.c:846
@ PARTTARGET_PLANNER
Definition: partprune.c:93
static void gen_partprune_steps(RelOptInfo *rel, List *clauses, PartClauseTarget target, GeneratePruningStepsContext *context)
Definition: partprune.c:743
Definition: fmgr.h:57
FmgrInfo * partsupfunc
Definition: partprune.h:56
ExprContext * exprcontext
Definition: partprune.h:60
MemoryContext ppccontext
Definition: partprune.h:58
PlanState * planstate
Definition: partprune.h:59
FmgrInfo * stepcmpfuncs
Definition: partprune.h:57
ExprState ** exprstates
Definition: partprune.h:61
List * baserestrictinfo
Definition: pathnodes.h:1040
int nparts
Definition: pathnodes.h:1076

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

Referenced by expand_partitioned_rtentry().

AltStyle によって変換されたページ (->オリジナル) /