From 1119b33c18b6dae3c9bdb46bb51029f1987bb0c6 Mon Sep 17 00:00:00 2001 From: Rui Zhao Date: Mon, 7 Sep 2026 00:01:57 +0800 Subject: [PATCH] Emit SET LOGGED for an unlogged table's logged identity sequence emit_identity_sequence_alterations() emitted ALTER SEQUENCE ... SET UNLOGGED whenever the identity sequence was unlogged. That covers a logged table whose sequence was made unlogged, but an identity sequence starts out with its table's persistence, so on an unlogged table the sequence is unlogged by default and the only thing worth emitting is the opposite change: a sequence that was SET LOGGED afterwards. That case produced nothing, and the replayed sequence came back unlogged. Compare the sequence's persistence with the table's instead, and emit SET LOGGED or SET UNLOGGED accordingly. The regression database has this shape in identity_dump_unlogged; add the same shape next to the existing SET UNLOGGED test. --- src/backend/utils/adt/ddlutils.c | 20 ++++++++++++++----- .../regress/expected/pg_get_table_ddl.out | 13 +++++++++++- src/test/regress/sql/pg_get_table_ddl.sql | 4 ++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/backend/utils/adt/ddlutils.c b/src/backend/utils/adt/ddlutils.c index e8c037e552..73def6aea0 100644 --- a/src/backend/utils/adt/ddlutils.c +++ b/src/backend/utils/adt/ddlutils.c @@ -2941,8 +2941,9 @@ emit_typed_column_storage(TableDdlContext *ctx) * ALTER SEQUENCE statement(s) after the CREATE TABLE. * * Currently handles: - * - Non-default persistence (e.g. UNLOGGED): the inline syntax has - * no way to specify sequence persistence. + * - Persistence differing from the table's (ALTER SEQUENCE ... SET + * LOGGED/UNLOGGED after the fact): the inline syntax has no way + * to specify sequence persistence. * - Sequence type differing from the column type (e.g. AS smallint * on an integer column): generateSerialExtraStmts() always * prepends AS to the inline options, so a second AS @@ -2987,15 +2988,24 @@ emit_identity_sequence_alterations(TableDdlContext *ctx) { Form_pg_sequence seq = (Form_pg_sequence) GETSTRUCT(seqTup); - if (seqClass->relpersistence == RELPERSISTENCE_UNLOGGED) + /* + * Persistence: an identity sequence is created with its + * table's persistence, so only a later change needs an + * ALTER SEQUENCE -- in either direction. Comparing against + * the table (not against LOGGED) is what makes an unlogged + * table's sequence that was SET LOGGED come back. + */ + if (seqClass->relpersistence != ctx->rel->rd_rel->relpersistence) { char *seqname = lookup_relname_for_emit(seqid, ctx->schema_qualified, ctx->base_namespace); resetStringInfo(&ctx->buf); - appendStringInfo(&ctx->buf, "ALTER SEQUENCE %s SET UNLOGGED;", - seqname); + appendStringInfo(&ctx->buf, "ALTER SEQUENCE %s SET %s;", + seqname, + seqClass->relpersistence == RELPERSISTENCE_UNLOGGED ? + "UNLOGGED" : "LOGGED"); append_stmt(ctx); pfree(seqname); } diff --git a/src/test/regress/expected/pg_get_table_ddl.out b/src/test/regress/expected/pg_get_table_ddl.out index c7448bc10a..e836c899b9 100644 --- a/src/test/regress/expected/pg_get_table_ddl.out +++ b/src/test/regress/expected/pg_get_table_ddl.out @@ -2055,6 +2055,16 @@ SELECT stmt FROM pg_get_table_ddl('idl', owner => false) stmt; ALTER SEQUENCE pgtbl_ddl_test.idl_a_seq SET UNLOGGED; (2 rows) +-- and the other direction: an unlogged table whose sequence was SET LOGGED. +CREATE UNLOGGED TABLE idu (a int GENERATED ALWAYS AS IDENTITY); +ALTER SEQUENCE idu_a_seq SET LOGGED; +SELECT stmt FROM pg_get_table_ddl('idu', owner => false) stmt; + stmt +--------------------------------------------------------------------------------------------- + CREATE UNLOGGED TABLE pgtbl_ddl_test.idu (a integer GENERATED ALWAYS AS IDENTITY NOT NULL); + ALTER SEQUENCE pgtbl_ddl_test.idu_a_seq SET LOGGED; +(2 rows) + -- Issue 12: ALTER INDEX ... ALTER COLUMN SET STATISTICS on a constraint-backed -- index (PK, UNIQUE, EXCLUSION) must be emitted after the ADD CONSTRAINT. -- EXCLUSION with an expression column is used because only expression columns @@ -2075,7 +2085,7 @@ DROP SERVER dummy_srv CASCADE; NOTICE: drop cascades to foreign table fpar_2 DROP FOREIGN DATA WRAPPER dummy_fdw CASCADE; DROP SCHEMA pgtbl_ddl_test CASCADE; -NOTICE: drop cascades to 60 other objects +NOTICE: drop cascades to 61 other objects DETAIL: drop cascades to table basic drop cascades to table id_cols drop cascades to table id_custom @@ -2135,4 +2145,5 @@ drop cascades to table fpar drop cascades to table cc drop cascades to table tsp drop cascades to table idl +drop cascades to table idu drop cascades to table exs diff --git a/src/test/regress/sql/pg_get_table_ddl.sql b/src/test/regress/sql/pg_get_table_ddl.sql index bebb3069a6..64f8fd7704 100644 --- a/src/test/regress/sql/pg_get_table_ddl.sql +++ b/src/test/regress/sql/pg_get_table_ddl.sql @@ -1210,6 +1210,10 @@ SELECT stmt FROM pg_get_table_ddl('tsp', owner => false, tablespace => false) st CREATE TABLE idl (a int GENERATED ALWAYS AS IDENTITY); ALTER SEQUENCE idl_a_seq SET UNLOGGED; SELECT stmt FROM pg_get_table_ddl('idl', owner => false) stmt; +-- and the other direction: an unlogged table whose sequence was SET LOGGED. +CREATE UNLOGGED TABLE idu (a int GENERATED ALWAYS AS IDENTITY); +ALTER SEQUENCE idu_a_seq SET LOGGED; +SELECT stmt FROM pg_get_table_ddl('idu', owner => false) stmt; -- Issue 12: ALTER INDEX ... ALTER COLUMN SET STATISTICS on a constraint-backed -- index (PK, UNIQUE, EXCLUSION) must be emitted after the ADD CONSTRAINT. -- 2.43.7