1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-17 17:02:08 +03:00

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 d363d42bb9, 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
This commit is contained in:
Robert Haas
2017-09-15 21:15:55 -04:00
parent c29145f00d
commit 9361f6f54e
8 changed files with 102 additions and 37 deletions

View File

@ -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;
@ -3468,6 +3476,46 @@ transformPartitionBound(ParseState *pstate, Relation parent,
return result_spec;
}
/*
* 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
*/