Allow ALTER SEQUENCE START WITH to change the recorded start_value of a
authorTom Lane
Sat, 17 May 2008 01:20:39 +0000 (01:20 +0000)
committerTom Lane
Sat, 17 May 2008 01:20:39 +0000 (01:20 +0000)
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
src/backend/commands/sequence.c

index 31e64dac35d85948d4c817baf3fc2bfba17b48ae..7cf69e9ea3faadbeff36f49e6395f2d4093fe0a5 100644 (file)
@@ -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 
+        class="parameter">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 
-        class="parameter">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 
-        class="parameter">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.
   
index 748413ebed3843acc117bc4dfe7139e91d21b327..5d5a3a243c4c8bfe63d7414b4e4082dd6dd92a2a 100644 (file)
@@ -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],