*/
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)
{
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:
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;
+}
) 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"