partbounds.h 6.8 KB

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