From 03db510539b4f0ebc4fea35dd07bcb7630198e5c Mon Sep 17 00:00:00 2001 From: Vitaly Burovoy Date: Fri, 31 Mar 2017 02:25:23 +0000 Subject: [PATCH 2/2] Fix overriding max/min value of a sequence to +-1 on "ALTER...AS type" If the max/min value match the bounds of the old type and neither MAXVALUE/MINVALUE nor NO MAXVALUE/NO MINVALUE are set, change values to the bounds of the new type, not treat it as NO MAXVALUE/NO MINVALUE. --- src/backend/commands/sequence.c | 4 ++-- src/test/regress/expected/sequence.out | 41 ++++++++++++++++++++++++++++++++-- src/test/regress/sql/sequence.sql | 21 +++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 3f0e9d5..c2ee7d6 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1400,7 +1400,7 @@ init_params(ParseState *pstate, List *options, bool isInit, } 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) @@ -1437,7 +1437,7 @@ init_params(ParseState *pstate, List *options, bool isInit, } else if (isInit || min_value != NULL || reset_min_value) { - if (seqform->seqincrement > 0) + if (seqform->seqincrement > 0 && !reset_min_value) seqform->seqmin = 1; /* ascending seq */ else { diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out index a5de1f3..7464d7c 100644 --- a/src/test/regress/expected/sequence.out +++ b/src/test/regress/expected/sequence.out @@ -33,6 +33,11 @@ CREATE SEQUENCE sequence_test5 AS integer; CREATE SEQUENCE sequence_test6 AS smallint; CREATE SEQUENCE sequence_test7 AS bigint; CREATE SEQUENCE sequence_test8 AS integer MAXVALUE 100000; +CREATE SEQUENCE sequence_test9 AS integer MINVALUE -100000 START 1; +CREATE SEQUENCE sequence_testa AS smallint; +CREATE SEQUENCE sequence_testb AS smallint INCREMENT -1; +CREATE SEQUENCE sequence_testc AS smallint MINVALUE -32768; +CREATE SEQUENCE sequence_testd AS smallint MAXVALUE 32767 INCREMENT -1; CREATE SEQUENCE sequence_testx AS text; ERROR: sequence type must be smallint, integer, or bigint CREATE SEQUENCE sequence_testx AS nosuchtype; @@ -47,6 +52,28 @@ ALTER SEQUENCE sequence_test5 AS smallint; -- success, max will be adjusted ALTER SEQUENCE sequence_test8 AS smallint; -- fail, max has to be adjusted ERROR: MAXVALUE (100000) is out of range for sequence data type smallint ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000; -- ok now +ALTER SEQUENCE sequence_test9 AS smallint; -- fail, min has to be adjusted +ERROR: MINVALUE (-100000) is out of range for sequence data type smallint +ALTER SEQUENCE sequence_test9 AS smallint MINVALUE -20000; -- ok now +ALTER SEQUENCE sequence_testa AS int; -- enlarge a single bound +ALTER SEQUENCE sequence_testb AS int; -- enlarge a single bound +ALTER SEQUENCE sequence_testc AS int; -- enlarge both bounds +ALTER SEQUENCE sequence_testd AS int; -- enlarge both bounds +SELECT schemaname, sequencename, start_value, min_value, max_value, increment_by, cycle, cache_size, last_value +FROM pg_sequences +WHERE sequencename IN('sequence_testa', 'sequence_testb', 'sequence_testc', 'sequence_testd') + ORDER BY sequencename ASC; + schemaname | sequencename | start_value | min_value | max_value | increment_by | cycle | cache_size | last_value +------------+----------------+-------------+-------------+------------+--------------+-------+------------+------------ + public | sequence_testa | 1 | 1 | 2147483647 | 1 | f | 1 | + public | sequence_testb | -1 | -2147483648 | -1 | -1 | f | 1 | + public | sequence_testc | -32768 | -2147483648 | 2147483647 | 1 | f | 1 | + public | sequence_testd | 32767 | -2147483648 | 2147483647 | -1 | f | 1 | +(4 rows) + +ALTER SEQUENCE sequence_testa AS int; -- shrink a single bound +ALTER SEQUENCE sequence_testb AS int; -- shrink both bounds +ALTER SEQUENCE sequence_testc AS int; -- shrink both bounds --- --- test creation of SERIAL column --- @@ -468,13 +495,18 @@ SELECT * FROM information_schema.sequences regression | public | sequence_test6 | smallint | 16 | 2 | 0 | 1 | 1 | 32767 | 1 | NO regression | public | sequence_test7 | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO regression | public | sequence_test8 | smallint | 16 | 2 | 0 | 1 | 1 | 20000 | 1 | NO + regression | public | sequence_test9 | smallint | 16 | 2 | 0 | 1 | -20000 | 32767 | 1 | NO + regression | public | sequence_testa | integer | 32 | 2 | 0 | 1 | 1 | 2147483647 | 1 | NO + regression | public | sequence_testb | integer | 32 | 2 | 0 | -1 | -2147483648 | -1 | -1 | NO + regression | public | sequence_testc | integer | 32 | 2 | 0 | -32768 | -2147483648 | 2147483647 | 1 | NO + regression | public | sequence_testd | integer | 32 | 2 | 0 | 32767 | -2147483648 | 2147483647 | -1 | NO regression | public | serialtest1_f2_foo | integer | 32 | 2 | 0 | 1 | 1 | 2147483647 | 1 | NO regression | public | serialtest2_f2_seq | integer | 32 | 2 | 0 | 1 | 1 | 2147483647 | 1 | NO regression | public | serialtest2_f3_seq | smallint | 16 | 2 | 0 | 1 | 1 | 32767 | 1 | NO regression | public | serialtest2_f4_seq | smallint | 16 | 2 | 0 | 1 | 1 | 32767 | 1 | NO regression | public | serialtest2_f5_seq | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO regression | public | serialtest2_f6_seq | bigint | 64 | 2 | 0 | 1 | 1 | 9223372036854775807 | 1 | NO -(13 rows) +(18 rows) SELECT schemaname, sequencename, start_value, min_value, max_value, increment_by, cycle, cache_size, last_value FROM pg_sequences @@ -489,13 +521,18 @@ WHERE sequencename ~ ANY(ARRAY['sequence_test', 'serialtest']) public | sequence_test6 | 1 | 1 | 32767 | 1 | f | 1 | public | sequence_test7 | 1 | 1 | 9223372036854775807 | 1 | f | 1 | public | sequence_test8 | 1 | 1 | 20000 | 1 | f | 1 | + public | sequence_test9 | 1 | -20000 | 32767 | 1 | f | 1 | + public | sequence_testa | 1 | 1 | 2147483647 | 1 | f | 1 | + public | sequence_testb | -1 | -2147483648 | -1 | -1 | f | 1 | + public | sequence_testc | -32768 | -2147483648 | 2147483647 | 1 | f | 1 | + public | sequence_testd | 32767 | -2147483648 | 2147483647 | -1 | f | 1 | public | serialtest1_f2_foo | 1 | 1 | 2147483647 | 1 | f | 1 | 3 public | serialtest2_f2_seq | 1 | 1 | 2147483647 | 1 | f | 1 | 2 public | serialtest2_f3_seq | 1 | 1 | 32767 | 1 | f | 1 | 2 public | serialtest2_f4_seq | 1 | 1 | 32767 | 1 | f | 1 | 2 public | serialtest2_f5_seq | 1 | 1 | 9223372036854775807 | 1 | f | 1 | 2 public | serialtest2_f6_seq | 1 | 1 | 9223372036854775807 | 1 | f | 1 | 2 -(13 rows) +(18 rows) SELECT * FROM pg_sequence_parameters('sequence_test4'::regclass); start_value | minimum_value | maximum_value | increment | cycle_option | cache_size | data_type diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql index 8f8d54b..1d04f65 100644 --- a/src/test/regress/sql/sequence.sql +++ b/src/test/regress/sql/sequence.sql @@ -24,6 +24,11 @@ CREATE SEQUENCE sequence_test5 AS integer; CREATE SEQUENCE sequence_test6 AS smallint; CREATE SEQUENCE sequence_test7 AS bigint; CREATE SEQUENCE sequence_test8 AS integer MAXVALUE 100000; +CREATE SEQUENCE sequence_test9 AS integer MINVALUE -100000 START 1; +CREATE SEQUENCE sequence_testa AS smallint; +CREATE SEQUENCE sequence_testb AS smallint INCREMENT -1; +CREATE SEQUENCE sequence_testc AS smallint MINVALUE -32768; +CREATE SEQUENCE sequence_testd AS smallint MAXVALUE 32767 INCREMENT -1; CREATE SEQUENCE sequence_testx AS text; CREATE SEQUENCE sequence_testx AS nosuchtype; @@ -33,6 +38,22 @@ CREATE SEQUENCE sequence_testx AS smallint MINVALUE -100000; ALTER SEQUENCE sequence_test5 AS smallint; -- success, max will be adjusted ALTER SEQUENCE sequence_test8 AS smallint; -- fail, max has to be adjusted ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000; -- ok now +ALTER SEQUENCE sequence_test9 AS smallint; -- fail, min has to be adjusted +ALTER SEQUENCE sequence_test9 AS smallint MINVALUE -20000; -- ok now + +ALTER SEQUENCE sequence_testa AS int; -- enlarge a single bound +ALTER SEQUENCE sequence_testb AS int; -- enlarge a single bound +ALTER SEQUENCE sequence_testc AS int; -- enlarge both bounds +ALTER SEQUENCE sequence_testd AS int; -- enlarge both bounds + +SELECT schemaname, sequencename, start_value, min_value, max_value, increment_by, cycle, cache_size, last_value +FROM pg_sequences +WHERE sequencename IN('sequence_testa', 'sequence_testb', 'sequence_testc', 'sequence_testd') + ORDER BY sequencename ASC; + +ALTER SEQUENCE sequence_testa AS int; -- shrink a single bound +ALTER SEQUENCE sequence_testb AS int; -- shrink both bounds +ALTER SEQUENCE sequence_testc AS int; -- shrink both bounds --- --- test creation of SERIAL column -- 2.7.3