37#include "utils/fmgroids.h"
89#define compare_range_bounds(partnatts, partsupfunc, partcollations, \
91 (partition_rbound_cmp(partnatts, partsupfunc, partcollations, \
92 (bound1)->datums, (bound1)->kind, (bound1)->lower, \
180 List *merged_indexes,
215 List **merged_indexes);
257 switch (key->strategy)
324 for (
i = 0;
i < nparts;
i++)
327 switch (key->strategy)
358 boundinfo->
strategy = key->strategy;
366 for (
i = 0;
i < nparts;
i++)
371 elog(
ERROR,
"invalid strategy in partition bound spec");
406 for (
i = 0;
i < nparts;
i++)
440 for (
i = 0;
i < nparts;
i++)
448 if (!
val->constisnull)
470 int default_index = -1;
475 boundinfo->
strategy = key->strategy;
485 for (
j = 0,
i = 0;
i < nparts;
i++)
491 elog(
ERROR,
"invalid strategy in partition bound spec");
498 if (
spec->is_default)
504 foreach(
c,
spec->listdatums)
508 if (!
val->constisnull)
520 if (null_index != -1)
521 elog(
ERROR,
"found null more than once");
553 for (
i = 0;
i < ndatums;
i++)
559 key->parttypbyval[0],
579 if (null_index != -1)
582 if ((*
mapping)[null_index] == -1)
584 boundinfo->
null_index = (*mapping)[null_index];
588 if (default_index != -1)
595 Assert(default_index >= 0);
686 int default_index = -1;
692 boundinfo->
strategy = key->strategy;
702 for (
i = 0;
i < nparts;
i++)
709 elog(
ERROR,
"invalid strategy in partition bound spec");
716 if (
spec->is_default)
728 Assert(ndatums == nparts * 2 ||
729 (default_index != -1 && ndatums == (nparts - 1) * 2));
742 for (
i = 0;
i < ndatums;
i++)
749 for (
j = 0;
j < key->partnatts;
j++)
768 key->partcollation[
j],
819 partnatts = key->partnatts;
823 for (
i = 0;
i < ndatums;
i++)
829 for (
j = 0;
j < partnatts;
j++)
834 key->parttypbyval[
j],
864 if (default_index != -1)
866 Assert(default_index >= 0 && (*
mapping)[default_index] == -1);
894 if (
b1->strategy !=
b2->strategy)
897 if (
b1->ndatums !=
b2->ndatums)
900 if (
b1->nindexes !=
b2->nindexes)
903 if (
b1->null_index !=
b2->null_index)
906 if (
b1->default_index !=
b2->default_index)
910 for (
i = 0;
i <
b1->nindexes;
i++)
912 if (
b1->indexes[
i] !=
b2->indexes[
i])
934#ifdef USE_ASSERT_CHECKING
935 for (
i = 0;
i <
b1->ndatums;
i++)
937 b1->datums[
i][1] ==
b2->datums[
i][1]));
942 for (
i = 0;
i <
b1->ndatums;
i++)
946 for (
j = 0;
j < partnatts;
j++)
952 if (
b1->kind[
i][
j] !=
b2->kind[
i][
j])
977 parttypbyval[
j], parttyplen[
j]))
1007 ndatums = dest->ndatums = src->
ndatums;
1008 nindexes = dest->nindexes = src->
nindexes;
1009 partnatts = key->partnatts;
1016 if (src->
kind !=
NULL && ndatums > 0)
1034 for (
i = 0;
i < ndatums;
i++)
1057 for (
i = 0;
i < ndatums;
i++)
1063 for (
j = 0;
j < natts;
j++)
1065 if (dest->kind ==
NULL ||
1073 typlen =
sizeof(
int32);
1078 byval = key->parttypbyval[
j];
1079 typlen = key->parttyplen[
j];
1089 memcpy(dest->indexes, src->
indexes,
sizeof(
int) * nindexes);
1211 int null_index = -1;
1212 int default_index = -1;
1429 Assert(null_index == -1);
1438 Assert(default_index == -1);
1524 int default_index = -1;
1757 Assert(default_index == -1);
1807 int nparts = rel->
nparts;
1815 for (
i = 0;
i < nparts;
i++)
2026 if (*default_index == -1)
2109 if (*default_index == -1)
2155 Assert(*null_index == -1);
2238 Assert(*null_index >= 0);
2293 Assert(*default_index == -1);
2302 Assert(*default_index == -1);
2318 Assert(*default_index == -1);
2327 Assert(*default_index == -1);
2342 Assert(*default_index == -1);
2348 Assert(*default_index >= 0);
2414 foreach(
lc, merged_indexes)
2514 int null_index,
int default_index)
2556 foreach(
lc, merged_indexes)
2759 elog(
ERROR,
"unrecognized join type: %d", (
int) jointype);
2775 List **merged_indexes)
2783 Assert(!*merged_indexes);
2822 *merged_indexes =
lappend_int(*merged_indexes, -1);
2896 bool overlap =
false;
2899 if (
spec->is_default)
2913 errmsg(
"partition \"%s\" conflicts with existing default partition \"%s\"",
2918 switch (key->strategy)
2925 if (partdesc->
nparts > 0)
2965 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
2966 errdetail(
"The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".",
2984 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
2985 errdetail(
"The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\".",
2990 if (offset + 1 < boundinfo->
ndatums)
3006 errmsg(
"every hash partition modulus must be a factor of the next larger modulus"),
3007 errdetail(
"The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".",
3046 if (partdesc->
nparts > 0)
3056 foreach(cell,
spec->listdatums)
3061 if (!
val->constisnull)
3071 if (offset >= 0 &&
equal)
3120 errmsg(
"empty range bound specified for partition \"%s\"",
3122 errdetail(
"Specified lower bound %s is greater than or equal to upper bound %s.",
3128 if (partdesc->
nparts > 0)
3158 if (boundinfo->
indexes[offset + 1] < 0)
3166 if (offset + 1 < boundinfo->
ndatums)
3172 datums = boundinfo->
datums[offset + 1];
3173 kind = boundinfo->
kind[offset + 1];
3230 errmsg(
"partition \"%s\" would overlap partition \"%s\"",
3274 (
errmsg_internal(
"updated partition constraint for default partition \"%s\" is implied by existing constraints",
3293 Expr *partition_constraint;
3312 partition_constraint = (
Expr *)
3325 (
errmsg_internal(
"updated partition constraint for default partition \"%s\" is implied by existing constraints",
3347 errmsg(
"skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"",
3377 if (!
ExecCheck(partqualstate, econtext))
3380 errmsg(
"updated partition constraint for default partition \"%s\" would be violated by some row",
3447 if (
val->constisnull)
3448 elog(
ERROR,
"invalid range bound datum");
3492 for (
i = 0;
i < partnatts;
i++)
3534 return cmpval == 0 ? 0 : (
cmpval < 0 ? -colnum : colnum);
3613 mid = (lo + hi + 1) / 2;
3616 boundinfo->
datums[mid][0],
3658 mid = (lo + hi + 1) / 2;
3662 boundinfo->
kind[mid],
3663 (boundinfo->
indexes[mid] == -1),
3701 mid = (lo + hi + 1) / 2;
3705 boundinfo->
kind[mid],
3745 mid = (lo + hi + 1) / 2;
3776 h2->modulus,
h2->remainder);
3792 key->partcollation[0],
3834 key->partopcintype[
col],
3835 key->partopcintype[
col],
3838 elog(
ERROR,
"missing operator %d(%u,%u) in partition opfamily %u",
3839 strategy, key->partopcintype[
col], key->partopcintype[
col],
3840 key->partopfamily[
col]);
3877 key->partcollation[
keynum] != key->parttypcoll[
keynum]))
3879 key->partopcintype[
keynum],
3881 key->partcollation[
keynum],
3885 switch (key->strategy)
3939 key->partcollation[
keynum]);
3954 key->partcollation[
keynum]);
4015 for (
i = 0;
i < key->partnatts;
i++)
4020 if (key->partattrs[
i] != 0)
4026 key->parttypcoll[
i],
4073 Assert(key->partnatts == 1);
4076 if (key->partattrs[0] != 0)
4081 key->parttypcoll[0],
4091 if (
spec->is_default)
4113 for (
i = 0;
i < ndatums;
i++)
4124 key->parttypcoll[0],
4127 key->parttypbyval[0],
4128 key->parttyplen[0]),
4130 key->parttypbyval[0]);
4140 foreach(cell,
spec->listdatums)
4144 if (
val->constisnull)
4213 if (
spec->is_default)
4292 if (
spec->is_default)
4297 int nparts =
pdesc->nparts,
4300 for (k = 0; k < nparts; k++)
4309 elog(
ERROR,
"cache lookup failed for relation %u", inhrelid);
4316 elog(
ERROR,
"expected PartitionBoundSpec");
4318 if (!
bspec->is_default)
4439 if (
i == key->partnatts - 1)
4440 elog(
ERROR,
"invalid range bound specification");
4499 else if (
j == key->partnatts - 1 ||
4632 if (key->partattrs[
keynum] != 0)
4638 key->parttypcoll[
keynum],
4644 elog(
ERROR,
"wrong number of partition key expressions");
4676 for (
i = 0;
i < key->partnatts;
i++)
4680 if (key->partattrs[
i] != 0)
4686 key->parttypcoll[
i],
4692 elog(
ERROR,
"wrong number of partition key expressions");
4721 for (
i = 0;
i < partnatts;
i++)
4794 errmsg(
"modulus for hash partition must be an integer value greater than zero")));
4798 errmsg(
"remainder for hash partition must be an integer value greater than or equal to zero")));
4802 errmsg(
"remainder for hash partition must be less than modulus")));
4822 errmsg(
"\"%s\" is not a hash partitioned table",
4830 if (key->partnatts != nargs)
4833 errmsg(
"number of partitioning columns (%d) does not match number of partition keys provided (%d)",
4834 key->partnatts, nargs)));
4837 fcinfo->flinfo->fn_extra =
4845 key->partnatts *
sizeof(
Oid));
4848 for (
j = 0;
j < key->partnatts; ++
j)
4855 errmsg(
"column %d of the partition key has type %s, but supplied value is of type %s",
4859 &key->partsupfunc[
j],
4860 fcinfo->flinfo->fn_mcxt);
4868 fcinfo->flinfo->fn_extra =
4880 my_extra->partcollid[0] = key->partcollation[0];
4883 for (
j = 0;
j < key->partnatts; ++
j)
4884 if (key->parttypid[
j] !=
my_extra->variadic_type)
4887 errmsg(
"column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"",
4893 &key->partsupfunc[0],
4894 fcinfo->flinfo->fn_mcxt);
4912 for (
i = 0;
i < nkeys;
i++)
4944 &datum, &isnull, &nelems);
4950 errmsg(
"number of partitioning columns (%d) does not match number of partition keys provided (%d)",
4953 for (
i = 0;
i < nelems;
i++)
5032 errmsg(
"can not merge partition \"%s\" together with partition \"%s\"",
5034 errdetail(
"lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"",
5036 errhint(
"ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be adjacent."),
5041 errmsg(
"can not split to partition \"%s\" together with partition \"%s\"",
5043 errdetail(
"lower bound of partition \"%s\" is not equal to the upper bound of partition \"%s\"",
5045 errhint(
"ALTER TABLE ... SPLIT PARTITION requires the partition bounds to be adjacent."),
5072 elog(
ERROR,
"partition bound for relation %u is null",
5078 elog(
ERROR,
"expected PartitionBoundSpec for relation %u",
5109 switch (key->strategy)
5138 for (
i = 1;
i < nparts;
i++)
5184 elog(
ERROR,
"unexpected partition strategy: %d",
5185 (
int) key->strategy);
5214 bool isnull1 =
val1->constisnull;
5218 if (
val2->constisnull)
5234 val2->constvalue)) == 0)
5272 for (
i = 0;
i < nparts;
i++)
5276 for (
j =
i + 1;
j < nparts;
j++)
5282 sps1->bound->listdatums,
5283 sps2->bound->listdatums);
5290 errmsg(
"new partition \"%s\" would overlap with another new partition \"%s\"",
5291 sps1->name->relname,
sps2->name->relname),
5362 errmsg(
"empty range bound specified for partition \"%s\"",
5364 errdetail(
"Specified lower bound %s is greater than or equal to upper bound %s.",
5404 errmsg(
"lower bound of partition \"%s\" is not equal to lower bound of split partition \"%s\"",
5407 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5408 "ALTER TABLE ... SPLIT PARTITION"),
5414 errmsg(
"lower bound of partition \"%s\" is less than lower bound of split partition \"%s\"",
5417 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5418 "ALTER TABLE ... SPLIT PARTITION"),
5446 errmsg(
"upper bound of partition \"%s\" is not equal to upper bound of split partition \"%s\"",
5449 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5450 "ALTER TABLE ... SPLIT PARTITION"),
5456 errmsg(
"upper bound of partition \"%s\" is greater than upper bound of split partition \"%s\"",
5459 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5460 "ALTER TABLE ... SPLIT PARTITION"),
5490 bool overlap =
false;
5505 if (!
val->constisnull)
5515 if (offset >= 0 &&
equal)
5527 errmsg(
"new partition \"%s\" cannot have this value because split partition \"%s\" does not have",
5544 errmsg(
"new partition \"%s\" cannot have NULL value because split partition \"%s\" does not have",
5555 errmsg(
"new partition \"%s\" would overlap with another (not split) partition \"%s\"",
5585 for (
int i = 0;
i < nparts;
i++)
5591 if (isnull &&
val->constisnull)
5594 if (!isnull && !
val->constisnull)
5645 key->partcollation,
parts, nparts, datum,
true))
5652 errmsg(
"new partitions combined partition bounds do not contain value (%s) but split partition \"%s\" does",
5655 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5656 "ALTER TABLE ... SPLIT PARTITION"));
5667 datum = boundinfo->
datums[
i][0];
5669 key->partcollation,
parts, nparts, datum,
false))
5687 key->parttypcoll[0],
5691 key->parttypbyval[0]);
5695 errmsg(
"new partitions combined partition bounds do not contain value (%s) but split partition \"%s\" does",
5698 errhint(
"%s require combined bounds of new partitions must exactly match the bound of the split partition",
5699 "ALTER TABLE ... SPLIT PARTITION"));
5733 int default_index = -1;
5764 if (
sps->bound->is_default)
5771 if (default_index != -1)
5790 for (
i = 0;
i < nparts;
i++)
5803 for (
i = 0;
i < nparts;
i++)
5810 for (
i = 0;
i < nparts;
i++)
5835 bool first = (
i == 0);
5836 bool last = (
i == (nparts - 1));
#define PG_GETARG_ARRAYTYPE_P(n)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
static Datum values[MAXATTR]
static void cleanup(void)
#define TextDatumGetCString(d)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
Datum datumCopy(Datum value, bool typByVal, int typLen)
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
bool ExecCheck(ExprState *state, ExprContext *econtext)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
void FreeExecutorState(EState *estate)
EState * CreateExecutorState(void)
#define GetPerTupleExprContext(estate)
#define ResetExprContext(econtext)
#define GetPerTupleMemoryContext(estate)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
#define palloc_object(type)
#define palloc_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_INT32(n)
#define PG_RETURN_BOOL(x)
static uint64 hash_combine64(uint64 a, uint64 b)
#define HeapTupleIsValid(tuple)
List * lappend(List *list, void *datum)
List * list_concat(List *list1, const List *list2)
List * lappend_int(List *list, int datum)
void list_free(List *list)
#define AccessExclusiveLock
char * get_rel_name(Oid relid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
RegProcedure get_opcode(Oid opno)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Oid get_array_type(Oid typid)
#define type_is_array(typid)
Expr * make_ands_explicit(List *andclauses)
Expr * makeBoolExpr(BoolExprType boolop, List *args, int location)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Node * makeBoolConst(bool value, bool isnull)
RelabelType * makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat)
FuncExpr * makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat)
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
int exprLocation(const Node *expr)
void fix_opfuncids(Node *node)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define castNode(_type_, nodeptr)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
int parser_errposition(ParseState *pstate, int location)
@ PARTITION_STRATEGY_HASH
@ PARTITION_STRATEGY_LIST
@ PARTITION_STRATEGY_RANGE
@ PARTITION_RANGE_DATUM_MAXVALUE
@ PARTITION_RANGE_DATUM_VALUE
@ PARTITION_RANGE_DATUM_MINVALUE
static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, PartitionRangeBound *probe, int32 *cmpval)
static int process_inner_partition(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int inner_index, int outer_default, JoinType jointype, int *next_index, int *default_index)
static void merge_default_partitions(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int outer_default, int inner_default, JoinType jointype, int *next_index, int *default_index)
static void init_partition_map(RelOptInfo *rel, PartitionMap *map)
static void check_partition_bounds_for_split_list(Relation parent, char *relname, PartitionBoundSpec *spec, Oid splitPartOid, ParseState *pstate)
static List * get_qual_for_list(Relation parent, PartitionBoundSpec *spec)
static void check_parent_values_in_new_partitions(Relation parent, Oid partOid, SinglePartitionSpec **parts, int nparts, ParseState *pstate)
static int32 qsort_partition_rbound_cmp(const void *a, const void *b, void *arg)
static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, Datum *datums1, PartitionRangeDatumKind *kind1, bool lower1, PartitionRangeBound *b2)
static PartitionBoundInfo create_list_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
static bool is_dummy_partition(RelOptInfo *rel, int part_index)
static PartitionBoundInfo merge_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
bool partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, PartitionBoundInfo b1, PartitionBoundInfo b2)
int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, const Datum *rb_datums, PartitionRangeDatumKind *rb_kind, const Datum *tuple_datums, int n_tuple_datums)
PartitionBoundInfo partition_bounds_merge(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
static int merge_matching_partitions(PartitionMap *outer_map, PartitionMap *inner_map, int outer_index, int inner_index, int *next_index)
static List * get_qual_for_hash(Relation parent, PartitionBoundSpec *spec)
static void get_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, JoinType jointype, PartitionRangeBound *outer_lb, PartitionRangeBound *outer_ub, PartitionRangeBound *inner_lb, PartitionRangeBound *inner_ub, int lb_cmpval, int ub_cmpval, PartitionRangeBound *merged_lb, PartitionRangeBound *merged_ub)
static void check_two_partitions_bounds_range(Relation parent, RangeVar *first_name, PartitionBoundSpec *first_bound, RangeVar *second_name, PartitionBoundSpec *second_bound, bool defaultPart, bool is_merge, ParseState *pstate)
#define compare_range_bounds(partnatts, partsupfunc, partcollations, bound1, bound2)
static int32 qsort_partition_hbound_cmp(const void *a, const void *b)
static void free_partition_map(PartitionMap *map)
static int get_non_null_list_datum_count(PartitionBoundSpec **boundspecs, int nparts)
void check_new_partition_bound(char *relname, Relation parent, PartitionBoundSpec *spec, ParseState *pstate)
static void fix_merged_indexes(PartitionMap *outer_map, PartitionMap *inner_map, int nmerged, List *merged_indexes)
static PartitionBoundSpec * get_partition_bound_spec(Oid partOid)
static int merge_partition_with_dummy(PartitionMap *map, int index, int *next_index)
static void check_partition_bounds_for_split_range(Relation parent, char *relname, PartitionBoundSpec *spec, Oid splitPartOid, bool first, bool last, bool defaultPart, ParseState *pstate)
static Expr * make_partition_op_expr(PartitionKey key, int keynum, uint16 strategy, Expr *arg1, Expr *arg2)
uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, const Oid *partcollation, const Datum *values, const bool *isnull)
PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
static PartitionBoundInfo create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
bool partitions_are_ordered(PartitionBoundInfo boundinfo, Bitmapset *live_parts)
static List * get_qual_for_range(Relation parent, PartitionBoundSpec *spec, bool for_default)
static PartitionBoundInfo merge_list_bounds(FmgrInfo *partsupfunc, Oid *partcollation, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
static void generate_matching_part_pairs(RelOptInfo *outer_rel, RelOptInfo *inner_rel, PartitionMap *outer_map, PartitionMap *inner_map, int nmerged, List **outer_parts, List **inner_parts)
static void add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, PartitionRangeBound *merged_lb, PartitionRangeBound *merged_ub, int merged_index, List **merged_datums, List **merged_kinds, List **merged_indexes)
Datum satisfies_hash_partition(PG_FUNCTION_ARGS)
static PartitionRangeBound * make_one_partition_rbound(PartitionKey key, int index, List *datums, bool lower)
int partition_hash_bsearch(PartitionBoundInfo boundinfo, int modulus, int remainder)
static bool find_value_in_new_partitions_list(FmgrInfo *partsupfunc, Oid *partcollation, SinglePartitionSpec **parts, int nparts, Datum value, bool isnull)
void check_partitions_for_split(Relation parent, Oid splitPartOid, List *partlist, ParseState *pstate)
static void get_range_key_properties(PartitionKey key, int keynum, PartitionRangeDatum *ldatum, PartitionRangeDatum *udatum, ListCell **partexprs_item, Expr **keyCol, Const **lower_val, Const **upper_val)
List * get_qual_from_partbound(Relation parent, PartitionBoundSpec *spec)
static int32 partition_hbound_cmp(int modulus1, int remainder1, int modulus2, int remainder2)
static PartitionBoundInfo create_range_bounds(PartitionBoundSpec **boundspecs, int nparts, PartitionKey key, int **mapping)
static List * partitions_listdatum_intersection(FmgrInfo *partsupfunc, Oid *partcollation, const List *list1, const List *list2)
void calculate_partition_bound_for_merge(Relation parent, List *partNames, List *partOids, PartitionBoundSpec *spec, ParseState *pstate)
static int32 qsort_partition_list_value_cmp(const void *a, const void *b, void *arg)
static void check_partitions_not_overlap_list(Relation parent, SinglePartitionSpec **parts, int nparts, ParseState *pstate)
static PartitionBoundInfo build_merged_partition_bounds(char strategy, List *merged_datums, List *merged_kinds, List *merged_indexes, int null_index, int default_index)
int get_hash_partition_greatest_modulus(PartitionBoundInfo bound)
static Oid get_partition_operator(PartitionKey key, int col, StrategyNumber strategy, bool *need_relabel)
static bool compare_range_partitions(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, PartitionRangeBound *outer_lb, PartitionRangeBound *outer_ub, PartitionRangeBound *inner_lb, PartitionRangeBound *inner_ub, int *lb_cmpval, int *ub_cmpval)
static int get_range_partition(RelOptInfo *rel, PartitionBoundInfo bi, int *lb_pos, PartitionRangeBound *lb, PartitionRangeBound *ub)
int partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, int nvalues, const Datum *values, bool *is_equal)
static void merge_null_partitions(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_null, bool inner_has_null, int outer_null, int inner_null, JoinType jointype, int *next_index, int *null_index)
void check_default_partition_contents(Relation parent, Relation default_rel, PartitionBoundSpec *new_spec)
static int get_range_partition_internal(PartitionBoundInfo bi, int *lb_pos, PartitionRangeBound *lb, PartitionRangeBound *ub)
static List * get_range_nulltest(PartitionKey key)
static int process_outer_partition(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, bool inner_has_default, int outer_index, int inner_default, JoinType jointype, int *next_index, int *default_index)
int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, Datum value, bool *is_equal)
PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, PartitionKey key)
#define partition_bound_has_default(bi)
#define partition_bound_accepts_nulls(bi)
PartitionKey RelationGetPartitionKey(Relation rel)
static int get_partition_strategy(PartitionKey key)
struct PartitionKeyData * PartitionKey
struct PartitionBoundInfoData * PartitionBoundInfo
PartitionDesc RelationGetPartitionDesc(Relation rel, bool omit_detached)
Oid get_default_oid_from_partdesc(PartitionDesc partdesc)
List * map_partition_varattnos(List *expr, int fromrel_varno, Relation to_rel, Relation from_rel)
List * get_proposed_default_constraint(List *new_part_constraints)
#define HASH_PARTITION_SEED
#define PARTITION_MAX_KEYS
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_current_index(var_or_cell)
#define list_make1_oid(x1)
static void * list_nth(const List *list, int n)
#define list_make3(x1, x2, x3)
#define foreach_node(type, var, lst)
static ListCell * list_head(const List *l)
#define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2)
#define foreach_oid(var, lst)
static ListCell * lnext(const List *l, const ListCell *c)
#define list_make2(x1, x2)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define qsort(a, b, c, d)
static uint64 DatumGetUInt64(Datum X)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Datum UInt64GetDatum(uint64 X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
void * stringToNode(const char *str)
static unsigned hash(unsigned *uv, int n)
#define RelationGetRelid(relation)
#define RelationGetRelationName(relation)
int errtable(Relation rel)
char * deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit)
char * get_range_partbound_string(List *bound_datums)
Snapshot GetLatestSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
MemoryContext es_query_cxt
TupleTableSlot * ecxt_scantuple
PartitionRangeDatumKind ** kind
PartitionStrategy strategy
Bitmapset * interleaved_parts
PartitionBoundInfo boundinfo
PartitionRangeDatumKind * kind
PartitionRangeDatumKind kind
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static void table_endscan(TableScanDesc scan)
static bool table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
static TableScanDesc table_beginscan(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key)
bool PartConstraintImpliedByRelConstraint(Relation scanrel, List *partConstraint)