From 60a0b2ec8943451186dfa22907f88334d97cb2e0 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 4 Apr 2017 12:36:15 -0400 Subject: Adjust min/max values when changing sequence type When changing the type of a sequence, adjust the min/max values of the sequence if it looks like the previous values were the default values. Previously, it would leave the old values in place, requiring manual adjustments even in the usual/default cases. Reviewed-by: Michael Paquier Reviewed-by: Vitaly Burovoy --- src/backend/commands/sequence.c | 43 +++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'src/backend/commands/sequence.c') diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index d547db714ea..89b810bbb7b 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1232,6 +1232,8 @@ init_params(ParseState *pstate, List *options, bool isInit, DefElem *cache_value = NULL; DefElem *is_cycled = NULL; ListCell *option; + bool reset_max_value = false; + bool reset_min_value = false; *owned_by = NIL; @@ -1335,13 +1337,34 @@ init_params(ParseState *pstate, List *options, bool isInit, /* AS type */ if (as_type != NULL) { - seqform->seqtypid = typenameTypeId(pstate, defGetTypeName(as_type)); - if (seqform->seqtypid != INT2OID && - seqform->seqtypid != INT4OID && - seqform->seqtypid != INT8OID) + Oid newtypid = typenameTypeId(pstate, defGetTypeName(as_type)); + + if (newtypid != INT2OID && + newtypid != INT4OID && + newtypid != INT8OID) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("sequence type must be smallint, integer, or bigint"))); + + if (!isInit) + { + /* + * When changing type and the old sequence min/max values were the + * min/max of the old type, adjust sequence min/max values to + * min/max of new type. (Otherwise, the user chose explicit + * min/max values, which we'll leave alone.) + */ + if ((seqform->seqtypid == INT2OID && seqform->seqmax == PG_INT16_MAX) || + (seqform->seqtypid == INT4OID && seqform->seqmax == PG_INT32_MAX) || + (seqform->seqtypid == INT8OID && seqform->seqmax == PG_INT64_MAX)) + reset_max_value = true; + if ((seqform->seqtypid == INT2OID && seqform->seqmin == PG_INT16_MIN) || + (seqform->seqtypid == INT4OID && seqform->seqmin == PG_INT32_MIN) || + (seqform->seqtypid == INT8OID && seqform->seqmin == PG_INT64_MIN)) + reset_min_value = true; + } + + seqform->seqtypid = newtypid; } else if (isInit) seqform->seqtypid = INT8OID; @@ -1375,9 +1398,9 @@ init_params(ParseState *pstate, List *options, bool isInit, seqform->seqmax = defGetInt64(max_value); seqdataform->log_cnt = 0; } - else if (isInit || max_value != NULL) + else if (isInit || max_value != NULL || reset_max_value) { - if (seqform->seqincrement > 0) + if (seqform->seqincrement > 0 || reset_max_value) { /* ascending seq */ if (seqform->seqtypid == INT2OID) @@ -1412,11 +1435,9 @@ init_params(ParseState *pstate, List *options, bool isInit, seqform->seqmin = defGetInt64(min_value); seqdataform->log_cnt = 0; } - else if (isInit || min_value != NULL) + else if (isInit || min_value != NULL || reset_min_value) { - if (seqform->seqincrement > 0) - seqform->seqmin = 1; /* ascending seq */ - else + if (seqform->seqincrement < 0 || reset_min_value) { /* descending seq */ if (seqform->seqtypid == INT2OID) @@ -1426,6 +1447,8 @@ init_params(ParseState *pstate, List *options, bool isInit, else seqform->seqmin = PG_INT64_MIN; } + else + seqform->seqmin = 1; /* ascending seq */ seqdataform->log_cnt = 0; } -- cgit v1.2.3