diff options
-rw-r--r-- | doc/src/sgml/ref/alter_sequence.sgml | 29 | ||||
-rw-r--r-- | src/backend/commands/sequence.c | 80 |
2 files changed, 59 insertions, 50 deletions
diff --git a/doc/src/sgml/ref/alter_sequence.sgml b/doc/src/sgml/ref/alter_sequence.sgml index 31e64dac35d..7cf69e9ea3f 100644 --- a/doc/src/sgml/ref/alter_sequence.sgml +++ b/doc/src/sgml/ref/alter_sequence.sgml @@ -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 --> @@ -26,7 +26,9 @@ PostgreSQL documentation <synopsis> 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 ] - [ 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 } ] 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> @@ -112,15 +114,29 @@ ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <rep <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> + <para> 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 <function>setval</> function with <literal>is_called</literal> = <literal>false</>: the specified value will be returned by the <emphasis>next</> call of <function>nextval</>. Writing <literal>RESTART</> with no <replaceable - class="parameter">start</replaceable> value is equivalent to supplying - the start value used when the sequence was created. + class="parameter">restart</> value is equivalent to supplying + the start value that was recorded by <command>CREATE SEQUENCE</> + or last set by <command>ALTER SEQUENCE START WITH</>. </para> </listitem> </varlistentry> @@ -261,7 +277,8 @@ ALTER SEQUENCE serial RESTART WITH 105; <para> <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 <productname>PostgreSQL</productname> extensions. </para> diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 748413ebed3..5d5a3a243c4 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -8,7 +8,7 @@ * * * 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 Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf); 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 process_owned_by(Relation seqrel, List *owned_by); @@ -119,7 +119,7 @@ DefineSequence(CreateSeqStmt *seq) NameData name; /* 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) @@ -357,8 +357,11 @@ AlterSequenceInternal(Oid relid, List *options) seq = read_info(elm, seqrel, &buf); page = BufferGetPage(buf); - /* Fill workspace with appropriate new info */ - init_params(options, false, &new, seq, &owned_by); + /* Copy old values of options into workspace */ + 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 */ /* Note that we do not change the currval() state */ @@ -989,9 +992,10 @@ read_info(SeqTable elm, Relation rel, Buffer *buf) */ 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) { - DefElem *last_value = NULL; + DefElem *start_value = NULL; + DefElem *restart_value = NULL; DefElem *increment_by = NULL; DefElem *max_value = NULL; DefElem *min_value = NULL; @@ -1001,12 +1005,6 @@ init_params(List *options, bool isInit, *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) { DefElem *defel = (DefElem *) lfirst(option); @@ -1021,27 +1019,19 @@ init_params(List *options, bool isInit, } else if (strcmp(defel->defname, "start") == 0) { - if (!isInit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("use RESTART not START in ALTER SEQUENCE"))); - if (last_value) + if (start_value) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - last_value = defel; + start_value = defel; } else if (strcmp(defel->defname, "restart") == 0) { - if (isInit) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("use START not RESTART in CREATE SEQUENCE"))); - if (last_value) + if (restart_value) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - last_value = defel; + restart_value = defel; } else if (strcmp(defel->defname, "maxvalue") == 0) { @@ -1145,30 +1135,15 @@ init_params(List *options, bool isInit, bufm, bufx))); } - /* START/RESTART [WITH] */ - if (last_value != NULL) - { - 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; - } + /* START WITH */ + if (start_value != NULL) + new->start_value = defGetInt64(start_value); else if (isInit) { if (new->increment_by > 0) new->start_value = new->min_value; /* ascending seq */ else new->start_value = new->max_value; /* descending seq */ - new->last_value = new->start_value; - new->is_called = false; - new->log_cnt = 1; } /* crosscheck START */ @@ -1197,7 +1172,24 @@ init_params(List *options, bool isInit, 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) { char bufs[100], |