aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
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 *