aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-05-09 22:41:12 -0400
committerRobert Haas <rhaas@postgresql.org>2017-05-09 22:41:12 -0400
commit3439f84475642fab029df0c06c81df94e6941dc0 (patch)
tree40343d84af3b2cef9075f853ed89df53c7d05b51
parent489b96e80b96c0eda02575347654e87968f2f5f4 (diff)
downloadpostgresql-3439f84475642fab029df0c06c81df94e6941dc0.tar.gz
postgresql-3439f84475642fab029df0c06c81df94e6941dc0.zip
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
-rw-r--r--src/backend/parser/parse_utilcmd.c34
-rw-r--r--src/test/regress/expected/create_table.out7
-rw-r--r--src/test/regress/sql/create_table.sql5
3 files changed, 46 insertions, 0 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index e187409f6f2..882955bb1c9 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -3358,6 +3358,7 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound)
int i,
j;
char *colname;
+ bool seen_unbounded;
if (spec->strategy != PARTITION_STRATEGY_RANGE)
ereport(ERROR,
@@ -3376,6 +3377,39 @@ transformPartitionBound(ParseState *pstate, Relation parent, Node *bound)
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
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;
result_spec->lowerdatums = result_spec->upperdatums = NIL;
forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums)
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index dda0d7ee5df..15d4ce591c7 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -505,6 +505,13 @@ ERROR: TO must specify exactly one value per partitioning column
-- cannot specify null values in range bounds
CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (unbounded);
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
-- cannot create as partition of a non-partitioned table
CREATE TABLE unparted (
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index caf5ddb58b3..95035c5947c 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -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
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
-- cannot create as partition of a non-partitioned table