Skip to content

Commit 970c050

Browse files
committed
Fix assertion failure in check_new_partition_bound().
Commit 6b2c4e5 was overly confident about not being able to see a negative cmpval result from partition_range_bsearch(). Adjust the code to cope with that. Report and patch by Amul Sul; some additional cosmetic changes by me Discussion: https://postgr.es/m/CAAJ_b97WCO=EyVA7fKzc86kKfojHXLU04_zs7-7+yVzm=-1QkQ@mail.gmail.com
1 parent 6f0bc5e commit 970c050

File tree

3 files changed

+25
-20
lines changed

3 files changed

+25
-20
lines changed

src/backend/partitioning/partbounds.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,10 +2703,10 @@ add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs,
27032703
prev_ub.lower = false;
27042704

27052705
/*
2706-
* We pass to partition_rbound_cmp() lower1 as false to prevent it
2707-
* from considering the last upper bound to be smaller than the lower
2708-
* bound of the merged partition when the values of the two range
2709-
* bounds compare equal.
2706+
* We pass lower1 = false to partition_rbound_cmp() to prevent it from
2707+
* considering the last upper bound to be smaller than the lower bound
2708+
* of the merged partition when the values of the two range bounds
2709+
* compare equal.
27102710
*/
27112711
cmpval = partition_rbound_cmp(partnatts, partsupfuncs, partcollations,
27122712
merged_lb->datums, merged_lb->kind,
@@ -2978,16 +2978,19 @@ check_new_partition_bound(char *relname, Relation parent,
29782978

29792979
/*
29802980
* First check if the resulting range would be empty with
2981-
* specified lower and upper bounds
2981+
* specified lower and upper bounds. partition_rbound_cmp
2982+
* cannot return zero here, since the lower-bound flags are
2983+
* different.
29822984
*/
29832985
cmpval = partition_rbound_cmp(key->partnatts,
29842986
key->partsupfunc,
29852987
key->partcollation,
29862988
lower->datums, lower->kind,
29872989
true, upper);
2988-
if (cmpval >= 0)
2990+
Assert(cmpval != 0);
2991+
if (cmpval > 0)
29892992
{
2990-
/* Fetch the problematic key from the lower datums list. */
2993+
/* Point to problematic key in the lower datums list. */
29912994
PartitionRangeDatum *datum = list_nth(spec->lowerdatums,
29922995
cmpval - 1);
29932996

@@ -3057,11 +3060,11 @@ check_new_partition_bound(char *relname, Relation parent,
30573060
if (cmpval < 0)
30583061
{
30593062
/*
3060-
* Fetch the problematic key from the upper
3063+
* Point to problematic key in the upper
30613064
* datums list.
30623065
*/
30633066
PartitionRangeDatum *datum =
3064-
list_nth(spec->upperdatums, -cmpval - 1);
3067+
list_nth(spec->upperdatums, Abs(cmpval) - 1);
30653068

30663069
/*
30673070
* The new partition overlaps with the
@@ -3083,15 +3086,11 @@ check_new_partition_bound(char *relname, Relation parent,
30833086
PartitionRangeDatum *datum;
30843087

30853088
/*
3086-
* Fetch the problematic key from the lower datums
3087-
* list. Given the way partition_range_bsearch()
3088-
* works, the new lower bound is certainly >= the
3089-
* bound at offset. If the bound matches exactly, we
3090-
* flag the 1st key.
3089+
* Point to problematic key in the lower datums list;
3090+
* if we have equality, point to the first one.
30913091
*/
3092-
Assert(cmpval >= 0);
30933092
datum = cmpval == 0 ? linitial(spec->lowerdatums) :
3094-
list_nth(spec->lowerdatums, cmpval - 1);
3093+
list_nth(spec->lowerdatums, Abs(cmpval) - 1);
30953094
overlap = true;
30963095
overlap_location = datum->location;
30973096
with = boundinfo->indexes[offset + 1];
@@ -3393,13 +3392,14 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
33933392
else if (kind1[i] > kind2[i])
33943393
return colnum;
33953394
else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE)
3396-
3395+
{
33973396
/*
33983397
* The column bounds are both MINVALUE or both MAXVALUE. No later
33993398
* columns should be considered, but we still need to compare
34003399
* whether they are upper or lower bounds.
34013400
*/
34023401
break;
3402+
}
34033403

34043404
cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i],
34053405
partcollation[i],
@@ -3692,9 +3692,9 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg)
36923692
PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b);
36933693
PartitionKey key = (PartitionKey) arg;
36943694

3695-
return partition_rbound_cmp(key->partnatts, key->partsupfunc,
3696-
key->partcollation, b1->datums, b1->kind,
3697-
b1->lower, b2);
3695+
return compare_range_bounds(key->partnatts, key->partsupfunc,
3696+
key->partcollation,
3697+
b1, b2);
36983698
}
36993699

37003700
/*

src/test/regress/expected/create_table.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,10 @@ ERROR: partition "fail_part" would overlap partition "part0"
856856
LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) ...
857857
^
858858
CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10);
859+
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1);
860+
ERROR: partition "fail_part" would overlap partition "part0"
861+
LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1)...
862+
^
859863
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue);
860864
ERROR: partition "fail_part" would overlap partition "part1"
861865
LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (max...

src/test/regress/sql/create_table.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1);
687687
CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1);
688688
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2);
689689
CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10);
690+
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1);
690691
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue);
691692
CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30);
692693
CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy