PostgreSQL Source Code  git master
partbounds.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * partbounds.h
4  *
5  * Copyright (c) 2007-2024, PostgreSQL Global Development Group
6  *
7  * src/include/partitioning/partbounds.h
8  *
9  *-------------------------------------------------------------------------
10  */
11 #ifndef PARTBOUNDS_H
12 #define PARTBOUNDS_H
13 
14 #include "fmgr.h"
15 #include "parser/parse_node.h"
16 #include "partitioning/partdefs.h"
17 
18 struct RelOptInfo; /* avoid including pathnodes.h here */
19 
20 
21 /*
22  * PartitionBoundInfoData encapsulates a set of partition bounds. It is
23  * usually associated with partitioned tables as part of its partition
24  * descriptor, but may also be used to represent a virtual partitioned
25  * table such as a partitioned joinrel within the planner.
26  *
27  * A list partition datum that is known to be NULL is never put into the
28  * datums array. Instead, it is tracked using the null_index field.
29  *
30  * In the case of range partitioning, ndatums will typically be far less than
31  * 2 * nparts, because a partition's upper bound and the next partition's lower
32  * bound are the same in most common cases, and we only store one of them (the
33  * upper bound). In case of hash partitioning, ndatums will be the same as the
34  * number of partitions.
35  *
36  * For range and list partitioned tables, datums is an array of datum-tuples
37  * with key->partnatts datums each. For hash partitioned tables, it is an array
38  * of datum-tuples with 2 datums, modulus and remainder, corresponding to a
39  * given partition.
40  *
41  * The datums in datums array are arranged in increasing order as defined by
42  * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and
43  * qsort_partition_hbound_cmp() for range, list and hash partitioned tables
44  * respectively. For range and list partitions this simply means that the
45  * datums in the datums array are arranged in increasing order as defined by
46  * the partition key's operator classes and collations.
47  *
48  * In the case of list partitioning, the indexes array stores one entry for
49  * each datum-array entry, which is the index of the partition that accepts
50  * rows matching that datum. So nindexes == ndatums.
51  *
52  * In the case of range partitioning, the indexes array stores one entry per
53  * distinct range datum, which is the index of the partition for which that
54  * datum is an upper bound (or -1 for a "gap" that has no partition). It is
55  * convenient to have an extra -1 entry representing values above the last
56  * range datum, so nindexes == ndatums + 1.
57  *
58  * In the case of hash partitioning, the number of entries in the indexes
59  * array is the same as the greatest modulus amongst all partitions (which
60  * is a multiple of all partition moduli), so nindexes == greatest modulus.
61  * The indexes array is indexed according to the hash key's remainder modulo
62  * the greatest modulus, and it contains either the partition index accepting
63  * that remainder, or -1 if there is no partition for that remainder.
64  *
65  * For LIST partitioned tables, we track the partition indexes of partitions
66  * which are possibly "interleaved" partitions. A partition is considered
67  * interleaved if it allows multiple values and there exists at least one
68  * other partition which could contain a value that lies between those values.
69  * For example, if a partition exists FOR VALUES IN(3,5) and another partition
70  * exists FOR VALUES IN (4), then the IN(3,5) partition is an interleaved
71  * partition. The same is possible with DEFAULT partitions since they can
72  * contain any value that does not belong in another partition. This field
73  * only serves as proof that a particular partition is not interleaved, not
74  * proof that it is interleaved. When we're uncertain, we marked the
75  * partition as interleaved. The interleaved_parts field is only ever set for
76  * RELOPT_BASEREL and RELOPT_OTHER_MEMBER_REL, it is always left NULL for join
77  * relations.
78  */
79 typedef struct PartitionBoundInfoData
80 {
81  PartitionStrategy strategy; /* hash, list or range? */
82  int ndatums; /* Length of the datums[] array */
84  PartitionRangeDatumKind **kind; /* The kind of each range bound datum;
85  * NULL for hash and list partitioned
86  * tables */
87  Bitmapset *interleaved_parts; /* Partition indexes of partitions which
88  * may be interleaved. See above. This is
89  * only set for LIST partitioned tables */
90  int nindexes; /* Length of the indexes[] array */
91  int *indexes; /* Partition indexes */
92  int null_index; /* Index of the null-accepting partition; -1
93  * if there isn't one */
94  int default_index; /* Index of the default partition; -1 if there
95  * isn't one */
97 
98 #define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1)
99 #define partition_bound_has_default(bi) ((bi)->default_index != -1)
100 
102 extern uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc,
103  const Oid *partcollation,
104  const Datum *values, const bool *isnull);
105 extern List *get_qual_from_partbound(Relation parent,
106  PartitionBoundSpec *spec);
108  int nparts, PartitionKey key, int **mapping);
109 extern bool partition_bounds_equal(int partnatts, int16 *parttyplen,
110  bool *parttypbyval, PartitionBoundInfo b1,
111  PartitionBoundInfo b2);
113  PartitionKey key);
114 extern PartitionBoundInfo partition_bounds_merge(int partnatts,
115  FmgrInfo *partsupfunc,
116  Oid *partcollation,
117  struct RelOptInfo *outer_rel,
118  struct RelOptInfo *inner_rel,
119  JoinType jointype,
120  List **outer_parts,
121  List **inner_parts);
122 extern bool partitions_are_ordered(PartitionBoundInfo boundinfo,
123  Bitmapset *live_parts);
124 extern void check_new_partition_bound(char *relname, Relation parent,
125  PartitionBoundSpec *spec,
126  ParseState *pstate);
127 extern void check_default_partition_contents(Relation parent,
128  Relation default_rel,
129  PartitionBoundSpec *new_spec);
130 
131 extern int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc,
132  Oid *partcollation,
133  Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
134  Datum *tuple_datums, int n_tuple_datums);
135 extern int partition_list_bsearch(FmgrInfo *partsupfunc,
136  Oid *partcollation,
137  PartitionBoundInfo boundinfo,
138  Datum value, bool *is_equal);
139 extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc,
140  Oid *partcollation,
141  PartitionBoundInfo boundinfo,
142  int nvalues, Datum *values, bool *is_equal);
143 extern int partition_hash_bsearch(PartitionBoundInfo boundinfo,
144  int modulus, int remainder);
145 
146 #endif /* PARTBOUNDS_H */
static Datum values[MAXATTR]
Definition: bootstrap.c:151
int16_t int16
Definition: c.h:480
int32_t int32
Definition: c.h:481
uint64_t uint64
Definition: c.h:486
static struct @160 value
JoinType
Definition: nodes.h:288
PartitionStrategy
Definition: parsenodes.h:873
PartitionRangeDatumKind
Definition: parsenodes.h:925
int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, Datum *rb_datums, PartitionRangeDatumKind *rb_kind, Datum *tuple_datums, int n_tuple_datums)
Definition: partbounds.c:3556
struct PartitionBoundInfoData PartitionBoundInfoData
PartitionBoundInfo partition_bounds_merge(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, struct RelOptInfo *outer_rel, struct RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
Definition: partbounds.c:1118
bool partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, PartitionBoundInfo b1, PartitionBoundInfo b2)
Definition: partbounds.c:896
void check_new_partition_bound(char *relname, Relation parent, PartitionBoundSpec *spec, ParseState *pstate)
Definition: partbounds.c:2896
List * get_qual_from_partbound(Relation parent, PartitionBoundSpec *spec)
Definition: partbounds.c:249
uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, const Oid *partcollation, const Datum *values, const bool *isnull)
Definition: partbounds.c:4722
PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
Definition: partbounds.c:299
bool partitions_are_ordered(PartitionBoundInfo boundinfo, Bitmapset *live_parts)
Definition: partbounds.c:2852
int partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, int nvalues, Datum *values, bool *is_equal)
Definition: partbounds.c:3695
int partition_hash_bsearch(PartitionBoundInfo boundinfo, int modulus, int remainder)
Definition: partbounds.c:3738
int get_hash_partition_greatest_modulus(PartitionBoundInfo bound)
Definition: partbounds.c:3414
void check_default_partition_contents(Relation parent, Relation default_rel, PartitionBoundSpec *new_spec)
Definition: partbounds.c:3251
int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, Datum value, bool *is_equal)
Definition: partbounds.c:3607
PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, PartitionKey key)
Definition: partbounds.c:1002
NameData relname
Definition: pg_class.h:38
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
Definition: fmgr.h:57
Definition: pg_list.h:54
PartitionRangeDatumKind ** kind
Definition: partbounds.h:84
PartitionStrategy strategy
Definition: partbounds.h:81
Bitmapset * interleaved_parts
Definition: partbounds.h:87