From 24fb190a9cf56fff1c1296b02d179ef33d049794 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 29 Mar 2022 12:53:53 +0200 Subject: [PATCH v5] Unlogged sequences Add support for unlogged sequences. Unlike for unlogged tables, this is not a performance feature. It allows sequences associated with unlogged tables to be excluded from replication. A new subcommand ALTER SEQUENCE ... SET LOGGED/UNLOGGED is added. An identity/serial sequence now automatically gets and follows the persistence level (logged/unlogged) of its owning table. (The sequences owned by temporary tables were already temporary through the separate mechanism in RangeVarAdjustRelationPersistence().) Discussion: https://www.postgresql.org/message-id/flat/04e12818-2f98-257c-b926-2845d74ed04f%402ndquadrant.com --- doc/src/sgml/ref/alter_sequence.sgml | 12 +++++ doc/src/sgml/ref/create_sequence.sgml | 23 +++++++- doc/src/sgml/ref/pg_dump.sgml | 7 +-- src/backend/commands/sequence.c | 58 +++++++++++++++++--- src/backend/commands/tablecmds.c | 32 ++++++++++-- src/backend/parser/parse_utilcmd.c | 1 + src/bin/pg_dump/pg_dump.c | 4 +- src/bin/psql/describe.c | 8 ++- src/bin/psql/tab-complete.c | 5 +- src/include/commands/sequence.h | 1 + src/test/recovery/t/014_unlogged_reinit.pl | 61 +++++++++++++++++++--- src/test/regress/expected/alter_table.out | 4 +- src/test/regress/expected/sequence.out | 20 ++++++- src/test/regress/sql/sequence.sql | 10 +++- 14 files changed, 216 insertions(+), 30 deletions(-) diff --git a/doc/src/sgml/ref/alter_sequence.sgml b/doc/src/sgml/ref/alter_sequence.sgml index 3cd9ece49f..148085d4f2 100644 --- a/doc/src/sgml/ref/alter_sequence.sgml +++ b/doc/src/sgml/ref/alter_sequence.sgml @@ -31,6 +31,7 @@ [ RESTART [ [ WITH ] restart ] ] [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table_name.column_name | NONE } ] +ALTER SEQUENCE [ IF EXISTS ] name SET { LOGGED | UNLOGGED } ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema @@ -237,6 +238,17 @@ Parameters + + SET { LOGGED | UNLOGGED } + + + This form changes the sequence from unlogged to logged or vice-versa + (see ). It cannot be applied to a + temporary sequence. + + + + OWNED BY table_name.column_name OWNED BY NONE diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml index 20bdbc002f..a84aa5bf56 100644 --- a/doc/src/sgml/ref/create_sequence.sgml +++ b/doc/src/sgml/ref/create_sequence.sgml @@ -21,7 +21,7 @@ -CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] name +CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name [ AS data_type ] [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] @@ -92,6 +92,27 @@ Parameters + + UNLOGGED + + + If specified, the sequence is created as an unlogged sequence. Changes + to unlogged sequences are not written to the write-ahead log. They are + not crash-safe: an unlogged sequence is automatically reset to its + initial state after a crash or unclean shutdown. Unlogged sequences are + also not replicated to standby servers. + + + + Unlike unlogged tables, unlogged sequences do not offer a significant + performance advantage. This option is mainly intended for sequences + associated with unlogged tables via identity columns or serial columns. + In those cases, it usually wouldn't make sense to have the sequence + WAL-logged and replicated but not its associated table. + + + + IF NOT EXISTS diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 2f0042fd96..723b2a1a66 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -981,9 +981,10 @@ Options - Do not dump the contents of unlogged tables. This option has no - effect on whether or not the table definitions (schema) are dumped; - it only suppresses dumping the table data. Data in unlogged tables + Do not dump the contents of unlogged tables and sequences. This + option has no effect on whether or not the table and sequence + definitions (schema) are dumped; it only suppresses dumping the table + and sequence data. Data in unlogged tables and sequences is always excluded when dumping from a standby server. diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 717bb0b2aa..47f62c28d4 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -30,6 +30,7 @@ #include "catalog/objectaccess.h" #include "catalog/pg_sequence.h" #include "catalog/pg_type.h" +#include "catalog/storage_xlog.h" #include "commands/defrem.h" #include "commands/sequence.h" #include "commands/tablecmds.h" @@ -95,6 +96,7 @@ static HTAB *seqhashtab = NULL; /* hash table for SeqTable items */ static SeqTableData *last_used_seq = NULL; static void fill_seq_with_data(Relation rel, HeapTuple tuple); +static void fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum); static Relation lock_and_open_sequence(SeqTable seq); static void create_seq_hashtable(void); static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel); @@ -133,12 +135,6 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) bool pgs_nulls[Natts_pg_sequence]; int i; - /* Unlogged sequences are not implemented -- not clear if useful. */ - if (seq->sequence->relpersistence == RELPERSISTENCE_UNLOGGED) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unlogged sequences are not supported"))); - /* * If if_not_exists was given and a relation with the same name already * exists, bail out. (Note: we needn't check this when not if_not_exists, @@ -492,9 +488,33 @@ SetSequence(Oid seq_relid, bool transactional, int64 last_value, int64 log_cnt, /* * Initialize a sequence's relation with the specified tuple as content + * + * This handles unlogged sequences by writing to both the main and the init + * fork as necessary. */ static void fill_seq_with_data(Relation rel, HeapTuple tuple) +{ + fill_seq_fork_with_data(rel, tuple, MAIN_FORKNUM); + + if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED) + { + SMgrRelation srel; + + srel = smgropen(rel->rd_node, InvalidBackendId); + smgrcreate(srel, INIT_FORKNUM, false); + log_smgrcreate(&rel->rd_node, INIT_FORKNUM); + fill_seq_fork_with_data(rel, tuple, INIT_FORKNUM); + FlushRelationBuffers(rel); + smgrclose(srel); + } +} + +/* + * Initialize a sequence's relation fork with the specified tuple as content + */ +static void +fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum) { Buffer buf; Page page; @@ -503,7 +523,7 @@ fill_seq_with_data(Relation rel, HeapTuple tuple) /* Initialize first page of relation with special magic number */ - buf = ReadBuffer(rel, P_NEW); + buf = ReadBufferExtended(rel, forkNum, P_NEW, RBM_NORMAL, NULL); Assert(BufferGetBlockNumber(buf) == 0); page = BufferGetPage(buf); @@ -549,7 +569,7 @@ fill_seq_with_data(Relation rel, HeapTuple tuple) elog(ERROR, "failed to add sequence tuple to page"); /* XLOG stuff */ - if (RelationNeedsWAL(rel)) + if (RelationNeedsWAL(rel) || forkNum == INIT_FORKNUM) { xl_seq_rec xlrec; XLogRecPtr recptr; @@ -682,6 +702,28 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt) return address; } +void +SequenceChangePersistence(Oid relid, char newrelpersistence) +{ + SeqTable elm; + Relation seqrel; + Buffer buf; + HeapTupleData seqdatatuple; + + init_sequence(relid, &elm, &seqrel); + + /* check the comment above nextval_internal()'s equivalent call. */ + if (RelationNeedsWAL(seqrel)) + GetTopTransactionId(); + + (void) read_seq_tuple(seqrel, &buf, &seqdatatuple); + RelationSetNewRelfilenode(seqrel, newrelpersistence); + fill_seq_with_data(seqrel, &seqdatatuple); + UnlockReleaseBuffer(buf); + + relation_close(seqrel, NoLock); +} + void DeleteSequenceTuple(Oid relid) { diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 124b9961dc..44db7df32c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -319,6 +319,7 @@ struct DropRelationCallbackState #define ATT_COMPOSITE_TYPE 0x0010 #define ATT_FOREIGN_TABLE 0x0020 #define ATT_PARTITIONED_INDEX 0x0040 +#define ATT_SEQUENCE 0x0080 /* * ForeignTruncateInfo @@ -4660,7 +4661,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, pass = AT_PASS_MISC; break; case AT_SetLogged: /* SET LOGGED */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_SEQUENCE); if (tab->chgPersistence) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -4675,7 +4676,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, pass = AT_PASS_MISC; break; case AT_SetUnLogged: /* SET UNLOGGED */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_SEQUENCE); if (tab->chgPersistence) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -5425,7 +5426,7 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode, * and assigns a new relfilenode, we automatically create or drop an * init fork for the relation as appropriate. */ - if (tab->rewrite > 0) + if (tab->rewrite > 0 && tab->relkind != RELKIND_SEQUENCE) { /* Build a temporary relation and copy data */ Relation OldHeap; @@ -5546,6 +5547,11 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode, InvokeObjectPostAlterHook(RelationRelationId, tab->relid, 0); } + else if (tab->rewrite > 0 && tab->relkind == RELKIND_SEQUENCE) + { + if (tab->chgPersistence) + SequenceChangePersistence(tab->relid, tab->newrelpersistence); + } else { /* @@ -5564,6 +5570,23 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode, if (tab->newTableSpace) ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode); } + + /* + * Also change persistence of owned sequences. + */ + if (tab->chgPersistence) + { + List *seqlist = getOwnedSequences(tab->relid); + ListCell *lc; + + foreach(lc, seqlist) + { + Oid seq_relid = lfirst_oid(lc); + + SequenceChangePersistence(seq_relid, tab->newrelpersistence); + } + } + } /* @@ -6224,6 +6247,9 @@ ATSimplePermissions(AlterTableType cmdtype, Relation rel, int allowed_targets) case RELKIND_FOREIGN_TABLE: actual_target = ATT_FOREIGN_TABLE; break; + case RELKIND_SEQUENCE: + actual_target = ATT_SEQUENCE; + break; default: actual_target = 0; break; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index cd946c7692..2826559d09 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -445,6 +445,7 @@ 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; seqstmt->options = seqoptions; /* diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 535b160165..d8e6cb2b2e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -16696,7 +16696,9 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) else { appendPQExpBuffer(query, - "CREATE SEQUENCE %s\n", + "CREATE %sSEQUENCE %s\n", + tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ? + "UNLOGGED " : "", fmtQualifiedDumpable(tbinfo)); if (strcmp(seqtype, "bigint") != 0) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 4dddf08789..73bbbe2eb4 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -1681,8 +1681,12 @@ describeOneTableDetails(const char *schemaname, printTableInit(&cont, &myopt, title.data, 7, numrows); printTableInitialized = true; - printfPQExpBuffer(&title, _("Sequence \"%s.%s\""), - schemaname, relationname); + if (tableinfo.relpersistence == 'u') + printfPQExpBuffer(&title, _("Unlogged sequence \"%s.%s\""), + schemaname, relationname); + else + printfPQExpBuffer(&title, _("Sequence \"%s.%s\""), + schemaname, relationname); printTableAddHeader(&cont, gettext_noop("Type"), true, 'l'); printTableAddHeader(&cont, gettext_noop("Start"), true, 'r'); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index c97d3e87f0..fce23c7b3d 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -2115,7 +2115,7 @@ psql_completion(const char *text, int start, int end) /* ALTER SEQUENCE */ else if (Matches("ALTER", "SEQUENCE", MatchAny)) COMPLETE_WITH("AS", "INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", - "NO", "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", + "NO", "CACHE", "CYCLE", "SET", "OWNED BY", "OWNER TO", "RENAME TO"); /* ALTER SEQUENCE AS */ else if (TailMatches("ALTER", "SEQUENCE", MatchAny, "AS")) @@ -2123,6 +2123,9 @@ psql_completion(const char *text, int start, int end) /* ALTER SEQUENCE NO */ else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO")) COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE"); + /* ALTER SEQUENCE SET */ + else if (Matches("ALTER", "SEQUENCE", MatchAny, "SET")) + COMPLETE_WITH("SCHEMA", "LOGGED", "UNLOGGED"); /* ALTER SERVER */ else if (Matches("ALTER", "SERVER", MatchAny)) COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO"); diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index 5bab90db8e..f2381982d5 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -58,6 +58,7 @@ extern List *sequence_options(Oid relid); extern ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *stmt); extern ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt); +extern void SequenceChangePersistence(Oid relid, char newrelpersistence); extern void DeleteSequenceTuple(Oid relid); extern void ResetSequence(Oid seq_relid); extern void SetSequence(Oid seq_relid, bool transactional, int64 last_value, int64 log_cnt, bool is_called); diff --git a/src/test/recovery/t/014_unlogged_reinit.pl b/src/test/recovery/t/014_unlogged_reinit.pl index f3199fbd2e..0dca3f69fe 100644 --- a/src/test/recovery/t/014_unlogged_reinit.pl +++ b/src/test/recovery/t/014_unlogged_reinit.pl @@ -18,16 +18,27 @@ $node->start; my $pgdata = $node->data_dir; -# Create an unlogged table to test that forks other than init are not -# copied. +# Create an unlogged table and an unlogged sequence to test that forks +# other than init are not copied. $node->safe_psql('postgres', 'CREATE UNLOGGED TABLE base_unlogged (id int)'); +$node->safe_psql('postgres', 'CREATE UNLOGGED SEQUENCE seq_unlogged'); my $baseUnloggedPath = $node->safe_psql('postgres', q{select pg_relation_filepath('base_unlogged')}); +my $seqUnloggedPath = $node->safe_psql('postgres', + q{select pg_relation_filepath('seq_unlogged')}); # Test that main and init forks exist. -ok(-f "$pgdata/${baseUnloggedPath}_init", 'init fork in base exists'); -ok(-f "$pgdata/$baseUnloggedPath", 'main fork in base exists'); +ok(-f "$pgdata/${baseUnloggedPath}_init", 'table init fork exists'); +ok(-f "$pgdata/$baseUnloggedPath", 'table main fork exists'); +ok(-f "$pgdata/${seqUnloggedPath}_init", 'sequence init fork exists'); +ok(-f "$pgdata/$seqUnloggedPath", 'sequence main fork exists'); + +# Test the sequence +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged')"), + 1, 'sequence nextval'); +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged')"), + 2, 'sequence nextval again'); # Create an unlogged table in a tablespace. @@ -44,6 +55,19 @@ ok(-f "$pgdata/${ts1UnloggedPath}_init", 'init fork in tablespace exists'); ok(-f "$pgdata/$ts1UnloggedPath", 'main fork in tablespace exists'); +# Create more unlogged sequences for testing. +$node->safe_psql('postgres', 'CREATE UNLOGGED SEQUENCE seq_unlogged2'); +# This rewrites the sequence relation in AlterSequence(). +$node->safe_psql('postgres', 'ALTER SEQUENCE seq_unlogged2 INCREMENT 2'); +$node->safe_psql('postgres', "SELECT nextval('seq_unlogged2')"); + +$node->safe_psql('postgres', + 'CREATE UNLOGGED TABLE tab_seq_unlogged3 (a int GENERATED ALWAYS AS IDENTITY)' +); +# This rewrites the sequence relation in ResetSequence(). +$node->safe_psql('postgres', 'TRUNCATE tab_seq_unlogged3 RESTART IDENTITY'); +$node->safe_psql('postgres', 'INSERT INTO tab_seq_unlogged3 DEFAULT VALUES'); + # Crash the postmaster. $node->stop('immediate'); @@ -54,6 +78,8 @@ # Remove main fork to test that it is recopied from init. unlink("$pgdata/${baseUnloggedPath}") or BAIL_OUT("could not remove \"${baseUnloggedPath}\": $!"); +unlink("$pgdata/${seqUnloggedPath}") + or BAIL_OUT("could not remove \"${seqUnloggedPath}\": $!"); # the same for the tablespace append_to_file("$pgdata/${ts1UnloggedPath}_vm", 'TEST_VM'); @@ -64,13 +90,25 @@ $node->start; # check unlogged table in base -ok(-f "$pgdata/${baseUnloggedPath}_init", 'init fork in base still exists'); -ok(-f "$pgdata/$baseUnloggedPath", 'main fork in base recreated at startup'); +ok( -f "$pgdata/${baseUnloggedPath}_init", + 'table init fork in base still exists'); +ok(-f "$pgdata/$baseUnloggedPath", + 'table main fork in base recreated at startup'); ok(!-f "$pgdata/${baseUnloggedPath}_vm", 'vm fork in base removed at startup'); ok( !-f "$pgdata/${baseUnloggedPath}_fsm", 'fsm fork in base removed at startup'); +# check unlogged sequence +ok(-f "$pgdata/${seqUnloggedPath}_init", 'sequence init fork still exists'); +ok(-f "$pgdata/$seqUnloggedPath", 'sequence main fork recreated at startup'); + +# Test the sequence after restart +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged')"), + 1, 'sequence nextval after restart'); +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged')"), + 2, 'sequence nextval after restart again'); + # check unlogged table in tablespace ok( -f "$pgdata/${ts1UnloggedPath}_init", 'init fork still exists in tablespace'); @@ -81,4 +119,15 @@ ok( !-f "$pgdata/${ts1UnloggedPath}_fsm", 'fsm fork in tablespace removed at startup'); +# Test other sequences +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged2')"), + 1, 'altered sequence nextval after restart'); +is($node->safe_psql('postgres', "SELECT nextval('seq_unlogged2')"), + 3, 'altered sequence nextval after restart again'); + +$node->safe_psql('postgres', + "INSERT INTO tab_seq_unlogged3 VALUES (DEFAULT), (DEFAULT)"); +is($node->safe_psql('postgres', "SELECT * FROM tab_seq_unlogged3"), + "1\n2", 'reset sequence nextval after restart'); + done_testing(); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 07473dd660..5ede56d9b5 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -3461,7 +3461,7 @@ ORDER BY relname; unlogged1 | r | u unlogged1 toast index | i | u unlogged1 toast table | t | u - unlogged1_f1_seq | S | p + unlogged1_f1_seq | S | u unlogged1_pkey | i | u (5 rows) @@ -3528,7 +3528,7 @@ ORDER BY relname; logged1 | r | u logged1 toast index | i | u logged1 toast table | t | u - logged1_f1_seq | S | p + logged1_f1_seq | S | u logged1_pkey | i | u (5 rows) diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out index 71c2b0f1df..7cb2f7cc02 100644 --- a/src/test/regress/expected/sequence.out +++ b/src/test/regress/expected/sequence.out @@ -2,8 +2,6 @@ -- CREATE SEQUENCE -- -- various error cases -CREATE UNLOGGED SEQUENCE sequence_testx; -ERROR: unlogged sequences are not supported CREATE SEQUENCE sequence_testx INCREMENT BY 0; ERROR: INCREMENT must not be zero CREATE SEQUENCE sequence_testx INCREMENT BY -1 MINVALUE 20; @@ -600,6 +598,24 @@ DROP SEQUENCE seq2; -- should fail SELECT lastval(); ERROR: lastval is not yet defined in this session +-- unlogged sequences +-- (more tests in src/test/recovery/) +CREATE UNLOGGED SEQUENCE sequence_test_unlogged; +ALTER SEQUENCE sequence_test_unlogged SET LOGGED; +\d sequence_test_unlogged + Sequence "public.sequence_test_unlogged" + Type | Start | Minimum | Maximum | Increment | Cycles? | Cache +--------+-------+---------+---------------------+-----------+---------+------- + bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 + +ALTER SEQUENCE sequence_test_unlogged SET UNLOGGED; +\d sequence_test_unlogged + Unlogged sequence "public.sequence_test_unlogged" + Type | Start | Minimum | Maximum | Increment | Cycles? | Cache +--------+-------+---------+---------------------+-----------+---------+------- + bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1 + +DROP SEQUENCE sequence_test_unlogged; -- Test sequences in read-only transactions CREATE TEMPORARY SEQUENCE sequence_test_temp1; START TRANSACTION READ ONLY; diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql index 7928ee23ee..674f5f1f66 100644 --- a/src/test/regress/sql/sequence.sql +++ b/src/test/regress/sql/sequence.sql @@ -3,7 +3,6 @@ -- -- various error cases -CREATE UNLOGGED SEQUENCE sequence_testx; CREATE SEQUENCE sequence_testx INCREMENT BY 0; CREATE SEQUENCE sequence_testx INCREMENT BY -1 MINVALUE 20; CREATE SEQUENCE sequence_testx INCREMENT BY 1 MAXVALUE -20; @@ -272,6 +271,15 @@ CREATE SEQUENCE seq2; -- should fail SELECT lastval(); +-- unlogged sequences +-- (more tests in src/test/recovery/) +CREATE UNLOGGED SEQUENCE sequence_test_unlogged; +ALTER SEQUENCE sequence_test_unlogged SET LOGGED; +\d sequence_test_unlogged +ALTER SEQUENCE sequence_test_unlogged SET UNLOGGED; +\d sequence_test_unlogged +DROP SEQUENCE sequence_test_unlogged; + -- Test sequences in read-only transactions CREATE TEMPORARY SEQUENCE sequence_test_temp1; START TRANSACTION READ ONLY; base-commit: 8cd7627c7b19c5a1bb235e7ad91b53856b101e65 -- 2.35.1