Skip to content

Commit caede71

Browse files
committed
Allow ALTER SEQUENCE START WITH to change the recorded start_value of a
sequence. This seems an obvious extension to the recent patch, and it makes the code noticeably cleaner and more orthogonal.
1 parent 3951fae commit caede71

File tree

2 files changed

+59
-50
lines changed

2 files changed

+59
-50
lines changed

doc/src/sgml/ref/alter_sequence.sgml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.20 2008/05/16 23:36:04 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.21 2008/05/17 01:20:39 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -26,7 +26,9 @@ PostgreSQL documentation
2626
<synopsis>
2727
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
2828
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
29-
[ RESTART [ [ WITH ] <replaceable class="parameter">start</replaceable> ] ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
29+
[ START [ WITH ] <replaceable class="parameter">start</replaceable> ]
30+
[ RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] ]
31+
[ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
3032
[ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
3133
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
3234
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
@@ -110,17 +112,31 @@ ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <rep
110112

111113
<varlistentry>
112114
<term><replaceable class="parameter">start</replaceable></term>
115+
<listitem>
116+
<para>
117+
The optional clause <literal>START WITH <replaceable
118+
class="parameter">start</replaceable></literal> changes the
119+
recorded start value of the sequence. This has no effect on the
120+
<emphasis>current</> sequence value; it simply sets the value
121+
that future <command>ALTER SEQUENCE RESTART</> commands will use.
122+
</para>
123+
</listitem>
124+
</varlistentry>
125+
126+
<varlistentry>
127+
<term><replaceable class="parameter">restart</replaceable></term>
113128
<listitem>
114129
<para>
115130
The optional clause <literal>RESTART [ WITH <replaceable
116-
class="parameter">start</replaceable> ]</literal> changes the
131+
class="parameter">restart</replaceable> ]</literal> changes the
117132
current value of the sequence. This is equivalent to calling the
118133
<function>setval</> function with <literal>is_called</literal> =
119134
<literal>false</>: the specified value will be returned by the
120135
<emphasis>next</> call of <function>nextval</>.
121136
Writing <literal>RESTART</> with no <replaceable
122-
class="parameter">start</replaceable> value is equivalent to supplying
123-
the start value used when the sequence was created.
137+
class="parameter">restart</> value is equivalent to supplying
138+
the start value that was recorded by <command>CREATE SEQUENCE</>
139+
or last set by <command>ALTER SEQUENCE START WITH</>.
124140
</para>
125141
</listitem>
126142
</varlistentry>
@@ -261,7 +277,8 @@ ALTER SEQUENCE serial RESTART WITH 105;
261277

262278
<para>
263279
<command>ALTER SEQUENCE</command> conforms to the <acronym>SQL</acronym>
264-
standard, except for the <literal>OWNED BY</>, <literal>RENAME</>, and
280+
standard, except for the <literal>START WITH</>,
281+
<literal>OWNED BY</>, <literal>RENAME</>, and
265282
<literal>SET SCHEMA</literal> clauses, which are
266283
<productname>PostgreSQL</productname> extensions.
267284
</para>

src/backend/commands/sequence.c

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.151 2008/05/16 23:36:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.152 2008/05/17 01:20:39 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -91,7 +91,7 @@ static Relation open_share_lock(SeqTable seq);
9191
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
9292
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
9393
static void init_params(List *options, bool isInit,
94-
Form_pg_sequence new, Form_pg_sequence old, List **owned_by);
94+
Form_pg_sequence new, List **owned_by);
9595
static void do_setval(Oid relid, int64 next, bool iscalled);
9696
static void process_owned_by(Relation seqrel, List *owned_by);
9797

@@ -119,7 +119,7 @@ DefineSequence(CreateSeqStmt *seq)
119119
NameData name;
120120

121121
/* Check and set all option values */
122-
init_params(seq->options, true, &new, NULL, &owned_by);
122+
init_params(seq->options, true, &new, &owned_by);
123123

124124
/*
125125
* Create relation (and fill value[] and null[] for the tuple)
@@ -357,8 +357,11 @@ AlterSequenceInternal(Oid relid, List *options)
357357
seq = read_info(elm, seqrel, &buf);
358358
page = BufferGetPage(buf);
359359

360-
/* Fill workspace with appropriate new info */
361-
init_params(options, false, &new, seq, &owned_by);
360+
/* Copy old values of options into workspace */
361+
memcpy(&new, seq, sizeof(FormData_pg_sequence));
362+
363+
/* Check and set new values */
364+
init_params(options, false, &new, &owned_by);
362365

