On 2017/08/10 5:59, Tom Lane wrote:
> Alvaro Herrera <alvhe...@2ndquadrant.com> writes:
>> Dean Rasheed wrote:
>>> There was an earlier suggestion to use "greater than or equal to". I
>>> think that would work quite well:
> 
>> Is it possible to detect the equality case specifically and use a
>> different errdetail?  Something like "the lower bound %s is equal to the
>> upper bound" (obviously without including both in the message.)
> 
> That seems like overkill.  I'm good with "greater than or equal to".

Attached updated patch has "greater than or equal to".

Thanks,
Amit
From 11d40a76dc9e56a85fe480fd5690a53406cea9c3 Mon Sep 17 00:00:00 2001
From: amit <amitlangot...@gmail.com>
Date: Wed, 9 Aug 2017 14:36:57 +0900
Subject: [PATCH] Fix error message when apprently empty range bound is
 specified

---
 src/backend/catalog/partition.c            | 10 +++-
 src/backend/utils/adt/ruleutils.c          | 84 +++++++++++++++---------------
 src/include/utils/ruleutils.h              |  1 +
 src/test/regress/expected/create_table.out |  6 ++-
 4 files changed, 56 insertions(+), 45 deletions(-)

diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index dcc7f8af27..65630421d3 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("invalid range 
bound specification 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 d83377d1d8..0faa0204ce 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 a2206cb7cd..e9c5193855 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 aa44c11273..b94a7b8426 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:  invalid range bound specification 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:  invalid range bound specification 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"
-- 
2.11.0

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to