Skip to content

Commit 3410d7d

Browse files
committed
range partitioning for text partitioning key
1 parent b9b20ec commit 3410d7d

File tree

5 files changed

+44
-28
lines changed

5 files changed

+44
-28
lines changed

src/init.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ PathmanInitState pg_pathman_init_state;
6363
/* Shall we install new relcache callback? */
6464
static bool relcache_callback_needed = true;
6565

66+
/*
67+
* Comparison function info. This structure is only needed to pass FmgrInfo and
68+
* collation to qsort
69+
*/
70+
typedef struct cmp_func_info
71+
{
72+
FmgrInfo flinfo;
73+
Oid collid;
74+
} cmp_func_info;
6675

6776
/* Functions for various local caches */
6877
static bool init_pathman_relation_oids(void);
@@ -449,15 +458,16 @@ fill_prel_with_partitions(const Oid *partitions,
449458
if (prel->parttype == PT_RANGE)
450459
{
451460
MemoryContext old_mcxt;
452-
FmgrInfo flinfo;
461+
cmp_func_info cmp_info;
453462

454463
/* Prepare function info */
455-
fmgr_info(prel->cmp_proc, &flinfo);
464+
fmgr_info(prel->cmp_proc, &cmp_info.flinfo);
465+
cmp_info.collid = prel->attcollid;
456466

457467
/* Sort partitions by RangeEntry->min asc */
458468
qsort_arg((void *) prel->ranges, PrelChildrenCount(prel),
459469
sizeof(RangeEntry), cmp_range_entries,
460-
(void *) &flinfo);
470+
(void *) &cmp_info);
461471

462472
/* Initialize 'prel->children' array */
463473
for (i = 0; i < PrelChildrenCount(prel); i++)
@@ -921,9 +931,9 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
921931
{
922932
const RangeEntry *v1 = (const RangeEntry *) p1;
923933
const RangeEntry *v2 = (const RangeEntry *) p2;
924-
FmgrInfo *flinfo = (FmgrInfo *) arg;
934+
cmp_func_info *info = (cmp_func_info *) arg;
925935

926-
return cmp_bounds(flinfo, &v1->min, &v2->min);
936+
return cmp_bounds(&info->flinfo, info->collid, &v1->min, &v2->min);
927937
}
928938

929939
/* Validates a single expression of kind VAR >= CONST or VAR < CONST */

src/partition_creation.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ static Oid spawn_partitions_val(Oid parent_relid,
5454
Datum interval_binary,
5555
Oid interval_type,
5656
Datum value,
57-
Oid value_type);
57+
Oid value_type,
58+
Oid collid);
5859

5960
static void create_single_partition_common(Oid partition_relid,
6061
Constraint *check_constraint,
@@ -395,7 +396,8 @@ create_partitions_for_value_internal(Oid relid, Datum value, Oid value_type)
395396
partid = spawn_partitions_val(PrelParentRelid(prel),
396397
&bound_min, &bound_max, base_bound_type,
397398
interval_binary, interval_type,
398-
value, base_value_type);
399+
value, base_value_type,
400+
prel->attcollid);
399401
}
400402
}
401403
else
@@ -463,7 +465,8 @@ spawn_partitions_val(Oid parent_relid, /* parent's Oid */
463465
Datum interval_binary, /* interval in binary form */
464466
Oid interval_type, /* INTERVALOID or prel->atttype */
465467
Datum value, /* value to be INSERTed */
466-
Oid value_type) /* type of value */
468+
Oid value_type, /* type of value */
469+
Oid collid) /* collation id */
467470
{
468471
bool should_append; /* append or prepend? */
469472

@@ -489,15 +492,15 @@ spawn_partitions_val(Oid parent_relid, /* parent's Oid */
489492
errdetail("both bounds are infinite")));
490493

