aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/sequence.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-04-04 12:36:15 -0400
committerPeter Eisentraut <peter_e@gmx.net>2017-04-04 12:49:39 -0400
commit60a0b2ec8943451186dfa22907f88334d97cb2e0 (patch)
tree4be14644f7a4ce42f4300ef7b5cd134d3f4251d2 /src/backend/commands/sequence.c
parenta9a7949134189c29a9b38ac7394c53849684fe4d (diff)
downloadpostgresql-60a0b2ec8943451186dfa22907f88334d97cb2e0.tar.gz
postgresql-60a0b2ec8943451186dfa22907f88334d97cb2e0.zip
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 <michael.paquier@gmail.com> Reviewed-by: Vitaly Burovoy <vitaly.burovoy@gmail.com>
Diffstat (limited to 'src/backend/commands/sequence.c')
-rw-r--r--src/backend/commands/sequence.c43
1 files changed, 33 insertions, 10 deletions
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;
}