1 /*-------------------------------------------------------------------------
2  *
3  * partbounds.h
4  *
5  * Copyright (c) 2007-2020, 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 "nodes/parsenodes.h"
16 #include "nodes/pg_list.h"
17 #include "partitioning/partdefs.h"
18 #include "utils/relcache.h"
19 struct RelOptInfo;				/* avoid including pathnodes.h here */
20 
21 
22 /*
23  * PartitionBoundInfoData encapsulates a set of partition bounds. It is
24  * usually associated with partitioned tables as part of its partition
25  * descriptor, but may also be used to represent a virtual partitioned
26  * table such as a partitioned joinrel within the planner.
27  *
28  * A list partition datum that is known to be NULL is never put into the
29  * datums array. Instead, it is tracked using the null_index field.
30  *
31  * In the case of range partitioning, ndatums will typically be far less than
32  * 2 * nparts, because a partition's upper bound and the next partition's lower
33  * bound are the same in most common cases, and we only store one of them (the
34  * upper bound).  In case of hash partitioning, ndatums will be the same as the
35  * number of partitions.
36  *
37  * For range and list partitioned tables, datums is an array of datum-tuples
38  * with key->partnatts datums each.  For hash partitioned tables, it is an array
39  * of datum-tuples with 2 datums, modulus and remainder, corresponding to a
40  * given partition.
41  *
42  * The datums in datums array are arranged in increasing order as defined by
43  * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and
44  * qsort_partition_hbound_cmp() for range, list and hash partitioned tables
45  * respectively. For range and list partitions this simply means that the
46  * datums in the datums array are arranged in increasing order as defined by
47  * the partition key's operator classes and collations.
48  *
49  * In the case of list partitioning, the indexes array stores one entry for
50  * each datum-array entry, which is the index of the partition that accepts
51  * rows matching that datum.  So nindexes == ndatums.
52  *
53  * In the case of range partitioning, the indexes array stores one entry per
54  * distinct range datum, which is the index of the partition for which that
55  * datum is an upper bound (or -1 for a "gap" that has no partition).  It is
56  * convenient to have an extra -1 entry representing values above the last
57  * range datum, so nindexes == ndatums + 1.
58  *
59  * In the case of hash partitioning, the number of entries in the indexes
60  * array is the same as the greatest modulus amongst all partitions (which
61  * is a multiple of all partition moduli), so nindexes == greatest modulus.
62  * The indexes array is indexed according to the hash key's remainder modulo
63  * the greatest modulus, and it contains either the partition index accepting
64  * that remainder, or -1 if there is no partition for that remainder.
65  */
66 typedef struct PartitionBoundInfoData
67 {
68 	char		strategy;		/* hash, list or range? */
69 	int			ndatums;		/* Length of the datums[] array */
70 	Datum	  **datums;
71 	PartitionRangeDatumKind **kind; /* The kind of each range bound datum;
72 									 * NULL for hash and list partitioned
73 									 * tables */
74 	int		   *indexes;		/* Partition indexes */
75 	int			null_index;		/* Index of the null-accepting partition; -1
76 								 * if there isn't one */
77 	int			default_index;	/* Index of the default partition; -1 if there
78 								 * isn't one */
79 	int			nindexes;		/* Length of the indexes[] array */
80 } PartitionBoundInfoData;
81 
82 #define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1)
83 #define partition_bound_has_default(bi) ((bi)->default_index != -1)
84 
85 extern int	get_hash_partition_greatest_modulus(PartitionBoundInfo b);
86 extern uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc,
87 										   Oid *partcollation,
88 										   Datum *values, bool *isnull);
89 extern List *get_qual_from_partbound(Relation rel, Relation parent,
90 									 PartitionBoundSpec *spec);
91 extern PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs,
92 												  int nparts, PartitionKey key, int **mapping);
93 extern bool partition_bounds_equal(int partnatts, int16 *parttyplen,
94 								   bool *parttypbyval, PartitionBoundInfo b1,
95 								   PartitionBoundInfo b2);
96 extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src,
97 												PartitionKey key);
98 extern PartitionBoundInfo partition_bounds_merge(int partnatts,
99 												 FmgrInfo *partsupfunc,
100 												 Oid *partcollation,
101 												 struct RelOptInfo *outer_rel,
102 												 struct RelOptInfo *inner_rel,
103 												 JoinType jointype,
104 												 List **outer_parts,
105 												 List **inner_parts);
106 extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts);
107 extern void check_new_partition_bound(char *relname, Relation parent,
108 									  PartitionBoundSpec *spec);
109 extern void check_default_partition_contents(Relation parent,
110 											 Relation defaultRel,
111 											 PartitionBoundSpec *new_spec);
112 
113 extern int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc,
114 										Oid *partcollation,
115 										Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
116 										Datum *tuple_datums, int n_tuple_datums);
117 extern int	partition_list_bsearch(FmgrInfo *partsupfunc,
118 								   Oid *partcollation,
119 								   PartitionBoundInfo boundinfo,
120 								   Datum value, bool *is_equal);
121 extern int	partition_range_datum_bsearch(FmgrInfo *partsupfunc,
122 										  Oid *partcollation,
123 										  PartitionBoundInfo boundinfo,
124 										  int nvalues, Datum *values, bool *is_equal);
125 extern int	partition_hash_bsearch(PartitionBoundInfo boundinfo,
126 								   int modulus, int remainder);
127 
128 #endif							/* PARTBOUNDS_H */
129