v4-0001-Improve-check-new-partition-bound-error-position-.patch
application/octet-stream
Filename: v4-0001-Improve-check-new-partition-bound-error-position-.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v4-0001
Subject: Improve check new partition bound error position report
| File | + | − |
|---|---|---|
| src/backend/commands/tablecmds.c | 10 | 5 |
| src/backend/parser/parse_utilcmd.c | 3 | 0 |
| src/backend/partitioning/partbounds.c | 51 | 30 |
| src/include/partitioning/partbounds.h | 3 | 1 |
| src/test/regress/expected/alter_table.out | 10 | 0 |
| src/test/regress/expected/create_table.out | 30 | 0 |
From 5e5c45eeecc3f5d56475e5d9b9eab4d1eca927a4 Mon Sep 17 00:00:00 2001
From: Alexandra Wang <walexandra@vmware.com>
Date: Fri, 10 Jul 2020 10:28:49 -0700
Subject: [PATCH v4] Improve check new partition bound error position report
We have been passing a dummy ParseState to ereport(). Without the source
text in the ParseState ereport does not report the error position even
if a error location is supplied. This patch passes a ParseState to
check_new_partition_bound() when it is available.
-- Create parent table
create table foo (a int, b int, c date) partition by range (b,c);
-- Before:
create table foo_part_1 partition of foo for values from (1, date '2007-01-01') to (1, date '2006-01-01');
ERROR: empty range bound specified for partition "foo_part_1"
DETAIL: Specified lower bound (1, '2007-01-01') is greater than or equal to upper bound (1, '2006-01-01').
-- After:
create table foo_part_1 partition of foo for values from (1, date '2007-01-01') to (1, date '2006-01-01');
ERROR: empty range bound specified for partition "foo_part_1"
LINE 1: ...e foo_part_1 partition of foo for values from (1, date '2007...
^
DETAIL: Specified lower bound (1, '2007-01-01') is greater than or equal to upper bound (1, '2006-01-01').
Co-authored-by: Ashwin Agrawal <aashwin@vmware.com>
Co-authored-by: Amit Langote <amitlangote09@gmail.com>
---
src/backend/commands/tablecmds.c | 15 ++++--
src/backend/parser/parse_utilcmd.c | 3 ++
src/backend/partitioning/partbounds.c | 81 +++++++++++++++++++-----------
src/include/partitioning/partbounds.h | 4 +-
src/test/regress/expected/alter_table.out | 10 ++++
src/test/regress/expected/create_table.out | 30 +++++++++++
6 files changed, 107 insertions(+), 36 deletions(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index eab570a..9038310 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -543,7 +543,8 @@ static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partPa
static void CreateInheritance(Relation child_rel, Relation parent_rel);
static void RemoveInheritance(Relation child_rel, Relation parent_rel);
static ObjectAddress ATExecAttachPartition(List **wqueue, Relation rel,
- PartitionCmd *cmd);
+ PartitionCmd *cmd,
+ AlterTableUtilityContext * context);
static void AttachPartitionEnsureIndexes(Relation rel, Relation attachrel);
static void QueuePartitionConstraintValidation(List **wqueue, Relation scanrel,
List *partConstraint,
@@ -1007,7 +1008,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* Check first that the new partition's bound is valid and does not
* overlap with any of existing partitions of the parent.
*/
- check_new_partition_bound(relname, parent, bound);
+ check_new_partition_bound(relname, parent, bound, pstate);
/*
* If the default partition exists, its partition constraints will
@@ -4718,7 +4719,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
cur_pass, context);
Assert(cmd != NULL);
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def);
+ ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def,
+ context);
else
ATExecAttachPartitionIdx(wqueue, rel,
((PartitionCmd *) cmd->def)->name);
@@ -16280,7 +16282,8 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel,
* Return the address of the newly attached partition.
*/
static ObjectAddress
-ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
+ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd,
+ AlterTableUtilityContext * context)
{
Relation attachrel,
catalog;
@@ -16295,6 +16298,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
const char *trigger_name;
Oid defaultPartOid;
List *partBoundConstraint;
+ ParseState *pstate = make_parsestate(NULL);
/*
* We must lock the default partition if one exists, because attaching a
@@ -16459,8 +16463,9 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
* of existing partitions of the parent - note that it does not return on
* error.
*/
+ pstate->p_sourcetext = context->queryString;
check_new_partition_bound(RelationGetRelationName(attachrel), rel,
- cmd->bound);
+ cmd->bound, pstate);
/* OK to create inheritance. Rest of the checks performed there */
CreateInheritance(attachrel, rel);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index ec94437..6626757 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -4256,5 +4256,8 @@ transformPartitionBoundValue(ParseState *pstate, Node *val,
if (!IsA(value, Const))
elog(ERROR, "could not evaluate partition bound expression");
+ /* Preserve parser location information. */
+ ((Const *) value)->location = exprLocation(val);
+
return (Const *) value;
}
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 58f9b46..5cf1bf0 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -220,10 +220,10 @@ static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
Oid *partcollation, Datum *datums1,
PartitionRangeDatumKind *kind1, bool lower1,
PartitionRangeBound *b2);
-static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
- Oid *partcollation,
- PartitionBoundInfo boundinfo,
- PartitionRangeBound *probe, bool *is_equal);
+static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
+ Oid *partcollation,
+ PartitionBoundInfo boundinfo,
+ PartitionRangeBound *probe, int32 *cmpval);
static int get_partition_bound_num_indexes(PartitionBoundInfo b);
static Expr *make_partition_op_expr(PartitionKey key, int keynum,
uint16 strategy, Expr *arg1, Expr *arg2);
@@ -2805,14 +2805,14 @@ partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts)
*/
void
check_new_partition_bound(char *relname, Relation parent,
- PartitionBoundSpec *spec)
+ PartitionBoundSpec *spec, ParseState *pstate)
{
PartitionKey key = RelationGetPartitionKey(parent);
PartitionDesc partdesc = RelationGetPartitionDesc(parent);
PartitionBoundInfo boundinfo = partdesc->boundinfo;
- ParseState *pstate = make_parsestate(NULL);
int with = -1;
bool overlap = false;
+ int overlap_location = 0;
if (spec->is_default)
{
@@ -2907,6 +2907,7 @@ check_new_partition_bound(char *relname, Relation parent,
if (boundinfo->indexes[remainder] != -1)
{
overlap = true;
+ overlap_location = spec->location;
with = boundinfo->indexes[remainder];
break;
}
@@ -2935,6 +2936,7 @@ check_new_partition_bound(char *relname, Relation parent,
{
Const *val = castNode(Const, lfirst(cell));
+ overlap_location = val->location;
if (!val->constisnull)
{
int offset;
@@ -2968,6 +2970,7 @@ check_new_partition_bound(char *relname, Relation parent,
{
PartitionRangeBound *lower,
*upper;
+ int cmpval;
Assert(spec->strategy == PARTITION_STRATEGY_RANGE);
lower = make_one_partition_rbound(key, -1, spec->lowerdatums, true);
@@ -2977,10 +2980,16 @@ check_new_partition_bound(char *relname, Relation parent,
* First check if the resulting range would be empty with
* specified lower and upper bounds
*/
- if (partition_rbound_cmp(key->partnatts, key->partsupfunc,
- key->partcollation, lower->datums,
- lower->kind, true, upper) >= 0)
+ cmpval = partition_rbound_cmp(key->partnatts,
+ key->partsupfunc,
+ key->partcollation, lower->datums,
+ lower->kind, true, upper);
+ if (cmpval >= 0)
{
+ /* Fetch the problem bound from lower datums list. */
+ PartitionRangeDatum *datum = list_nth(spec->lowerdatums,
+ cmpval - 1);
+
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("empty range bound specified for partition \"%s\"",
@@ -2988,13 +2997,12 @@ check_new_partition_bound(char *relname, Relation parent,
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)));
+ parser_errposition(pstate, datum->location)));
}
if (partdesc->nparts > 0)
{
int offset;
- bool equal;
Assert(boundinfo &&
boundinfo->strategy == PARTITION_STRATEGY_RANGE &&
@@ -3020,7 +3028,7 @@ check_new_partition_bound(char *relname, Relation parent,
key->partsupfunc,
key->partcollation,
boundinfo, lower,
- &equal);
+ &cmpval);
if (boundinfo->indexes[offset + 1] < 0)
{
@@ -3032,7 +3040,6 @@ check_new_partition_bound(char *relname, Relation parent,
*/
if (offset + 1 < boundinfo->ndatums)
{
- int32 cmpval;
Datum *datums;
PartitionRangeDatumKind *kind;
bool is_lower;
@@ -3054,6 +3061,8 @@ check_new_partition_bound(char *relname, Relation parent,
* offset + 2.
*/
overlap = true;
+ overlap_location = ((PartitionRangeDatum *)
+ list_nth(spec->upperdatums, -cmpval - 1))->location;
with = boundinfo->indexes[offset + 2];
}
}
@@ -3064,7 +3073,14 @@ check_new_partition_bound(char *relname, Relation parent,
* The new partition overlaps with the existing
* partition between offset and offset + 1.
*/
+ Datum *datum;
+
overlap = true;
+ /* New lower bound is certainly >= bound at offet. */
+ Assert(cmpval >= 0);
+ datum = cmpval == 0 ? linitial(spec->lowerdatums):
+ list_nth(spec->lowerdatums, cmpval - 1);
+ overlap_location = ((PartitionRangeDatum *) datum)->location;
with = boundinfo->indexes[offset + 1];
}
}
@@ -3080,11 +3096,12 @@ check_new_partition_bound(char *relname, Relation parent,
if (overlap)
{
Assert(with >= 0);
+ Assert(overlap_location > 0);
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("partition \"%s\" would overlap partition \"%s\"",
relname, get_rel_name(partdesc->oids[with])),
- parser_errposition(pstate, spec->location)));
+ parser_errposition(pstate, overlap_location)));
}
}
@@ -3317,8 +3334,10 @@ make_one_partition_rbound(PartitionKey key, int index, List *datums, bool lower)
/*
* partition_rbound_cmp
*
- * Return for two range bounds whether the 1st one (specified in datums1,
- * kind1, and lower1) is <, =, or > the bound specified in *b2.
+ * For two range bounds this decides whether the 1st one (specified in
+ * datums1, kind1, and lower1) is <, =, or > the bound specified in *b2. 0 is
+ * returned if equal, otherwise a non-zero integer whose absolute values gives
+ * the 1-based partition key number of the first mismatching column.
*
* partnatts, partsupfunc and partcollation give the number of attributes in the
* bounds to be compared, comparison function to be used and the collations of
@@ -3338,6 +3357,7 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
bool lower1, PartitionRangeBound *b2)
{
int32 cmpval = 0; /* placate compiler */
+ int result = 0;
int i;
Datum *datums2 = b2->datums;
PartitionRangeDatumKind *kind2 = b2->kind;
@@ -3345,6 +3365,8 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
for (i = 0; i < partnatts; i++)
{
+ result++;
+
/*
* First, handle cases where the column is unbounded, which should not
* invoke the comparison procedure, and should not consider any later
@@ -3352,9 +3374,9 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
* compare the same way as the values they represent.
*/
if (kind1[i] < kind2[i])
- return -1;
+ return -result;
else if (kind1[i] > kind2[i])
- return 1;
+ return result;
else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE)
/*
@@ -3379,9 +3401,9 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
* two.
*/
if (cmpval == 0 && lower1 != lower2)
- cmpval = lower1 ? 1 : -1;
+ cmpval = lower1 ? result : -result;
- return cmpval;
+ return cmpval == 0 ? 0 : (cmpval < 0 ? -result : result);;
}
/*
@@ -3486,14 +3508,16 @@ partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation,
* equal to the given range bound or -1 if all of the range bounds are
* greater
*
- * *is_equal is set to true if the range bound at the returned index is equal
- * to the input range bound
+ * Upon return from this function, *cmpval is set to 0 if the bound at the
+ * returned index matches exactly with the input range bound, otherwise a
+ * non-zero integer whose absolute value gives the 1-based partition key number
+ * of the first mismatching column.
*/
static int
partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
Oid *partcollation,
PartitionBoundInfo boundinfo,
- PartitionRangeBound *probe, bool *is_equal)
+ PartitionRangeBound *probe, int32 *cmpval)
{
int lo,
hi,
@@ -3503,21 +3527,18 @@ partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
hi = boundinfo->ndatums - 1;
while (lo < hi)
{
- int32 cmpval;
-
mid = (lo + hi + 1) / 2;
- cmpval = partition_rbound_cmp(partnatts, partsupfunc,
+ *cmpval = partition_rbound_cmp(partnatts, partsupfunc,
partcollation,
boundinfo->datums[mid],
boundinfo->kind[mid],
(boundinfo->indexes[mid] == -1),
probe);
- if (cmpval <= 0)
+ if (*cmpval <= 0)
{
lo = mid;
- *is_equal = (cmpval == 0);
- if (*is_equal)
+ if (*cmpval == 0)
break;
}
else
@@ -3528,7 +3549,7 @@ partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
}
/*
- * partition_range_bsearch
+ * partition_range_datum_bsearch
* Returns the index of the greatest range bound that is less than or
* equal to the given tuple or -1 if all of the range bounds are greater
*
diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h
index dfc7207..c82f77d 100644
--- a/src/include/partitioning/partbounds.h
+++ b/src/include/partitioning/partbounds.h
@@ -14,6 +14,7 @@
#include "fmgr.h"
#include "nodes/parsenodes.h"
#include "nodes/pg_list.h"
+#include "parser/parse_node.h"
#include "partitioning/partdefs.h"
#include "utils/relcache.h"
struct RelOptInfo; /* avoid including pathnodes.h here */
@@ -98,7 +99,8 @@ extern PartitionBoundInfo partition_bounds_merge(int partnatts,
List **inner_parts);
extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts);
extern void check_new_partition_bound(char *relname, Relation parent,
- PartitionBoundSpec *spec);
+ PartitionBoundSpec *spec,
+ ParseState *pstate);
extern void check_default_partition_contents(Relation parent,
Relation defaultRel,
PartitionBoundSpec *new_spec);
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index f566153..0ce6ee4 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -3868,6 +3868,8 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_1'::reg
CREATE TABLE fail_part (LIKE part_1 INCLUDING CONSTRAINTS);
ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
ERROR: partition "fail_part" would overlap partition "part_1"
+LINE 1: ...LE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
+ ^
DROP TABLE fail_part;
-- check that an existing table can be attached as a default partition
CREATE TABLE def_part (LIKE list_parted INCLUDING CONSTRAINTS);
@@ -3877,6 +3879,8 @@ ALTER TABLE list_parted ATTACH PARTITION def_part DEFAULT;
CREATE TABLE fail_def_part (LIKE part_1 INCLUDING CONSTRAINTS);
ALTER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT;
ERROR: partition "fail_def_part" conflicts with existing default partition "def_part"
+LINE 1: ...ER TABLE list_parted ATTACH PARTITION fail_def_part DEFAULT;
+ ^
-- check validation when attaching list partitions
CREATE TABLE list_parted2 (
a int,
@@ -3946,6 +3950,8 @@ CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT;
CREATE TABLE partr_def2 (LIKE part1 INCLUDING CONSTRAINTS);
ALTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT;
ERROR: partition "partr_def2" conflicts with existing default partition "partr_def1"
+LINE 1: ...LTER TABLE range_parted ATTACH PARTITION partr_def2 DEFAULT;
+ ^
-- Overlapping partitions cannot be attached, hence, following should give error
INSERT INTO partr_def1 VALUES (2, 10);
CREATE TABLE part3 (LIKE range_parted);
@@ -4066,8 +4072,12 @@ CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAIN
CREATE TABLE fail_part (LIKE hpart_1);
ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4);
ERROR: partition "fail_part" would overlap partition "hpart_1"
+LINE 1: ...hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODU...
+ ^
ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 0);
ERROR: partition "fail_part" would overlap partition "hpart_1"
+LINE 1: ...hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODU...
+ ^
DROP TABLE fail_part;
-- check validation when attaching hash partitions
-- check that violating rows are correctly reported
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 1c72f23..41dce69 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -677,6 +677,8 @@ LINE 1: ...BLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODU...
CREATE TABLE part_default PARTITION OF list_parted DEFAULT;
CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT;
ERROR: partition "fail_default_part" conflicts with existing default partition "part_default"
+LINE 1: ...TE TABLE fail_default_part PARTITION OF list_parted DEFAULT;
+ ^
-- specified literal can't be cast to the partition column data type
CREATE TABLE bools (
a bool
@@ -702,6 +704,8 @@ CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10);
-- fails due to overlap:
CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10');
ERROR: partition "bigintp_10_2" would overlap partition "bigintp_10"
+LINE 1: ...ABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10');
+ ^
DROP TABLE bigintp;
CREATE TABLE range_parted (
a date
@@ -823,8 +827,12 @@ CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b');
CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT;
CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null);
ERROR: partition "fail_part" would overlap partition "part_null_z"
+LINE 1: ...LE fail_part PARTITION OF list_parted2 FOR VALUES IN (null);
+ ^
CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c');
ERROR: partition "fail_part" would overlap partition "part_ab"
+LINE 1: ...ail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c');
+ ^
-- check default partition overlap
INSERT INTO list_parted2 VALUES('X');
CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y');
@@ -835,28 +843,42 @@ CREATE TABLE range_parted2 (
-- trying to create range partition with empty range
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0);
ERROR: empty range bound specified for partition "fail_part"
+LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0);
+ ^
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: empty range bound specified for partition "fail_part"
+LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1);
+ ^
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"
+LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) ...
+ ^
CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue);
ERROR: partition "fail_part" would overlap partition "part1"
+LINE 1: ..._part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (max...
+ ^
CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30);
CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30);
ERROR: partition "fail_part" would overlap partition "part2"
+LINE 1: ...art PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30);
+ ^
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50);
ERROR: partition "fail_part" would overlap partition "part2"
+LINE 1: ...art PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50);
+ ^
-- Create a default partition for range partitioned table
CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT;
-- More than one default partition is not allowed, so this should give error
CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT;
ERROR: partition "fail_default_part" conflicts with existing default partition "range2_default"
+LINE 1: ... TABLE fail_default_part PARTITION OF range_parted2 DEFAULT;
+ ^
-- Check if the range for default partitions overlap
INSERT INTO range_parted2 VALUES (85);
CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90);
@@ -870,17 +892,23 @@ CREATE TABLE range_parted3 (
CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue);
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1);
ERROR: partition "fail_part" would overlap partition "part00"
+LINE 1: ..._part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalu...
+ ^
CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1);
CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10);
CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue);
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20);
ERROR: partition "fail_part" would overlap partition "part12"
+LINE 1: ...rt PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1,...
+ ^
CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT;
-- cannot create a partition that says column b is allowed to range
-- from -infinity to +infinity, while there exist partitions that have
-- more specific ranges
CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue);
ERROR: partition "fail_part" would overlap partition "part10"
+LINE 1: ..._part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalu...
+ ^
-- check for partition bound overlap and other invalid specifications for the hash partition
CREATE TABLE hash_parted2 (
a varchar
@@ -892,6 +920,8 @@ CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMA
-- overlap with part_4
CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
ERROR: partition "fail_part" would overlap partition "h2part_4"
+LINE 1: ...LE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODU...
+ ^
-- modulus must be greater than zero
CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1);
ERROR: modulus for hash partition must be a positive integer
--
1.8.3.1