491494
/* value >= MAX_BOUNDARY */
492-
else if (cmp_bounds(&cmp_value_bound_finfo,
495+
else if (cmp_bounds(&cmp_value_bound_finfo, collid,
493496
&value_bound, range_bound_max) >= 0)
494497
{
495498
should_append = true;
496499
cur_leading_bound = BoundGetValue(range_bound_max);
497500
}
498501

499502
/* value < MIN_BOUNDARY */
500-
else if (cmp_bounds(&cmp_value_bound_finfo,
503+
else if (cmp_bounds(&cmp_value_bound_finfo, collid,
501504
&value_bound, range_bound_min) < 0)
502505
{
503506
should_append = false;
@@ -1214,8 +1217,8 @@ check_range_available(Oid parent_relid,
12141217
{
12151218
int c1, c2;
12161219

1217-
c1 = cmp_bounds(&cmp_func, start, &ranges[i].max);
1218-
c2 = cmp_bounds(&cmp_func, end, &ranges[i].min);
1220+
c1 = cmp_bounds(&cmp_func, prel->attcollid, start, &ranges[i].max);
1221+
c2 = cmp_bounds(&cmp_func, prel->attcollid, end, &ranges[i].min);
12191222

12201223
/* There's something! */
12211224
if (c1 < 0 && c2 > 0)

src/pg_pathman.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ select_range_partitions(const Datum value,
456456
Oid collid,
457457
WrapperNode *result)
458458
{
459+
#define cmp_call(value1, value2) \
460+
DatumGetInt32(FunctionCall2Coll(cmp_func, collid, value1, value2))
461+
459462
const RangeEntry *current_re;
460463
bool lossy = false,
461464
is_less,
@@ -488,9 +491,9 @@ select_range_partitions(const Datum value,
488491

489492
/* Corner cases */
490493
cmp_min = IsInfinite(&ranges[startidx].min) ?
491-
1 : DatumGetInt32(FunctionCall2Coll(cmp_func, collid, value, BoundGetValue(&ranges[startidx].min)));
494+
1 : cmp_call(value, BoundGetValue(&ranges[startidx].min));
492495
cmp_max = IsInfinite(&ranges[endidx].max) ?
493-
-1 : DatumGetInt32(FunctionCall2Coll(cmp_func, collid, value, BoundGetValue(&ranges[endidx].max)));
496+
-1 : cmp_call(value, BoundGetValue(&ranges[endidx].max));
494497

495498
if ((cmp_min <= 0 && strategy == BTLessStrategyNumber) ||
496499
(cmp_min < 0 && (strategy == BTLessEqualStrategyNumber ||
@@ -538,13 +541,9 @@ select_range_partitions(const Datum value,
538541
current_re = &ranges[i];
539542

540543
cmp_min = IsInfinite(&current_re->min) ?
541-
1 :
542-
FunctionCall2(cmp_func, value,
543-
BoundGetValue(&current_re->min));
544+
1 : cmp_call(value, BoundGetValue(&current_re->min));
544545
cmp_max = IsInfinite(&current_re->max) ?
545-
-1 :
546-
FunctionCall2(cmp_func, value,
547-
BoundGetValue(&current_re->max));
546+
-1 : cmp_call(value, BoundGetValue(&current_re->max));
548547

549548
is_less = (cmp_min < 0 || (cmp_min == 0 && strategy == BTLessStrategyNumber));
550549
is_greater = (cmp_max > 0 || (cmp_max >= 0 && strategy != BTLessStrategyNumber));

src/pl_range_funcs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static ArrayType *construct_infinitable_array(Bound *elems,
3636
int elmlen,
3737
bool elmbyval,
3838
char elmalign);
39-
static void check_range_adjacence(Oid cmp_proc, List *ranges);
39+
static void check_range_adjacence(Oid cmp_proc, Oid collid, List *ranges);
4040
static void merge_range_partitions_internal(Oid parent,
4141
Oid *parts,
4242
uint32 nparts);
@@ -490,15 +490,15 @@ merge_range_partitions_internal(Oid parent, Oid *parts, uint32 nparts)
490490
}
491491

492492
/* Check that partitions are adjacent */
493-
check_range_adjacence(prel->cmp_proc, rentry_list);
493+
check_range_adjacence(prel->cmp_proc, prel->attcollid, rentry_list);
494494

495495
/* First determine the bounds of a new constraint */
496496
first = (RangeEntry *) linitial(rentry_list);
497497
last = (RangeEntry *) llast(rentry_list);
498498

499499
/* Swap ranges if 'last' < 'first' */
500500
fmgr_info(prel->cmp_proc, &cmp_proc);
501-
if (cmp_bounds(&cmp_proc, &last->min, &first->min) < 0)
501+
if (cmp_bounds(&cmp_proc, prel->attcollid, &last->min, &first->min) < 0)
502502
{
503503
RangeEntry *tmp = last;
504504

@@ -762,7 +762,7 @@ construct_infinitable_array(Bound *elems,
762762
* Check that range entries are adjacent
763763
*/
764764
static void
765-
check_range_adjacence(Oid cmp_proc, List *ranges)
765+
check_range_adjacence(Oid cmp_proc, Oid collid, List *ranges)
766766
{
767767
ListCell *lc;
768768
RangeEntry *last = NULL;
@@ -782,8 +782,8 @@ check_range_adjacence(Oid cmp_proc, List *ranges)
782782
}
783783

784784
/* Check that last and current partitions are adjacent */
785-
if ((cmp_bounds(&finfo, &last->max, &cur->min) != 0) &&
786-
(cmp_bounds(&finfo, &cur->max, &last->min) != 0))
785+
if ((cmp_bounds(&finfo, collid, &last->max, &cur->min) != 0) &&
786+
(cmp_bounds(&finfo, collid, &cur->max, &last->min) != 0))
787787
{
788788
elog(ERROR, "partitions \"%s\" and \"%s\" are not adjacent",
789789
get_rel_name(last->child_oid),

src/relation_info.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ BoundGetValue(const Bound *bound)
8181
}
8282

8383
inline static int
84-
cmp_bounds(FmgrInfo *cmp_func, const Bound *b1, const Bound *b2)
84+
cmp_bounds(FmgrInfo *cmp_func, Oid collid, const Bound *b1, const Bound *b2)
8585
{
8686
if (IsMinusInfinity(b1) || IsPlusInfinity(b2))
8787
return -1;
@@ -90,7 +90,11 @@ cmp_bounds(FmgrInfo *cmp_func, const Bound *b1, const Bound *b2)
9090

9191
Assert(cmp_func);
9292

93-
return FunctionCall2(cmp_func, BoundGetValue(b1), BoundGetValue(b2));
93+
return DatumGetInt32(
94+
FunctionCall2Coll(cmp_func,
95+
collid,
96+
BoundGetValue(b1),
97+
BoundGetValue(b2)));
9498
}
9599

96100

0 commit comments

Comments
 (0)