mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
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.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.20 2008/05/16 23:36:04 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.21 2008/05/17 01:20:39 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -26,7 +26,9 @@ PostgreSQL documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
|
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
|
||||||
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
|
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
|
||||||
[ RESTART [ [ WITH ] <replaceable class="parameter">start</replaceable> ] ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
|
[ START [ WITH ] <replaceable class="parameter">start</replaceable> ]
|
||||||
|
[ RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] ]
|
||||||
|
[ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
|
||||||
[ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
|
[ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
|
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
|
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
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">start</replaceable></term>
|
<term><replaceable class="parameter">start</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The optional clause <literal>START WITH <replaceable
|
||||||
|
class="parameter">start</replaceable></literal> changes the
|
||||||
|
recorded start value of the sequence. This has no effect on the
|
||||||
|
<emphasis>current</> sequence value; it simply sets the value
|
||||||
|
that future <command>ALTER SEQUENCE RESTART</> commands will use.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">restart</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The optional clause <literal>RESTART [ WITH <replaceable
|
The optional clause <literal>RESTART [ WITH <replaceable
|
||||||
class="parameter">start</replaceable> ]</literal> changes the
|
class="parameter">restart</replaceable> ]</literal> changes the
|
||||||
current value of the sequence. This is equivalent to calling the
|
current value of the sequence. This is equivalent to calling the
|
||||||
<function>setval</> function with <literal>is_called</literal> =
|
<function>setval</> function with <literal>is_called</literal> =
|
||||||
<literal>false</>: the specified value will be returned by the
|
<literal>false</>: the specified value will be returned by the
|
||||||
<emphasis>next</> call of <function>nextval</>.
|
<emphasis>next</> call of <function>nextval</>.
|
||||||
Writing <literal>RESTART</> with no <replaceable
|
Writing <literal>RESTART</> with no <replaceable
|
||||||
class="parameter">start</replaceable> value is equivalent to supplying
|
class="parameter">restart</> value is equivalent to supplying
|
||||||
the start value used when the sequence was created.
|
the start value that was recorded by <command>CREATE SEQUENCE</>
|
||||||
|
or last set by <command>ALTER SEQUENCE START WITH</>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -261,7 +277,8 @@ ALTER SEQUENCE serial RESTART WITH 105;
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>ALTER SEQUENCE</command> conforms to the <acronym>SQL</acronym>
|
<command>ALTER SEQUENCE</command> conforms to the <acronym>SQL</acronym>
|
||||||
standard, except for the <literal>OWNED BY</>, <literal>RENAME</>, and
|
standard, except for the <literal>START WITH</>,
|
||||||
|
<literal>OWNED BY</>, <literal>RENAME</>, and
|
||||||
<literal>SET SCHEMA</literal> clauses, which are
|
<literal>SET SCHEMA</literal> clauses, which are
|
||||||
<productname>PostgreSQL</productname> extensions.
|
<productname>PostgreSQL</productname> extensions.
|
||||||
</para>
|
</para>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.151 2008/05/16 23:36:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.152 2008/05/17 01:20:39 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -91,7 +91,7 @@ static Relation open_share_lock(SeqTable seq);
|
|||||||
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
|
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
|
||||||
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
|
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
|
||||||
static void init_params(List *options, bool isInit,
|
static void init_params(List *options, bool isInit,
|
||||||
Form_pg_sequence new, Form_pg_sequence old, List **owned_by);
|
Form_pg_sequence new, List **owned_by);
|
||||||
static void do_setval(Oid relid, int64 next, bool iscalled);
|
static void do_setval(Oid relid, int64 next, bool iscalled);
|
||||||
static void process_owned_by(Relation seqrel, List *owned_by);
|
static void process_owned_by(Relation seqrel, List *owned_by);
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ DefineSequence(CreateSeqStmt *seq)
|
|||||||
NameData name;
|
NameData name;
|
||||||
|
|
||||||
/* Check and set all option values */
|
/* Check and set all option values */
|
||||||
init_params(seq->options, true, &new, NULL, &owned_by);
|
init_params(seq->options, true, &new, &owned_by);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create relation (and fill value[] and null[] for the tuple)
|
* Create relation (and fill value[] and null[] for the tuple)
|
||||||
@ -357,8 +357,11 @@ AlterSequenceInternal(Oid relid, List *options)
|
|||||||
seq = read_info(elm, seqrel, &buf);
|
seq = read_info(elm, seqrel, &buf);
|
||||||
page = BufferGetPage(buf);
|
page = BufferGetPage(buf);
|
||||||
|
|
||||||
/* Fill workspace with appropriate new info */
|
/* Copy old values of options into workspace */
|
||||||
init_params(options, false, &new, seq, &owned_by);
|
memcpy(&new, seq, sizeof(FormData_pg_sequence));
|
||||||
|
|
||||||
|
/* Check and set new values */
|
||||||
|
init_params(options, false, &new, &owned_by);
|
||||||
|
|
||||||
/* Clear local cache so that we don't think we have cached numbers */
|
/* Clear local cache so that we don't think we have cached numbers */
|
||||||
/* Note that we do not change the currval() state */
|
/* Note that we do not change the currval() state */
|
||||||
@ -989,9 +992,10 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
init_params(List *options, bool isInit,
|
init_params(List *options, bool isInit,
|
||||||
Form_pg_sequence new, Form_pg_sequence old, List **owned_by)
|
Form_pg_sequence new, List **owned_by)
|
||||||
{
|
{
|
||||||
DefElem *last_value = NULL;
|
DefElem *start_value = NULL;
|
||||||
|
DefElem *restart_value = NULL;
|
||||||
DefElem *increment_by = NULL;
|
DefElem *increment_by = NULL;
|
||||||
DefElem *max_value = NULL;
|
DefElem *max_value = NULL;
|
||||||
DefElem *min_value = NULL;
|
DefElem *min_value = NULL;
|
||||||
@ -1001,12 +1005,6 @@ init_params(List *options, bool isInit,
|
|||||||
|
|
||||||
*owned_by = NIL;
|
*owned_by = NIL;
|
||||||
|
|
||||||
/* Copy old values of options into workspace */
|
|
||||||
if (old != NULL)
|
|
||||||
memcpy(new, old, sizeof(FormData_pg_sequence));
|
|
||||||
else
|
|
||||||
memset(new, 0, sizeof(FormData_pg_sequence));
|
|
||||||
|
|
||||||
foreach(option, options)
|
foreach(option, options)
|
||||||
{
|
{
|
||||||
DefElem *defel = (DefElem *) lfirst(option);
|
DefElem *defel = (DefElem *) lfirst(option);
|
||||||
@ -1021,27 +1019,19 @@ init_params(List *options, bool isInit,
|
|||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "start") == 0)
|
else if (strcmp(defel->defname, "start") == 0)
|
||||||
{
|
{
|
||||||
if (!isInit)
|
if (start_value)
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("use RESTART not START in ALTER SEQUENCE")));
|
|
||||||
if (last_value)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("conflicting or redundant options")));
|
errmsg("conflicting or redundant options")));
|
||||||
last_value = defel;
|
start_value = defel;
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "restart") == 0)
|
else if (strcmp(defel->defname, "restart") == 0)
|
||||||
{
|
{
|
||||||
if (isInit)
|
if (restart_value)
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("use START not RESTART in CREATE SEQUENCE")));
|
|
||||||
if (last_value)
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("conflicting or redundant options")));
|
errmsg("conflicting or redundant options")));
|
||||||
last_value = defel;
|
restart_value = defel;
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "maxvalue") == 0)
|
else if (strcmp(defel->defname, "maxvalue") == 0)
|
||||||
{
|
{
|
||||||
@ -1145,30 +1135,15 @@ init_params(List *options, bool isInit,
|
|||||||
bufm, bufx)));
|
bufm, bufx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* START/RESTART [WITH] */
|
/* START WITH */
|
||||||
if (last_value != NULL)
|
if (start_value != NULL)
|
||||||
{
|
new->start_value = defGetInt64(start_value);
|
||||||
if (last_value->arg != NULL)
|
|
||||||
new->last_value = defGetInt64(last_value);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert(old != NULL);
|
|
||||||
new->last_value = old->start_value;
|
|
||||||
}
|
|
||||||
if (isInit)
|
|
||||||
new->start_value = new->last_value;
|
|
||||||
new->is_called = false;
|
|
||||||
new->log_cnt = 1;
|
|
||||||
}
|
|
||||||
else if (isInit)
|
else if (isInit)
|
||||||
{
|
{
|
||||||
if (new->increment_by > 0)
|
if (new->increment_by > 0)
|
||||||
new->start_value = new->min_value; /* ascending seq */
|
new->start_value = new->min_value; /* ascending seq */
|
||||||
else
|
else
|
||||||
new->start_value = new->max_value; /* descending seq */
|
new->start_value = new->max_value; /* descending seq */
|
||||||
new->last_value = new->start_value;
|
|
||||||
new->is_called = false;
|
|
||||||
new->log_cnt = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* crosscheck START */
|
/* crosscheck START */
|
||||||
@ -1197,7 +1172,24 @@ init_params(List *options, bool isInit,
|
|||||||
bufs, bufm)));
|
bufs, bufm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must crosscheck RESTART separately */
|
/* RESTART [WITH] */
|
||||||
|
if (restart_value != NULL)
|
||||||
|
{
|
||||||
|
if (restart_value->arg != NULL)
|
||||||
|
new->last_value = defGetInt64(restart_value);
|
||||||
|
else
|
||||||
|
new->last_value = new->start_value;
|
||||||
|
new->is_called = false;
|
||||||
|
new->log_cnt = 1;
|
||||||
|
}
|
||||||
|
else if (isInit)
|
||||||
|
{
|
||||||
|
new->last_value = new->start_value;
|
||||||
|
new->is_called = false;
|
||||||
|
new->log_cnt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* crosscheck RESTART (or current value, if changing MIN/MAX) */
|
||||||
if (new->last_value < new->min_value)
|
if (new->last_value < new->min_value)
|
||||||
{
|
{
|
||||||
char bufs[100],
|
char bufs[100],
|
||||||
|
Reference in New Issue
Block a user