0004-Some-interface-changes-for-partition_bound_-cmp-bsea-v3.patch
text/plain
Filename: 0004-Some-interface-changes-for-partition_bound_-cmp-bsea-v3.patch
Type: text/plain
Part: 3
Patch
Format: format-patch
Series: patch v3-0004
Subject: Some interface changes for partition_bound_{cmp/bsearch}
| File | + | − |
|---|---|---|
| src/backend/catalog/partition.c | 96 | 39 |
From e7aa6826c055c3c02bd902bc9bee4ed3c31d644f Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 22 Aug 2017 11:33:27 +0900
Subject: [PATCH 4/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 | 135 ++++++++++++++++++++++++++++------------
1 file changed, 96 insertions(+), 39 deletions(-)
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 362ebba75b..73f4e7ab95 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -207,6 +207,30 @@ typedef struct PartitionSet
Bitmapset *other_parts;
} PartitionSet;
+/*
+ * 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;
+ } bound;
+
+ Datum *datums;
+ int ndatums;
+} PartitionBoundCmpArg;
+
static int32 qsort_partition_list_value_cmp(const void *a, const void *b,
void *arg);
static int32 qsort_partition_rbound_cmp(const void *a, const void *b,
@@ -235,14 +259,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 void get_partition_dispatch_recurse(Relation rel, Relation parent,
List **pds, List **leaf_part_oids);
@@ -938,10 +963,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;
@@ -992,6 +1023,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 &&
@@ -1013,8 +1045,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)
{
@@ -1028,9 +1063,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)
{
/*
@@ -3475,12 +3510,15 @@ get_partition_for_tuple(PartitionDispatch *pd,
{
bool equal = false;
int cur_offset;
+ PartitionBoundCmpArg arg;
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = false;
+ arg.datums = values;
+ arg.ndatums = key->partnatts;
cur_offset = partition_bound_bsearch(key,
partdesc->boundinfo,
- values,
- false,
- &equal);
+ &arg, &equal);
if (cur_offset >= 0 && equal)
cur_index = partdesc->boundinfo->indexes[cur_offset];
}
@@ -3492,6 +3530,7 @@ get_partition_for_tuple(PartitionDispatch *pd,
range_partkey_has_null = false;
int cur_offset;
int i;
+ PartitionBoundCmpArg arg;
/*
* No range includes NULL, so this will be accepted by the
@@ -3522,12 +3561,13 @@ get_partition_for_tuple(PartitionDispatch *pd,
if (range_partkey_has_null)
break;
+ memset(&arg, 0, sizeof(PartitionBoundCmpArg));
+ arg.is_bound = false;
+ arg.datums = values;
+ arg.ndatums = key->partnatts;
cur_offset = partition_bound_bsearch(key,
partdesc->boundinfo,
- values,
- false,
- &equal);
-
+ &arg, &equal);
/*
* The offset returned is such that the bound at
* cur_offset is less than or equal to the tuple value, so
@@ -3724,12 +3764,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;
@@ -3751,11 +3791,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;
@@ -3763,17 +3803,35 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
switch (key->strategy)
{
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 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
@@ -3784,12 +3842,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;
}
@@ -3803,20 +3862,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,
@@ -3829,8 +3887,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