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