mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fix propagation of persistence to sequences in ALTER TABLE / ADD COLUMN
Fix for 344d62fb9a: That commit introduced unlogged sequences and
made it so that identity/serial sequences automatically get the
persistence level of their owning table.  But this works only for
CREATE TABLE and not for ALTER TABLE / ADD COLUMN.  The latter would
always create the sequence as logged (default), independent of the
persistence setting of the table.  This is fixed here.
Note: It is allowed to change the persistence of identity sequences
directly using ALTER SEQUENCE.  So mistakes in existing databases can
be fixed manually.
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/c4b6e2ed-bcdf-4ea7-965f-e49761094827%40eisentraut.org
			
			
This commit is contained in:
		@@ -456,7 +456,16 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
 | 
			
		||||
	seqstmt = makeNode(CreateSeqStmt);
 | 
			
		||||
	seqstmt->for_identity = for_identity;
 | 
			
		||||
	seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
 | 
			
		||||
	seqstmt->sequence->relpersistence = cxt->relation->relpersistence;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy the persistence of the table.  For CREATE TABLE, we get the
 | 
			
		||||
	 * persistence from cxt->relation, which comes from the CreateStmt in
 | 
			
		||||
	 * progress.  For ALTER TABLE, the parser won't set
 | 
			
		||||
	 * cxt->relation->relpersistence, but we have cxt->rel as the existing
 | 
			
		||||
	 * table, so we copy the persistence from there.
 | 
			
		||||
	 */
 | 
			
		||||
	seqstmt->sequence->relpersistence = cxt->rel ? cxt->rel->rd_rel->relpersistence : cxt->relation->relpersistence;
 | 
			
		||||
 | 
			
		||||
	seqstmt->options = seqoptions;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
 
 | 
			
		||||
@@ -365,6 +365,78 @@ SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regcl
 | 
			
		||||
 | 
			
		||||
ALTER TABLE itest3 ALTER COLUMN a TYPE text;  -- error
 | 
			
		||||
ERROR:  identity column type must be smallint, integer, or bigint
 | 
			
		||||
-- check that unlogged propagates to sequence
 | 
			
		||||
CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text);
 | 
			
		||||
ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
\d itest17
 | 
			
		||||
                    Unlogged table "public.itest17"
 | 
			
		||||
 Column |  Type   | Collation | Nullable |           Default            
 | 
			
		||||
--------+---------+-----------+----------+------------------------------
 | 
			
		||||
 a      | integer |           | not null | generated always as identity
 | 
			
		||||
 b      | text    |           |          | 
 | 
			
		||||
 c      | integer |           | not null | generated always as identity
 | 
			
		||||
 | 
			
		||||
\d itest17_a_seq
 | 
			
		||||
               Unlogged sequence "public.itest17_a_seq"
 | 
			
		||||
  Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache 
 | 
			
		||||
---------+-------+---------+------------+-----------+---------+-------
 | 
			
		||||
 integer |     1 |       1 | 2147483647 |         1 | no      |     1
 | 
			
		||||
Sequence for identity column: public.itest17.a
 | 
			
		||||
 | 
			
		||||
\d itest17_c_seq
 | 
			
		||||
               Unlogged sequence "public.itest17_c_seq"
 | 
			
		||||
  Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache 
 | 
			
		||||
---------+-------+---------+------------+-----------+---------+-------
 | 
			
		||||
 integer |     1 |       1 | 2147483647 |         1 | no      |     1
 | 
			
		||||
Sequence for identity column: public.itest17.c
 | 
			
		||||
 | 
			
		||||
CREATE TABLE itest18 (a int NOT NULL, b text);
 | 
			
		||||
ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
\d itest18
 | 
			
		||||
                    Unlogged table "public.itest18"
 | 
			
		||||
 Column |  Type   | Collation | Nullable |           Default            
 | 
			
		||||
--------+---------+-----------+----------+------------------------------
 | 
			
		||||
 a      | integer |           | not null | generated always as identity
 | 
			
		||||
 b      | text    |           |          | 
 | 
			
		||||
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
               Unlogged sequence "public.itest18_a_seq"
 | 
			
		||||
  Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache 
 | 
			
		||||
---------+-------+---------+------------+-----------+---------+-------
 | 
			
		||||
 integer |     1 |       1 | 2147483647 |         1 | no      |     1
 | 
			
		||||
Sequence for identity column: public.itest18.a
 | 
			
		||||
 | 
			
		||||
ALTER TABLE itest18 SET LOGGED;
 | 
			
		||||
\d itest18
 | 
			
		||||
                         Table "public.itest18"
 | 
			
		||||
 Column |  Type   | Collation | Nullable |           Default            
 | 
			
		||||
--------+---------+-----------+----------+------------------------------
 | 
			
		||||
 a      | integer |           | not null | generated always as identity
 | 
			
		||||
 b      | text    |           |          | 
 | 
			
		||||
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
                   Sequence "public.itest18_a_seq"
 | 
			
		||||
  Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache 
 | 
			
		||||
---------+-------+---------+------------+-----------+---------+-------
 | 
			
		||||
 integer |     1 |       1 | 2147483647 |         1 | no      |     1
 | 
			
		||||
Sequence for identity column: public.itest18.a
 | 
			
		||||
 | 
			
		||||
ALTER TABLE itest18 SET UNLOGGED;
 | 
			
		||||
\d itest18
 | 
			
		||||
                    Unlogged table "public.itest18"
 | 
			
		||||
 Column |  Type   | Collation | Nullable |           Default            
 | 
			
		||||
--------+---------+-----------+----------+------------------------------
 | 
			
		||||
 a      | integer |           | not null | generated always as identity
 | 
			
		||||
 b      | text    |           |          | 
 | 
			
		||||
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
               Unlogged sequence "public.itest18_a_seq"
 | 
			
		||||
  Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache 
 | 
			
		||||
---------+-------+---------+------------+-----------+---------+-------
 | 
			
		||||
 integer |     1 |       1 | 2147483647 |         1 | no      |     1
 | 
			
		||||
Sequence for identity column: public.itest18.a
 | 
			
		||||
 | 
			
		||||
-- kinda silly to change property in the same command, but it should work
 | 
			
		||||
ALTER TABLE itest3
 | 
			
		||||
  ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY,
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,24 @@ SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regcl
 | 
			
		||||
 | 
			
		||||
ALTER TABLE itest3 ALTER COLUMN a TYPE text;  -- error
 | 
			
		||||
 | 
			
		||||
-- check that unlogged propagates to sequence
 | 
			
		||||
CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text);
 | 
			
		||||
ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
\d itest17
 | 
			
		||||
\d itest17_a_seq
 | 
			
		||||
\d itest17_c_seq
 | 
			
		||||
CREATE TABLE itest18 (a int NOT NULL, b text);
 | 
			
		||||
ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;
 | 
			
		||||
\d itest18
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
ALTER TABLE itest18 SET LOGGED;
 | 
			
		||||
\d itest18
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
ALTER TABLE itest18 SET UNLOGGED;
 | 
			
		||||
\d itest18
 | 
			
		||||
\d itest18_a_seq
 | 
			
		||||
 | 
			
		||||
-- kinda silly to change property in the same command, but it should work
 | 
			
		||||
ALTER TABLE itest3
 | 
			
		||||
  ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user