1/*-------------------------------------------------------------------------
2 *
3 * partbounds.h
4 *
5 * Copyright (c) 2007-2019, 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
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 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 * every datum, which is the index of the partition that accepts a given datum.
50 * In case of range partitioning, it stores one entry per distinct range
51 * datum, which is the index of the partition for which a given datum
52 * is an upper bound. In the case of hash partitioning, the number of the
53 * entries in the indexes array is same as the greatest modulus amongst all
54 * partitions. For a given partition key datum-tuple, the index of the
55 * partition which would accept that datum-tuple would be given by the entry
56 * pointed by remainder produced when hash value of the datum-tuple is divided
57 * by the greatest modulus.
58 */
59typedef struct PartitionBoundInfoData
60{
61 char strategy; /* hash, list or range? */
62 int ndatums; /* Length of the datums following array */
63 Datum **datums;
64 PartitionRangeDatumKind **kind; /* The kind of each range bound datum;
65 * NULL for hash and list partitioned
66 * tables */
67 int *indexes; /* Partition indexes */
68 int null_index; /* Index of the null-accepting partition; -1
69 * if there isn't one */
70 int default_index; /* Index of the default partition; -1 if there
71 * isn't one */
72} PartitionBoundInfoData;
73
74#define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1)
75#define partition_bound_has_default(bi) ((bi)->default_index != -1)
76
77extern int get_hash_partition_greatest_modulus(PartitionBoundInfo b);
78extern uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc,
79 Oid *partcollation,
80 Datum *values, bool *isnull);
81extern List *get_qual_from_partbound(Relation rel, Relation parent,
82 PartitionBoundSpec *spec);
83extern PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs,
84 int nparts, PartitionKey key, int **mapping);
85extern bool partition_bounds_equal(int partnatts, int16 *parttyplen,
86 bool *parttypbyval, PartitionBoundInfo b1,
87 PartitionBoundInfo b2);
88extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src,
89 PartitionKey key);
90extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts);
91extern void check_new_partition_bound(char *relname, Relation parent,
92 PartitionBoundSpec *spec);
93extern void check_default_partition_contents(Relation parent,
94 Relation defaultRel,
95 PartitionBoundSpec *new_spec);
96
97extern int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc,
98 Oid *partcollation,
99 Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
100 Datum *tuple_datums, int n_tuple_datums);
101extern int partition_list_bsearch(FmgrInfo *partsupfunc,
102 Oid *partcollation,
103 PartitionBoundInfo boundinfo,
104 Datum value, bool *is_equal);
105extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc,
106 Oid *partcollation,
107 PartitionBoundInfo boundinfo,
108 int nvalues, Datum *values, bool *is_equal);
109extern int partition_hash_bsearch(PartitionBoundInfo boundinfo,
110 int modulus, int remainder);
111
112#endif /* PARTBOUNDS_H */
113