aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-08-10 13:44:30 -0400
committerRobert Haas <rhaas@postgresql.org>2017-08-10 13:46:56 -0400
commitbb5d6e80b1387f0de58e55ac8e882f68ec6d4fcf (patch)
tree5d6488d2901c72a8a5ad5984294b27691319aee1 /src
parentc1ef4e5cdb11cd562891f4ad2f30d1e3583a973d (diff)
downloadpostgresql-bb5d6e80b1387f0de58e55ac8e882f68ec6d4fcf.tar.gz
postgresql-bb5d6e80b1387f0de58e55ac8e882f68ec6d4fcf.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/partition.c10
-rw-r--r--src/backend/utils/adt/ruleutils.c84
-rw-r--r--src/include/utils/ruleutils.h1
-rw-r--r--src/test/regress/expected/create_table.out6
4 files changed, 56 insertions, 45 deletions
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index dcc7f8af27c..0e4b343ab28 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -722,10 +722,16 @@ check_new_partition_bound(char *relname, Relation parent,
*/
if (partition_rbound_cmp(key, lower->datums, lower->kind, true,
upper) >= 0)
+ {
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("cannot create range partition with empty range"),
- parser_errposition(pstate, spec->location)));
+ errmsg("empty range bound specified for partition \"%s\"",
+ relname),
+ errdetail("Specified lower bound %s is greater than or equal to upper bound %s.",
+ get_range_partbound_string(spec->lowerdatums),
+ get_range_partbound_string(spec->upperdatums)),
+ parser_errposition(pstate, spec->location)));
+ }
if (partdesc->nparts > 0)
{
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index d83377d1d88..0faa0204cef 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8722,47 +8722,9 @@ get_rule_expr(Node *node, deparse_context *context,
list_length(spec->lowerdatums) ==
list_length(spec->upperdatums));
- appendStringInfoString(buf, "FOR VALUES FROM (");
- sep = "";
- foreach(cell, spec->lowerdatums)
- {
- PartitionRangeDatum *datum =
- castNode(PartitionRangeDatum, lfirst(cell));
-
- appendStringInfoString(buf, sep);
- if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
- appendStringInfoString(buf, "MINVALUE");
- else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
- appendStringInfoString(buf, "MAXVALUE");
- else
- {
- Const *val = castNode(Const, datum->value);
-
- get_const_expr(val, context, -1);
- }
- sep = ", ";
- }
- appendStringInfoString(buf, ") TO (");
- sep = "";
- foreach(cell, spec->upperdatums)
- {
- PartitionRangeDatum *datum =
- castNode(PartitionRangeDatum, lfirst(cell));
-
- appendStringInfoString(buf, sep);
- if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
- appendStringInfoString(buf, "MINVALUE");
- else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
- appendStringInfoString(buf, "MAXVALUE");
- else
- {
- Const *val = castNode(Const, datum->value);
-
- get_const_expr(val, context, -1);
- }
- sep = ", ";
- }
- appendStringInfoString(buf, ")");
+ appendStringInfo(buf, "FOR VALUES FROM %s TO %s",
+ get_range_partbound_string(spec->lowerdatums),
+ get_range_partbound_string(spec->upperdatums));
break;
default:
@@ -10943,3 +10905,43 @@ flatten_reloptions(Oid relid)
return result;
}
+
+/*
+ * get_one_range_partition_bound_string
+ * A C string representation of one range partition bound
+ */
+char *
+get_range_partbound_string(List *bound_datums)
+{
+ deparse_context context;
+ StringInfo buf = makeStringInfo();
+ ListCell *cell;
+ char *sep;
+
+ memset(&context, 0, sizeof(deparse_context));
+ context.buf = buf;
+
+ appendStringInfoString(buf, "(");
+ sep = "";
+ foreach(cell, bound_datums)
+ {
+ PartitionRangeDatum *datum =
+ castNode(PartitionRangeDatum, lfirst(cell));
+
+ appendStringInfoString(buf, sep);
+ if (datum->kind == PARTITION_RANGE_DATUM_MINVALUE)
+ appendStringInfoString(buf, "MINVALUE");
+ else if (datum->kind == PARTITION_RANGE_DATUM_MAXVALUE)
+ appendStringInfoString(buf, "MAXVALUE");
+ else
+ {
+ Const *val = castNode(Const, datum->value);
+
+ get_const_expr(val, &context, -1);
+ }
+ sep = ", ";
+ }
+ appendStringInfoString(buf, ")");
+
+ return buf->data;
+}
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index a2206cb7cd0..e9c51938556 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -33,5 +33,6 @@ extern List *set_deparse_context_planstate(List *dpcontext,
extern List *select_rtable_names_for_explain(List *rtable,
Bitmapset *rels_used);
extern char *generate_collation_name(Oid collid);
+extern char *get_range_partbound_string(List *bound_datums);
#endif /* RULEUTILS_H */
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index aa44c112735..babda8978c7 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -567,10 +567,12 @@ CREATE TABLE range_parted2 (
) PARTITION BY RANGE (a);
-- trying to create range partition with empty range
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0);
-ERROR: cannot create range partition with empty range
+ERROR: empty range bound specified for partition "fail_part"
+DETAIL: Specified lower bound (1) is greater than or equal to upper bound (0).
-- note that the range '[1, 1)' has no elements
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1);
-ERROR: cannot create range partition with empty range
+ERROR: empty range bound specified for partition "fail_part"
+DETAIL: Specified lower bound (1) is greater than or equal to upper bound (1).
CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2);
ERROR: partition "fail_part" would overlap partition "part0"