v18-0001-Some-interface-changes-for-partition_bound_-cmp-.patch
text/plain
Filename: v18-0001-Some-interface-changes-for-partition_bound_-cmp-.patch
Type: text/plain
Part: 0
Patch
Format: format-patch
Series: patch v18-0001
Subject: Some interface changes for partition_bound_{cmp/bsearch}
| File | + | − |
|---|---|---|
| src/backend/catalog/partition.c | 122 | 42 |
From 505323bc4f745bd4525e46b0d511c44beb819f8c Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 22 Aug 2017 11:33:27 +0900
Subject: [PATCH v18 1/5] Some interface changes for
partition_bound_{cmp/bsearch}
Introduces a notion of PartitionBoundCmpArg, which replaces the set
of arguments void *probe and bool probe_is_bound of both
partition_bound_cmp and partition_bound_bsearch. It wasn't possible
before to specify the number of datums when a non-bound type of
probe is passed. Slightly tweaking the existing interface to allow
specifying the same seems awkward. So, instead encapsulate that
into PartitionBoundCmpArg. Also, modify partition_rbound_datum_cmp
to compare caller-specifed number of datums, instead of
key->partnatts datums.
---
src/backend/catalog/partition.c | 164 ++++++++++++++++++++++++++++++----------
1 file changed, 122 insertions(+), 42 deletions(-)
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 8adc4ee977..d937edcd83 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -138,6 +138,31 @@ typedef struct PartitionRangeBound
bool lower; /* this is the lower (vs upper) bound */
} PartitionRangeBound;
+/*
+ * PartitionBoundCmpArg - Caller-defined argument to be passed to
+ * partition_bound_cmp()
+ *
+ * The first (fixed) argument involved in a comparison is the partition bound
+ * found in the catalog, while an instance of the following struct describes
+ * either a new partition bound being compared against existing bounds
+ * (is_bound is true in that case and either lbound or rbound is set), or a
+ * new tuple's partition key specified in datums (where ndatums = number of
+ * partition key columns specified in the query).
+ */
+typedef struct PartitionBoundCmpArg
+{
+ bool is_bound;
+ union
+ {
+ PartitionListValue *lbound;
+ PartitionRangeBound *rbound;
+ PartitionHashBound *hbound;
+ } bound;
+
+ Datum *datums;
+ int ndatums;
+} PartitionBoundCmpArg;
+
static int32 qsort_partition_hbound_cmp(const void *a, const void *b);
static int32 qsort_partition_list_value_cmp(const void *a, const void *b,
void *arg);
@@ -170,14 +195,15 @@ static int32 partition_rbound_cmp(PartitionKey key,
bool lower1, PartitionRangeBound *b2);
static int32 partition_rbound_datum_cmp(PartitionKey key,
Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
- Datum *tuple_datums);
+ Datum *tuple_datums, int n_tuple_datums);
static int32 partition_bound_cmp(PartitionKey key,
PartitionBoundInfo boundinfo,
- int offset, void *probe, bool probe_is_bound);
+ int offset, PartitionBoundCmpArg *arg);
static int partition_bound_bsearch(PartitionKey key,
PartitionBoundInfo boundinfo,
- void *probe, bool probe_is_bound, bool *is_equal);
+ PartitionBoundCmpArg *arg,
+ bool *is_equal);
static int get_partition_bound_num_indexes(PartitionBoundInfo b);
static int get_greatest_modulus(PartitionBoundInfo b);
static uint64 compute_hash_value(PartitionKey key, Datum *values, bool *isnull);
@@ -985,6 +1011,8 @@ check_new_partition_bound(char *relname, Relation parent,
valid_modulus = true;
int prev_modulus, /* Previous largest modulus */
next_modulus; /* Next largest modulus */
+ PartitionHashBound hbound;
+ PartitionBoundCmpArg arg;
/*
* Check rule that every modulus must be a factor of the
@@ -999,8 +1027,14 @@ check_new_partition_bound(char *relname, Relation parent,
* less than or equal to spec->modulus and
* spec->remainder.
*/
- offset = partition_bound_bsearch(key, boundinfo, spec,
- true, &equal);
+ memset(&hbound, 0, sizeof(PartitionHashBound));
+ hbound.modulus = spec->modulus;
+ hbound.remainder = spec->remainder;
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = true;
+ arg.bound.hbound = &hbound;
+ offset = partition_bound_bsearch(key, boundinfo, &arg,
+ &equal);
if (offset < 0)
{
next_modulus = DatumGetInt32(datums[0][0]);
@@ -1073,10 +1107,16 @@ check_new_partition_bound(char *relname, Relation parent,
{
int offset;
bool equal;
-
+ PartitionListValue lbound;
+ PartitionBoundCmpArg arg;
+
+ memset(&lbound, 0, sizeof(PartitionListValue));
+ lbound.value = val->constvalue;
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = true;
+ arg.bound.lbound = &lbound;
offset = partition_bound_bsearch(key, boundinfo,
- &val->constvalue,
- true, &equal);
+ &arg, &equal);
if (offset >= 0 && equal)
{
overlap = true;
@@ -1127,6 +1167,7 @@ check_new_partition_bound(char *relname, Relation parent,
PartitionBoundInfo boundinfo = partdesc->boundinfo;
int offset;
bool equal;
+ PartitionBoundCmpArg arg;
Assert(boundinfo &&
boundinfo->strategy == PARTITION_STRATEGY_RANGE &&
@@ -1148,8 +1189,11 @@ check_new_partition_bound(char *relname, Relation parent,
* since the index array is initialised with an extra -1
* at the end.
*/
- offset = partition_bound_bsearch(key, boundinfo, lower,
- true, &equal);
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = true;
+ arg.bound.rbound = lower;
+ offset = partition_bound_bsearch(key, boundinfo, &arg,
+ &equal);
if (boundinfo->indexes[offset + 1] < 0)
{
@@ -1163,9 +1207,9 @@ check_new_partition_bound(char *relname, Relation parent,
{
int32 cmpval;
+ arg.bound.rbound = upper;
cmpval = partition_bound_cmp(key, boundinfo,
- offset + 1, upper,
- true);
+ offset + 1, &arg);
if (cmpval < 0)
{
/*
@@ -2537,12 +2581,15 @@ get_partition_for_tuple(Relation relation, Datum *values, bool *isnull)
else
{
bool equal = false;
+ PartitionBoundCmpArg arg;
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = false;
+ arg.datums = values;
+ arg.ndatums = key->partnatts;
bound_offset = partition_bound_bsearch(key,
partdesc->boundinfo,
- values,
- false,
- &equal);
+ &arg, &equal);
if (bound_offset >= 0 && equal)
part_index = partdesc->boundinfo->indexes[bound_offset];
}
@@ -2569,11 +2616,15 @@ get_partition_for_tuple(Relation relation, Datum *values, bool *isnull)
if (!range_partkey_has_null)
{
+ PartitionBoundCmpArg arg;
+
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = false;
+ arg.datums = values;
+ arg.ndatums = key->partnatts;
bound_offset = partition_bound_bsearch(key,
partdesc->boundinfo,
- values,
- false,
- &equal);
+ &arg, &equal);
/*
* The bound at bound_offset is less than or equal to the
@@ -2845,12 +2896,12 @@ partition_rbound_cmp(PartitionKey key,
static int32
partition_rbound_datum_cmp(PartitionKey key,
Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
- Datum *tuple_datums)
+ Datum *tuple_datums, int n_tuple_datums)
{
int i;
int32 cmpval = -1;
- for (i = 0; i < key->partnatts; i++)
+ for (i = 0; i < n_tuple_datums; i++)
{
if (rb_kind[i] == PARTITION_RANGE_DATUM_MINVALUE)
return -1;
@@ -2872,11 +2923,11 @@ partition_rbound_datum_cmp(PartitionKey key,
* partition_bound_cmp
*
* Return whether the bound at offset in boundinfo is <, =, or > the argument
- * specified in *probe.
+ * specified in *arg.
*/
static int32
partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
- int offset, void *probe, bool probe_is_bound)
+ int offset, PartitionBoundCmpArg *arg)
{
Datum *bound_datums = boundinfo->datums[offset];
int32 cmpval = -1;
@@ -2885,25 +2936,55 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
{
case PARTITION_STRATEGY_HASH:
{
- PartitionBoundSpec *spec = (PartitionBoundSpec *) probe;
+ int modulus,
+ remainder;
+
+ if (arg->is_bound)
+ {
+ modulus = arg->bound.hbound->modulus;
+ remainder = arg->bound.hbound->remainder;
+ }
+ else
+ {
+ modulus = DatumGetInt32(arg->datums[0]);
+ remainder = DatumGetInt32(arg->datums[1]);
+ }
cmpval = partition_hbound_cmp(DatumGetInt32(bound_datums[0]),
DatumGetInt32(bound_datums[1]),
- spec->modulus, spec->remainder);
+ modulus, remainder);
break;
}
case PARTITION_STRATEGY_LIST:
- cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0],
- key->partcollation[0],
- bound_datums[0],
- *(Datum *) probe));
- break;
+ {
+ Datum listdatum;
+
+ if (arg->is_bound)
+ listdatum = arg->bound.lbound->value;
+ else
+ {
+ if (arg->ndatums >= 1)
+ listdatum = arg->datums[0];
+ /*
+ * If there's no tuple datum to compare with the bound,
+ * consider the latter to be greater.
+ */
+ else
+ return 1;
+ }
+
+ cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0],
+ key->partcollation[0],
+ bound_datums[0],
+ listdatum));
+ break;
+ }
case PARTITION_STRATEGY_RANGE:
{
PartitionRangeDatumKind *kind = boundinfo->kind[offset];
- if (probe_is_bound)
+ if (arg->is_bound)
{
/*
* We need to pass whether the existing bound is a lower
@@ -2914,12 +2995,13 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
cmpval = partition_rbound_cmp(key,
bound_datums, kind, lower,
- (PartitionRangeBound *) probe);
+ arg->bound.rbound);
}
else
cmpval = partition_rbound_datum_cmp(key,
bound_datums, kind,
- (Datum *) probe);
+ arg->datums,
+ arg->ndatums);
break;
}
@@ -2933,20 +3015,19 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
/*
* Binary search on a collection of partition bounds. Returns greatest
- * bound in array boundinfo->datums which is less than or equal to *probe.
- * If all bounds in the array are greater than *probe, -1 is returned.
+ * bound in array boundinfo->datums which is less than or equal to *arg.
+ * If all bounds in the array are greater than *arg, -1 is returned.
*
- * *probe could either be a partition bound or a Datum array representing
- * the partition key of a tuple being routed; probe_is_bound tells which.
- * We pass that down to the comparison function so that it can interpret the
- * contents of *probe accordingly.
+ * *arg could either be a partition bound or a Datum array representing
+ * the partition key of a tuple being routed. We simply pass that down to
+ * partition_bound_cmp where it is interpreted appropriately.
*
* *is_equal is set to whether the bound at the returned index is equal with
- * *probe.
+ * *arg.
*/
static int
partition_bound_bsearch(PartitionKey key, PartitionBoundInfo boundinfo,
- void *probe, bool probe_is_bound, bool *is_equal)
+ PartitionBoundCmpArg *arg, bool *is_equal)
{
int lo,
hi,
@@ -2959,8 +3040,7 @@ partition_bound_bsearch(PartitionKey key, PartitionBoundInfo boundinfo,
int32 cmpval;
mid = (lo + hi + 1) / 2;
- cmpval = partition_bound_cmp(key, boundinfo, mid, probe,
- probe_is_bound);
+ cmpval = partition_bound_cmp(key, boundinfo, mid, arg);
if (cmpval <= 0)
{
lo = mid;
--
2.11.0