363366
/* Clear local cache so that we don't think we have cached numbers */
364367
/* Note that we do not change the currval() state */
@@ -989,9 +992,10 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
989992
*/
990993
static void
991994
init_params(List *options, bool isInit,
992-
Form_pg_sequence new, Form_pg_sequence old, List **owned_by)
995+
Form_pg_sequence new, List **owned_by)
993996
{
994-
DefElem *last_value = NULL;
997+
DefElem *start_value = NULL;
998+
DefElem *restart_value = NULL;
995999
DefElem *increment_by = NULL;
9961000
DefElem *max_value = NULL;
9971001
DefElem *min_value = NULL;
@@ -1001,12 +1005,6 @@ init_params(List *options, bool isInit,
10011005

10021006
*owned_by = NIL;
10031007

1004-
/* Copy old values of options into workspace */
1005-
if (old != NULL)
1006-
memcpy(new, old, sizeof(FormData_pg_sequence));
1007-
else
1008-
memset(new, 0, sizeof(FormData_pg_sequence));
1009-
10101008
foreach(option, options)
10111009
{
10121010
DefElem *defel = (DefElem *) lfirst(option);
@@ -1021,27 +1019,19 @@ init_params(List *options, bool isInit,
10211019
}
10221020
else if (strcmp(defel->defname, "start") == 0)
10231021
{
1024-
if (!isInit)
1025-
ereport(ERROR,
1026-
(errcode(ERRCODE_SYNTAX_ERROR),
1027-
errmsg("use RESTART not START in ALTER SEQUENCE")));
1028-
if (last_value)
1022+
if (start_value)
10291023
ereport(ERROR,
10301024
(errcode(ERRCODE_SYNTAX_ERROR),
10311025
errmsg("conflicting or redundant options")));
1032-
last_value = defel;
1026+
start_value = defel;
10331027
}
10341028
else if (strcmp(defel->defname, "restart") == 0)
10351029
{
1036-
if (isInit)
1037-
ereport(ERROR,
1038-
(errcode(ERRCODE_SYNTAX_ERROR),
1039-
errmsg("use START not RESTART in CREATE SEQUENCE")));
1040-
if (last_value)
1030+
if (restart_value)
10411031
ereport(ERROR,
10421032
(errcode(ERRCODE_SYNTAX_ERROR),
10431033
errmsg("conflicting or redundant options")));
1044-
last_value = defel;
1034+
restart_value = defel;
10451035
}
10461036
else if (strcmp(defel->defname, "maxvalue") == 0)
10471037
{
@@ -1145,30 +1135,15 @@ init_params(List *options, bool isInit,
11451135
bufm, bufx)));
11461136
}
11471137

1148-
/* START/RESTART [WITH] */
1149-
if (last_value != NULL)
1150-
{
1151-
if (last_value->arg != NULL)
1152-
new->last_value = defGetInt64(last_value);
1153-
else
1154-
{
1155-
Assert(old != NULL);
1156-
new->last_value = old->start_value;
1157-
}
1158-
if (isInit)
1159-
new->start_value = new->last_value;
1160-
new->is_called = false;
1161-
new->log_cnt = 1;
1162-
}
1138+
/* START WITH */
1139+
if (start_value != NULL)
1140+
new->start_value = defGetInt64(start_value);
11631141
else if (isInit)
11641142
{
11651143
if (new->increment_by > 0)
11661144
new->start_value = new->min_value; /* ascending seq */
11671145
else
11681146
new->start_value = new->max_value; /* descending seq */
1169-
new->last_value = new->start_value;
1170-
new->is_called = false;
1171-
new->log_cnt = 1;
11721147
}
11731148

11741149
/* crosscheck START */
@@ -1197,7 +1172,24 @@ init_params(List *options, bool isInit,
11971172
bufs, bufm)));
11981173
}
11991174

1200-
/* must crosscheck RESTART separately */
1175+
/* RESTART [WITH] */
1176+
if (restart_value != NULL)
1177+
{
1178+
if (restart_value->arg != NULL)
1179+
new->last_value = defGetInt64(restart_value);
1180+
else
1181+
new->last_value = new->start_value;
1182+
new->is_called = false;
1183+
new->log_cnt = 1;
1184+
}
1185+
else if (isInit)
1186+
{
1187+
new->last_value = new->start_value;
1188+
new->is_called = false;
1189+
new->log_cnt = 1;
1190+
}
1191+
1192+
/* crosscheck RESTART (or current value, if changing MIN/MAX) */
12011193
if (new->last_value < new->min_value)
12021194
{
12031195
char bufs[100],

0 commit comments

Comments
 (0)