aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-09-15 21:15:55 -0400
committerRobert Haas <rhaas@postgresql.org>2017-09-15 21:15:55 -0400
commit9361f6f54e3ff9bab84e80d4b1e15be79b48d60e (patch)
treee1e17babdceb4afef02a4b55eb43189e907cef96 /src/backend/parser/parse_utilcmd.c
parentc29145f00df2aa873672ab9f1b3fc4ec6a0ec05d (diff)
downloadpostgresql-9361f6f54e3ff9bab84e80d4b1e15be79b48d60e.tar.gz
postgresql-9361f6f54e3ff9bab84e80d4b1e15be79b48d60e.zip
After a MINVALUE/MAXVALUE bound, allow only more of the same.
In the old syntax, which used UNBOUNDED, we had a similar restriction, but commit d363d42bb9a4399a0207bd3b371c966e22e06bd3, which changed the syntax, eliminated it. Put it back. Patch by me, reviewed by Dean Rasheed. Discussion: http://postgr.es/m/CA+Tgmobs+pLPC27tS3gOpEAxAffHrq5w509cvkwTf9pF6cWYbg@mail.gmail.com
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 655da02c109..27e568fc626 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -135,6 +135,7 @@ static void transformConstraintAttrs(CreateStmtContext *cxt,
static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column);
static void setSchemaName(char *context_schema, char **stmt_schema_name);
static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd);
+static void validateInfiniteBounds(ParseState *pstate, List *blist);
static Const *transformPartitionBoundValue(ParseState *pstate, A_Const *con,
const char *colName, Oid colType, int32 colTypmod);
@@ -3397,6 +3398,13 @@ transformPartitionBound(ParseState *pstate, Relation parent,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("TO must specify exactly one value per partitioning column")));
+ /*
+ * Once we see MINVALUE or MAXVALUE for one column, the remaining
+ * columns must be the same.
+ */
+ validateInfiniteBounds(pstate, spec->lowerdatums);
+ validateInfiniteBounds(pstate, spec->upperdatums);
+
/* Transform all the constants */
i = j = 0;
result_spec->lowerdatums = result_spec->upperdatums = NIL;
@@ -3469,6 +3477,46 @@ transformPartitionBound(ParseState *pstate, Relation parent,
}
/*
+ * validateInfiniteBounds
+ *
+ * Check that a MAXVALUE or MINVALUE specification in a partition bound is
+ * followed only by more of the same.
+ */
+static void
+validateInfiniteBounds(ParseState *pstate, List *blist)
+{
+ ListCell *lc;
+ PartitionRangeDatumKind kind = PARTITION_RANGE_DATUM_VALUE;
+
+ foreach(lc, blist)
+ {
+ PartitionRangeDatum *prd = castNode(PartitionRangeDatum, lfirst(lc));
+
+ if (kind == prd->kind)
+ continue;
+
+ switch (kind)
+ {
+ case PARTITION_RANGE_DATUM_VALUE:
+ kind = prd->kind;
+ break;
+
+ case PARTITION_RANGE_DATUM_MAXVALUE:
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("every bound following MAXVALUE must also be MAXVALUE"),
+ parser_errposition(pstate, exprLocation((Node *) prd))));
+
+ case PARTITION_RANGE_DATUM_MINVALUE:
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("every bound following MINVALUE must also be MINVALUE"),
+ parser_errposition(pstate, exprLocation((Node *) prd))));
+ }
+ }
+}
+
+/*
* Transform one constant in a partition bound spec
*/
static Const *