Skip to content

Commit efbfb64

Browse files
committed
Improve new hash partition bound check error messages
For the error message "every hash partition modulus must be a factor of the next larger modulus", add a detail message that shows the particular numbers and existing partition involved. Also comment the code more. Reviewed-by: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Discussion: https://www.postgresql.org/message-id/flat/bb9d60b4-aadb-607a-1a9d-fdc3434dddcd%40enterprisedb.com
1 parent 9294264 commit efbfb64

File tree

3 files changed

+47
-18
lines changed

3 files changed

+47
-18
lines changed

src/backend/partitioning/partbounds.c

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,14 +2832,9 @@ check_new_partition_bound(char *relname, Relation parent,
28322832

28332833
if (partdesc->nparts > 0)
28342834
{
2835-
Datum **datums = boundinfo->datums;
2836-
int ndatums = boundinfo->ndatums;
28372835
int greatest_modulus;
28382836
int remainder;
28392837
int offset;
2840-
bool valid_modulus = true;
2841-
int prev_modulus, /* Previous largest modulus */
2842-
next_modulus; /* Next largest modulus */
28432838

28442839
/*
28452840
* Check rule that every modulus must be a factor of the
@@ -2849,7 +2844,9 @@ check_new_partition_bound(char *relname, Relation parent,
28492844
* modulus 15, but you cannot add both a partition with
28502845
* modulus 10 and a partition with modulus 15, because 10
28512846
* is not a factor of 15.
2852-
*
2847+
*/
2848+
2849+
/*
28532850
* Get the greatest (modulus, remainder) pair contained in
28542851
* boundinfo->datums that is less than or equal to the
28552852
* (spec->modulus, spec->remainder) pair.
@@ -2859,26 +2856,55 @@ check_new_partition_bound(char *relname, Relation parent,
28592856
spec->remainder);
28602857
if (offset < 0)
28612858
{
2862-
next_modulus = DatumGetInt32(datums[0][0]);
2863-
valid_modulus = (next_modulus % spec->modulus) == 0;
2859+
int next_modulus;
2860+
2861+
/*
2862+
* All existing moduli are greater or equal, so the
2863+
* new one must be a factor of the smallest one, which
2864+
* is first in the boundinfo.
2865+
*/
2866+
next_modulus = DatumGetInt32(boundinfo->datums[0][0]);
2867+
if (next_modulus % spec->modulus != 0)
2868+
ereport(ERROR,
2869+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2870+
errmsg("every hash partition modulus must be a factor of the next larger modulus"),
2871+
errdetail("The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".",
2872+
spec->modulus, next_modulus,
2873+
get_rel_name(partdesc->oids[boundinfo->indexes[0]]))));
28642874
}
28652875
else
28662876
{
2867-
prev_modulus = DatumGetInt32(datums[offset][0]);
2868-
valid_modulus = (spec->modulus % prev_modulus) == 0;
2877+
int prev_modulus;
2878+
2879+
/* We found the largest modulus less than or equal to ours. */
2880+
prev_modulus = DatumGetInt32(boundinfo->datums[offset][0]);
2881+
2882+
if (spec->modulus % prev_modulus != 0)
2883+
ereport(ERROR,
2884+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2885+
errmsg("every hash partition modulus must be a factor of the next larger modulus"),
2886+
errdetail("The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\".",
2887+
spec->modulus,
2888+
prev_modulus,
2889+
get_rel_name(partdesc->oids[boundinfo->indexes[offset]]))));
28692890

2870-
if (valid_modulus && (offset + 1) < ndatums)
2891+
if (offset + 1 < boundinfo->ndatums)
28712892
{
2872-
next_modulus = DatumGetInt32(datums[offset + 1][0]);
2873-
valid_modulus = (next_modulus % spec->modulus) == 0;
2893+
int next_modulus;
2894+
2895+
/* Look at the next higher modulus */
2896+
next_modulus = DatumGetInt32(boundinfo->datums[offset + 1][0]);
2897+
2898+
if (next_modulus % spec->modulus != 0)
2899+
ereport(ERROR,
2900+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2901+
errmsg("every hash partition modulus must be a factor of the next larger modulus"),
2902+
errdetail("The new modulus %d is not factor of %d, the modulus of existing partition \"%s\".",
2903+
spec->modulus, next_modulus,
2904+
get_rel_name(partdesc->oids[boundinfo->indexes[offset + 1]]))));
28742905
}
28752906
}
28762907

2877-
if (!valid_modulus)
2878-
ereport(ERROR,
2879-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2880-
errmsg("every hash partition modulus must be a factor of the next larger modulus")));
2881-
28822908
greatest_modulus = boundinfo->nindexes;
28832909
remainder = spec->remainder;
28842910

src/test/regress/expected/alter_table.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,6 +4109,7 @@ ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, R
41094109
ERROR: remainder for hash partition must be less than modulus
41104110
ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 3, REMAINDER 2);
41114111
ERROR: every hash partition modulus must be a factor of the next larger modulus
4112+
DETAIL: The new modulus 3 is not a factor of 4, the modulus of existing partition "hpart_1".
41124113
DROP TABLE fail_part;
41134114
--
41144115
-- DETACH PARTITION

src/test/regress/expected/create_table.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,11 @@ CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMA
783783
-- modulus 25 is factor of modulus of 50 but 10 is not factor of 25.
784784
CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3);
785785
ERROR: every hash partition modulus must be a factor of the next larger modulus
786+
DETAIL: The new modulus 25 is not divisible by 10, the modulus of existing partition "hpart_1".
786787
-- previous modulus 50 is factor of 150 but this modulus is not factor of next modulus 200.
787788
CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3);
788789
ERROR: every hash partition modulus must be a factor of the next larger modulus
790+
DETAIL: The new modulus 150 is not factor of 200, the modulus of existing partition "hpart_3".
789791
-- trying to specify range for the hash partitioned table
790792
CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES FROM ('a', 1) TO ('z');
791793
ERROR: invalid bound specification for a hash partition

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