v4-0003-Support-global-temporary-sequences.patch
text/x-patch
Filename: v4-0003-Support-global-temporary-sequences.patch
Type: text/x-patch
Part: 2
Message:
Re: Global temporary tables
Patch
Format: format-patch
Series: patch v4-0003
Subject: Support global temporary sequences.
| File | + | − |
|---|---|---|
| src/backend/catalog/global_temp.c | 5 | 0 |
| src/backend/commands/sequence.c | 66 | 0 |
| src/backend/parser/parse_utilcmd.c | 2 | 1 |
| src/bin/pg_dump/pg_dump.c | 3 | 1 |
| src/bin/psql/describe.c | 6 | 0 |
| src/include/commands/sequence.h | 1 | 0 |
| src/test/isolation/expected/global-temp.out | 88 | 88 |
| src/test/isolation/specs/global-temp.spec | 1 | 1 |
| src/test/regress/expected/global_temp.out | 77 | 46 |
| src/test/regress/sql/global_temp.sql | 9 | 1 |
From 7f7ae6335041b6dd730cfcad1d26f35f3722cd41 Mon Sep 17 00:00:00 2001
From: Dean Rasheed <dean.a.rasheed@gmail.com>
Date: Tue, 9 Jun 2026 19:00:09 +0100
Subject: [PATCH v4 3/9] Support global temporary sequences.
---
src/backend/catalog/global_temp.c | 5 +
src/backend/commands/sequence.c | 66 ++++++++
src/backend/parser/parse_utilcmd.c | 3 +-
src/bin/pg_dump/pg_dump.c | 4 +-
src/bin/psql/describe.c | 6 +
src/include/commands/sequence.h | 1 +
src/test/isolation/expected/global-temp.out | 176 ++++++++++----------
src/test/isolation/specs/global-temp.spec | 2 +-
src/test/regress/expected/global_temp.out | 123 +++++++++-----
src/test/regress/sql/global_temp.sql | 10 +-
10 files changed, 258 insertions(+), 138 deletions(-)
diff --git a/src/backend/catalog/global_temp.c b/src/backend/catalog/global_temp.c
index 4ddadabfa1b..d4de2f02ffb 100644
--- a/src/backend/catalog/global_temp.c
+++ b/src/backend/catalog/global_temp.c
@@ -62,6 +62,7 @@
#include "access/xlogutils.h"
#include "catalog/global_temp.h"
#include "catalog/storage.h"
+#include "commands/sequence.h"
#include "lib/dshash.h"
#include "miscadmin.h"
#include "storage/ipc.h"
@@ -865,6 +866,10 @@ InitGlobalTempRelation(Relation relation)
if (nblocks > 0)
relation->rd_index->indisvalid = false;
}
+
+ /* If it's a sequence, initialize it */
+ if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
+ InitGlobalTempSequence(relation);
}
/* The remaining initialization works as if we had created it locally */
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 551667650ba..9a7cace6c37 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -321,6 +321,72 @@ ResetSequence(Oid seq_relid)
sequence_close(seq_rel, NoLock);
}
+/*
+ * InitGlobalTempSequence - initialize a global temporary sequence
+ *
+ * This is called the first time a global temporary sequence is accessed from
+ * a backend other than the backend that created it. On entry, the sequence
+ * should have valid catalog entries, and its physical disk file should have
+ * been created, but be empty.
+ */
+void
+InitGlobalTempSequence(Relation seq_rel)
+{
+ Oid seq_relid = RelationGetRelid(seq_rel);
+ SeqTable elm;
+ HeapTuple pgstuple;
+ Form_pg_sequence pgsform;
+ int64 startv;
+ int i;
+ Datum value[SEQ_COL_LASTCOL];
+ bool null[SEQ_COL_LASTCOL];
+ TupleDesc tupDesc;
+ HeapTuple tuple;
+
+ /* Find or create a hash table entry for this sequence */
+ if (seqhashtab == NULL)
+ create_seq_hashtable();
+
+ elm = (SeqTable) hash_search(seqhashtab, &seq_relid, HASH_ENTER, NULL);
+
+ /* Initialize the sequence state */
+ elm->filenumber = seq_rel->rd_rel->relfilenode;
+ elm->lxid = InvalidLocalTransactionId;
+ elm->last_valid = false;
+ elm->last = elm->cached = 0;
+
+ /* Read the sequence definition from pg_sequence */
+ pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(seq_relid));
+ if (!HeapTupleIsValid(pgstuple))
+ elog(ERROR, "cache lookup failed for sequence %u", seq_relid);
+ pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
+ startv = pgsform->seqstart;
+ ReleaseSysCache(pgstuple);
+
+ /* Build a new sequence tuple */
+ for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
+ {
+ switch (i)
+ {
+ case SEQ_COL_LASTVAL:
+ value[i - 1] = Int64GetDatumFast(startv);
+ break;
+ case SEQ_COL_LOG:
+ value[i - 1] = Int64GetDatum((int64) 0);
+ break;
+ case SEQ_COL_CALLED:
+ value[i - 1] = BoolGetDatum(false);
+ break;
+ }
+ null[i - 1] = false;
+ }
+ tupDesc = RelationGetDescr(seq_rel);
+ tuple = heap_form_tuple(tupDesc, value, null);
+
+ /* Initialize the sequence's data */
+ fill_seq_with_data(seq_rel, tuple);
+}
+
/*
* Initialize a sequence's relation with the specified tuple as content
*
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index a049cc67ed6..9fb216752dd 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -496,7 +496,8 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
seqpersistence = cxt->rel ? cxt->rel->rd_rel->relpersistence : cxt->relation->relpersistence;
if (loggedEl)
{
- if (seqpersistence == RELPERSISTENCE_TEMP)
+ if (seqpersistence == RELPERSISTENCE_TEMP ||
+ seqpersistence == RELPERSISTENCE_GLOBAL_TEMP)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot set logged status of a temporary sequence"),
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c31e15aff7a..e3fd28e47f2 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -19613,7 +19613,9 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo)
appendPQExpBuffer(query,
"CREATE %sSEQUENCE %s\n",
tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
- "UNLOGGED " : "",
+ "UNLOGGED " :
+ tbinfo->relpersistence == RELPERSISTENCE_GLOBAL_TEMP ?
+ "GLOBAL TEMP " : "",
fmtQualifiedDumpable(tbinfo));
if (seq->seqtype != SEQTYPE_BIGINT)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 34daeba6e36..7483a1ab72b 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1915,6 +1915,12 @@ describeOneTableDetails(const char *schemaname,
if (tableinfo.relpersistence == RELPERSISTENCE_UNLOGGED)
printfPQExpBuffer(&title, _("Unlogged sequence \"%s.%s\""),
schemaname, relationname);
+ else if (tableinfo.relpersistence == RELPERSISTENCE_TEMP)
+ printfPQExpBuffer(&title, _("Temporary sequence \"%s.%s\""),
+ schemaname, relationname);
+ else if (tableinfo.relpersistence == RELPERSISTENCE_GLOBAL_TEMP)
+ printfPQExpBuffer(&title, _("Global temporary sequence \"%s.%s\""),
+ schemaname, relationname);
else
printfPQExpBuffer(&title, _("Sequence \"%s.%s\""),
schemaname, relationname);
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 2c3c4a3f074..6f514ac6dd1 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -47,6 +47,7 @@ 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 InitGlobalTempSequence(Relation seq_rel);
extern void SetSequence(Oid relid, int64 next, bool iscalled);
extern void ResetSequenceCaches(void);
diff --git a/src/test/isolation/expected/global-temp.out b/src/test/isolation/expected/global-temp.out
index 78d944d34f8..748188f5393 100644
--- a/src/test/isolation/expected/global-temp.out
+++ b/src/test/isolation/expected/global-temp.out
@@ -4,15 +4,15 @@ starting permutation: ins1 ins2 sel1 sel2
step ins1: INSERT INTO tmp VALUES (1, 's1');
step ins2: INSERT INTO tmp VALUES (1, 's2');
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
@@ -41,28 +41,28 @@ step ins1: INSERT INTO tmp VALUES (1, 's1');
step b2: BEGIN;
step ins2: INSERT INTO tmp VALUES (1, 's2');
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step c2: COMMIT;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
@@ -71,27 +71,27 @@ step ins1: INSERT INTO tmp VALUES (1, 's1');
step b2: BEGIN;
step ins2: INSERT INTO tmp VALUES (1, 's2');
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step r2: ROLLBACK;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
+key|val|seq
+---+---+---
(0 rows)
@@ -100,28 +100,28 @@ step ins1: INSERT INTO tmp VALUES (1, 's1');
step b2: BEGIN;
step ins2: INSERT INTO tmp VALUES (1, 's2');
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step sp2: SAVEPOINT sp;
step r2: ROLLBACK;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
+key|val|seq
+---+---+---
(0 rows)
@@ -131,39 +131,39 @@ step b2: BEGIN;
step sp2: SAVEPOINT sp;
step ins2: INSERT INTO tmp VALUES (1, 's2');
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step rsp2: ROLLBACK TO SAVEPOINT sp;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
+key|val|seq
+---+---+---
(0 rows)
step r2: ROLLBACK;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
+key|val|seq
+---+---+---
(0 rows)
@@ -175,27 +175,27 @@ step sp2: SAVEPOINT sp;
step t2: TRUNCATE tmp;
step rsp2: ROLLBACK TO SAVEPOINT sp;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step r2: ROLLBACK;
step sel1: SELECT * FROM tmp;
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2: SELECT * FROM tmp;
-key|val
----+---
+key|val|seq
+---+---+---
(0 rows)
@@ -257,9 +257,9 @@ Index Scan using tmp_val_idx on tmp
Index Cond: (val = 's1'::text)
(2 rows)
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step ins2: INSERT INTO tmp VALUES (1, 's2');
@@ -276,9 +276,9 @@ Index Scan using tmp_val_idx on tmp
Index Cond: (val = 's2'::text)
(2 rows)
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
@@ -299,9 +299,9 @@ Index Scan using tmp_val_idx on tmp
Index Cond: (val = 's1'::text)
(2 rows)
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2_idx:
@@ -318,9 +318,9 @@ Seq Scan on tmp
Filter: (val = 's2'::text)
(3 rows)
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
@@ -341,9 +341,9 @@ Index Scan using tmp_val_idx on tmp
Index Cond: (val = 's1'::text)
(2 rows)
-key|val
----+---
- 1|s1
+key|val|seq
+---+---+---
+ 1|s1 | 1
(1 row)
step sel2_idx:
@@ -360,9 +360,9 @@ Seq Scan on tmp
Filter: (val = 's2'::text)
(3 rows)
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
step reidx2: REINDEX INDEX tmp_val_idx;
@@ -379,8 +379,8 @@ Index Scan using tmp_val_idx on tmp
Index Cond: (val = 's2'::text)
(2 rows)
-key|val
----+---
- 1|s2
+key|val|seq
+---+---+---
+ 1|s2 | 1
(1 row)
diff --git a/src/test/isolation/specs/global-temp.spec b/src/test/isolation/specs/global-temp.spec
index f33170260ce..0099ef86a1a 100644
--- a/src/test/isolation/specs/global-temp.spec
+++ b/src/test/isolation/specs/global-temp.spec
@@ -1,7 +1,7 @@
# Test global temporary relations
setup {
- CREATE GLOBAL TEMP TABLE tmp (key int PRIMARY KEY, val text);
+ CREATE GLOBAL TEMP TABLE tmp (key int PRIMARY KEY, val text, seq serial);
CREATE GLOBAL TEMP TABLE tmp_parted (key int PRIMARY KEY, val text) PARTITION BY LIST (key);
CREATE GLOBAL TEMP TABLE tmp_p1 PARTITION OF tmp_parted FOR VALUES IN (1);
diff --git a/src/test/regress/expected/global_temp.out b/src/test/regress/expected/global_temp.out
index 41f7075f863..6745146de9f 100644
--- a/src/test/regress/expected/global_temp.out
+++ b/src/test/regress/expected/global_temp.out
@@ -13,16 +13,17 @@ CREATE GLOBAL TEMP TABLE pg_temp.tmp1 (a int); -- fail
ERROR: cannot create global temporary relation in temporary schema
LINE 1: CREATE GLOBAL TEMP TABLE pg_temp.tmp1 (a int);
^
-CREATE GLOBAL TEMP TABLE tmp1 (a int PRIMARY KEY, b text);
+CREATE GLOBAL TEMP TABLE tmp1 (a int PRIMARY KEY, b text, c serial);
CREATE SCHEMA global_temp_xxx CREATE GLOBAL TEMP TABLE tmp2 (a int);
CREATE SCHEMA global_temp_yyy;
CREATE GLOBAL TEMP TABLE global_temp_yyy.tmp3 (a int);
\d tmp1
- Global temporary table "global_temp_tests.tmp1"
- Column | Type | Collation | Nullable | Default
---------+---------+-----------+----------+---------
+ Global temporary table "global_temp_tests.tmp1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------------------------------
a | integer | | not null |
b | text | | |
+ c | integer | | not null | nextval('tmp1_c_seq'::regclass)
Indexes:
"tmp1_pkey" PRIMARY KEY, btree (a)
@@ -54,16 +55,16 @@ NOTICE: drop cascades to table global_temp_yyy.tmp3
-- Basic tests
INSERT INTO tmp1 VALUES (1, 'xxx');
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
\c
SET search_path = global_temp_tests;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
-- Test index
@@ -78,9 +79,9 @@ SELECT * FROM tmp1 WHERE a = 1;
(2 rows)
SELECT * FROM tmp1 WHERE a = 1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
RESET enable_seqscan;
@@ -96,9 +97,9 @@ SELECT * FROM tmp1 WHERE b = 'xxx';
(2 rows)
SELECT * FROM tmp1 WHERE b = 'xxx';
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
RESET enable_seqscan;
@@ -128,9 +129,9 @@ ERROR: ON COMMIT DROP cannot be used on global temporary tables
-- Two-phase commit not allowed with global temp tables
BEGIN;
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
PREPARE TRANSACTION 'twophase'; -- fail
@@ -256,83 +257,113 @@ INSERT INTO tmp1 VALUES (1, 'xxx');
BEGIN;
TRUNCATE tmp1;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
ROLLBACK;
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
BEGIN;
SAVEPOINT sp1;
TRUNCATE tmp1;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
RELEASE sp1;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
ROLLBACK;
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
BEGIN;
SAVEPOINT sp1;
TRUNCATE tmp1;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
ROLLBACK TO sp1;
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
COMMIT;
SELECT * FROM tmp1;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 1
(1 row)
TRUNCATE tmp1;
SELECT * FROM tmp1;
- a | b
----+---
+ a | b | c
+---+---+---
(0 rows)
-- Test view creation
INSERT INTO tmp1 VALUES (1, 'xxx');
CREATE VIEW v AS SELECT * FROM tmp1;
SELECT * FROM v;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 2
(1 row)
DROP VIEW v;
CREATE TEMP VIEW v AS SELECT * FROM tmp1;
SELECT * FROM v;
- a | b
----+-----
- 1 | xxx
+ a | b | c
+---+-----+---
+ 1 | xxx | 2
(1 row)
DROP VIEW v;
CREATE GLOBAL TEMP VIEW v AS SELECT * FROM tmp1; -- fail
ERROR: views cannot be global temporary because they do not have storage
+-- Test global temp sequence
+CREATE GLOBAL TEMP SEQUENCE s MINVALUE 100 MAXVALUE 130 INCREMENT 10 START WITH 110 CYCLE;
+\d s
+ Global temporary sequence "global_temp_tests.s"
+ Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
+--------+-------+---------+---------+-----------+---------+-------
+ bigint | 110 | 100 | 130 | 10 | yes | 1
+
+SELECT nextval('s') FROM generate_series(1, 5);
+ nextval
+---------
+ 110
+ 120
+ 130
+ 100
+ 110
+(5 rows)
+
+\c
+SET search_path = global_temp_tests;
+SELECT nextval('s') FROM generate_series(1, 5);
+ nextval
+---------
+ 110
+ 120
+ 130
+ 100
+ 110
+(5 rows)
+
diff --git a/src/test/regress/sql/global_temp.sql b/src/test/regress/sql/global_temp.sql
index f8e04933b81..0a677557a71 100644
--- a/src/test/regress/sql/global_temp.sql
+++ b/src/test/regress/sql/global_temp.sql
@@ -11,7 +11,7 @@ SET ROLE regress_global_temp_user;
-- Test table creation
CREATE GLOBAL TEMP TABLE pg_temp.tmp1 (a int); -- fail
-CREATE GLOBAL TEMP TABLE tmp1 (a int PRIMARY KEY, b text);
+CREATE GLOBAL TEMP TABLE tmp1 (a int PRIMARY KEY, b text, c serial);
CREATE SCHEMA global_temp_xxx CREATE GLOBAL TEMP TABLE tmp2 (a int);
CREATE SCHEMA global_temp_yyy;
CREATE GLOBAL TEMP TABLE global_temp_yyy.tmp3 (a int);
@@ -180,3 +180,11 @@ SELECT * FROM v;
DROP VIEW v;
CREATE GLOBAL TEMP VIEW v AS SELECT * FROM tmp1; -- fail
+
+-- Test global temp sequence
+CREATE GLOBAL TEMP SEQUENCE s MINVALUE 100 MAXVALUE 130 INCREMENT 10 START WITH 110 CYCLE;
+\d s
+SELECT nextval('s') FROM generate_series(1, 5);
+\c
+SET search_path = global_temp_tests;
+SELECT nextval('s') FROM generate_series(1, 5);
--
2.51.0