Commit 3439f844 authored by Robert Haas's avatar Robert Haas

Disallow finite partition bound following earlier UNBOUNDED column.

Amit Langote, per an observation by me.

Discussion: http://postgr.es/m/CA+TgmoYWnV2GMnYLG-Czsix-E1WGAbo4D+0tx7t9NdfYBDMFsA@mail.gmail.com
parent 489b96e8
...@@ -3358,6 +3358,7 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound) ...@@ -3358,6 +3358,7 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound)
int i, int i,
j; j;
char *colname; char *colname;
bool seen_unbounded;
if (spec->strategy != PARTITION_STRATEGY_RANGE) if (spec->strategy != PARTITION_STRATEGY_RANGE)
ereport(ERROR, ereport(ERROR,
...@@ -3376,6 +3377,39 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound) ...@@ -3376,6 +3377,39 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound)
(errcode(ERRCODE_INVALID_TABLE_DEFINITION), (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("TO must specify exactly one value per partitioning column"))); errmsg("TO must specify exactly one value per partitioning column")));
/*
* Check that no finite value follows a UNBOUNDED literal in either of
* lower and upper bound lists.
*/
seen_unbounded = false;
foreach(cell1, spec->lowerdatums)
{
PartitionRangeDatum *ldatum;
ldatum = (PartitionRangeDatum *) lfirst(cell1);
if (ldatum->infinite)
seen_unbounded = true;
else if (seen_unbounded)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot specify finite value after UNBOUNDED"),
parser_errposition(pstate, exprLocation((Node *) ldatum))));
}
seen_unbounded = false;
foreach(cell1, spec->upperdatums)
{
PartitionRangeDatum *rdatum;
rdatum = (PartitionRangeDatum *) lfirst(cell1);
if (rdatum->infinite)
seen_unbounded = true;
else if (seen_unbounded)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot specify finite value after UNBOUNDED"),
parser_errposition(pstate, exprLocation((Node *) rdatum))));
}
i = j = 0; i = j = 0;
result_spec->lowerdatums = result_spec->upperdatums = NIL; result_spec->lowerdatums = result_spec->upperdatums = NIL;
forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums) forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums)
......
...@@ -505,6 +505,13 @@ ERROR: TO must specify exactly one value per partitioning column ...@@ -505,6 +505,13 @@ ERROR: TO must specify exactly one value per partitioning column
-- cannot specify null values in range bounds -- cannot specify null values in range bounds
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (unbounded); CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (unbounded);
ERROR: cannot specify NULL in range bound ERROR: cannot specify NULL in range bound
-- cannot specify finite values after UNBOUNDED has been specified
CREATE TABLE range_parted_multicol (a int, b int, c int) PARTITION BY RANGE (a, b, c);
CREATE TABLE fail_part PARTITION OF range_parted_multicol FOR VALUES FROM (1, UNBOUNDED, 1) TO (UNBOUNDED, 1, 1);
ERROR: cannot specify finite value after UNBOUNDED
LINE 1: ...ge_parted_multicol FOR VALUES FROM (1, UNBOUNDED, 1) TO (UNB...
^
DROP TABLE range_parted_multicol;
-- check if compatible with the specified parent -- check if compatible with the specified parent
-- cannot create as partition of a non-partitioned table -- cannot create as partition of a non-partitioned table
CREATE TABLE unparted ( CREATE TABLE unparted (
......
...@@ -473,6 +473,11 @@ CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', ...@@ -473,6 +473,11 @@ CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z',
-- cannot specify null values in range bounds -- cannot specify null values in range bounds
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (unbounded); CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (unbounded);
-- cannot specify finite values after UNBOUNDED has been specified
CREATE TABLE range_parted_multicol (a int, b int, c int) PARTITION BY RANGE (a, b, c);
CREATE TABLE fail_part PARTITION OF range_parted_multicol FOR VALUES FROM (1, UNBOUNDED, 1) TO (UNBOUNDED, 1, 1);
DROP TABLE range_parted_multicol;
-- check if compatible with the specified parent -- check if compatible with the specified parent
-- cannot create as partition of a non-partitioned table -- cannot create as partition of a non-partitioned table
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment