From caede71b447971399011ef7687f4c68fe5ac9fc6 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 17 May 2008 01:20:39 +0000 Subject: [PATCH] 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. --- doc/src/sgml/ref/alter_sequence.sgml | 29 +++++++--- 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 31e64dac35..7cf69e9ea3 100644 --- a/doc/src/sgml/ref/alter_sequence.sgml +++ b/doc/src/sgml/ref/alter_sequence.sgml @@ -1,5 +1,5 @@ @@ -26,7 +26,9 @@ PostgreSQL documentation ALTER SEQUENCE name [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] - [ RESTART [ [ WITH ] start ] ] [ CACHE cache ] [ [ NO ] CYCLE ] + [ START [ WITH ] start ] + [ RESTART [ [ WITH ] restart ] ] + [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table.column | NONE } ] ALTER SEQUENCE name RENAME TO new_name ALTER SEQUENCE name SET SCHEMA new_schema @@ -110,17 +112,31 @@ ALTER SEQUENCE name SET SCHEMA start + + + The optional clause START WITH start changes the + recorded start value of the sequence. This has no effect on the + current sequence value; it simply sets the value + that future ALTER SEQUENCE RESTART commands will use. + + + + + + restart The optional clause RESTART [ WITH start ] changes the + class="parameter">restart ] changes the current value of the sequence. This is equivalent to calling the setval function with is_called = false: the specified value will be returned by the next call of nextval. Writing RESTART with no start 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 CREATE SEQUENCE + or last set by ALTER SEQUENCE START WITH. @@ -261,7 +277,8 @@ ALTER SEQUENCE serial RESTART WITH 105; ALTER SEQUENCE conforms to the SQL - standard, except for the OWNED BY, RENAME, and + standard, except for the START WITH, + OWNED BY, RENAME, and SET SCHEMA clauses, which are PostgreSQL extensions. diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 748413ebed..5d5a3a243c 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], -- 2.40.0