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);
9191static void init_sequence (Oid relid ,SeqTable * p_elm ,Relation * p_rel );
9292static Form_pg_sequence read_info (SeqTable elm ,Relation rel ,Buffer * buf );
9393static 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 );
9595static void do_setval (Oid relid ,int64 next ,bool iscalled );
9696static void process_owned_by (Relation seqrel ,List * owned_by );
9797
@@ -119,7 +119,7 @@ DefineSequence(CreateSeqStmt *seq)
119119NameData 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)
357357seq = read_info (elm ,seqrel ,& buf );
358358page = 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 */
990993static void
991994init_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 ;
995999DefElem * increment_by = NULL ;
9961000DefElem * max_value = NULL ;
9971001DefElem * 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-
10101008foreach (option ,options )
10111009{
10121010DefElem * defel = (DefElem * )lfirst (option );
@@ -1021,27 +1019,19 @@ init_params(List *options, bool isInit,
10211019}
10221020else 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 )
10291023ereport (ERROR ,
10301024(errcode (ERRCODE_SYNTAX_ERROR ),
10311025errmsg ("conflicting or redundant options" )));
1032- last_value = defel ;
1026+ start_value = defel ;
10331027}
10341028else 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 )
10411031ereport (ERROR ,
10421032(errcode (ERRCODE_SYNTAX_ERROR ),
10431033errmsg ("conflicting or redundant options" )));
1044- last_value = defel ;
1034+ restart_value = defel ;
10451035}
10461036else if (strcmp (defel -> defname ,"maxvalue" )== 0 )
10471037{
@@ -1145,30 +1135,15 @@ init_params(List *options, bool isInit,
11451135bufm ,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 );
11631141else if (isInit )
11641142{
11651143if (new -> increment_by > 0 )
11661144new -> start_value = new -> min_value ;/* ascending seq */
11671145else
11681146new -> 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,
11971172bufs ,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) */
12011193if (new -> last_value < new -> min_value )
12021194{
12031195char bufs [100 ],