Skip to content

Commit bb5d6e8

Browse files
committed
Improve the error message when creating an empty range partition.
The previous message didn't mention the name of the table or the bounds. Put the table name in the primary error message and the bounds in the detail message. Amit Langote, changed slightly by me. Suggestions on the exac phrasing from Tom Lane, David G. Johnston, and Dean Rasheed. Discussion: http://postgr.es/m/CA+Tgmoae6bpwVa-1BMaVcwvCCeOoJ5B9Q9-RHWo-1gJxfPBZ5Q@mail.gmail.com
1 parent c1ef4e5 commit bb5d6e8

File tree

4 files changed

+56
-45
lines changed

4 files changed

+56
-45
lines changed

src/backend/catalog/partition.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,16 @@ check_new_partition_bound(char *relname, Relation parent,
722722
*/
723723
if (partition_rbound_cmp(key, lower->datums, lower->kind, true,
724724
upper) >= 0)
725+
{
725726
ereport(ERROR,
726727
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
727-
errmsg("cannot create range partition with empty range"),
728-
parser_errposition(pstate, spec->location)));
728+
errmsg("empty range bound specified for partition \"%s\"",
729+
relname),
730+
errdetail("Specified lower bound %s is greater than or equal to upper bound %s.",
731+
get_range_partbound_string(spec->lowerdatums),
732+
get_range_partbound_string(spec->upperdatums)),
733+
parser_errposition(pstate, spec->location)));
734+
}
729735

730736
if (partdesc->nparts > 0)
731737
{

src/backend/utils/adt/ruleutils.c

+43-41
Original file line numberDiff line numberDiff line change
@@ -8722,47 +8722,9 @@ get_rule_expr(Node *node, deparse_context *context,
87228722
list_length(spec->lowerdatums) ==
87238723
list_length(spec->upperdatums));
87248724

8725-
appendStringInfoString(buf, "FOR VALUES FROM (");
8726-
sep = "";
8727-
foreach(cell, spec->lowerdatums)
8728-
{
8729-
PartitionRangeDatum *datum =
8730-
castNode(PartitionRangeDatum, lfirst(cell));
8731-
8732-
appendStringInfoString(buf, sep);
8733-
if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
8734-
appendStringInfoString(buf, "MINVALUE");
8735-
else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
8736-
appendStringInfoString(buf, "MAXVALUE");
8737-
else
8738-
{
8739-
Const *val = castNode(Const, datum->value);
8740-
8741-
get_const_expr(val, context, -1);
8742-
}
8743-
sep = ", ";
8744-
}
8745-
appendStringInfoString(buf, ") TO (");
8746-
sep = "";
8747-
foreach(cell, spec->upperdatums)
8748-
{
8749-
PartitionRangeDatum *datum =
8750-
castNode(PartitionRangeDatum, lfirst(cell));
8751-
8752-
appendStringInfoString(buf, sep);
8753-
if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
8754-
appendStringInfoString(buf, "MINVALUE");
8755-
else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
8756-
appendStringInfoString(buf, "MAXVALUE");
8757-
else
8758-
{
8759-
Const *val = castNode(Const, datum->value);
8760-
8761-
get_const_expr(val, context, -1);
8762-
}
8763-
sep = ", ";
8764-
}
8765-
appendStringInfoString(buf, ")");
8725+
appendStringInfo(buf, "FOR VALUES FROM %s TO %s",
8726+
get_range_partbound_string(spec->lowerdatums),
8727+
get_range_partbound_string(spec->upperdatums));
87668728
break;
87678729

87688730
default:
@@ -10943,3 +10905,43 @@ flatten_reloptions(Oid relid)
1094310905

1094410906
return result;
1094510907
}
10908+
10909+
/*
10910+
* get_one_range_partition_bound_string
10911+
* A C string representation of one range partition bound
10912+
*/
10913+
char *
10914+
get_range_partbound_string(List *bound_datums)
10915+
{
10916+
deparse_context context;
10917+
StringInfo buf = makeStringInfo();
10918+
ListCell *cell;
10919+
char *sep;
10920+
10921+
memset(&context, 0, sizeof(deparse_context));
10922+
context.buf = buf;
10923+
10924+
appendStringInfoString(buf, "(");
10925+
sep = "";
10926+
foreach(cell, bound_datums)
10927+
{
10928+
PartitionRangeDatum *datum =
10929+
castNode(PartitionRangeDatum, lfirst(cell));
10930+
10931+
appendStringInfoString(buf, sep);
10932+
if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
10933+
appendStringInfoString(buf, "MINVALUE");
10934+
else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
10935+
appendStringInfoString(buf, "MAXVALUE");
10936+
else
10937+
{
10938+
Const *val = castNode(Const, datum->value);
10939+
10940+
get_const_expr(val, &context, -1);
10941+
}
10942+
sep = ", ";
10943+
}
10944+
appendStringInfoString(buf, ")");
10945+
10946+
return buf->data;
10947+
}

src/include/utils/ruleutils.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ extern List *set_deparse_context_planstate(List *dpcontext,
3333
extern List *select_rtable_names_for_explain(List *rtable,
3434
Bitmapset *rels_used);
3535
extern char *generate_collation_name(Oid collid);
36+
extern char *get_range_partbound_string(List *bound_datums);
3637

3738
#endif /* RULEUTILS_H */

src/test/regress/expected/create_table.out

+4-2
Original file line numberDiff line numberDiff line change
@@ -567,10 +567,12 @@ CREATE TABLE range_parted2 (
567567
) PARTITION BY RANGE (a);
568568
-- trying to create range partition with empty range
569569
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0);
570-
ERROR: cannot create range partition with empty range
570+
ERROR: empty range bound specified for partition "fail_part"
571+
DETAIL: Specified lower bound (1) is greater than or equal to upper bound (0).
571572
-- note that the range '[1, 1)' has no elements
572573
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1);
573-
ERROR: cannot create range partition with empty range
574+
ERROR: empty range bound specified for partition "fail_part"
575+
DETAIL: Specified lower bound (1) is greater than or equal to upper bound (1).
574576
CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1);
575577
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2);
576578
ERROR: partition "fail_part" would overlap partition "part0"

0 commit comments

Comments
 (0)