88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.103 2003/09/25 06:57:58 petere Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.104 2003/11/24 16:54:07 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -70,7 +70,7 @@ static SeqTable seqtab = NULL;/* Head of list of SeqTable items */
7070static void init_sequence (RangeVar * relation ,
7171SeqTable * p_elm ,Relation * p_rel );
7272static Form_pg_sequence read_info (SeqTable elm ,Relation rel ,Buffer * buf );
73- static void init_params (List * options ,Form_pg_sequence new );
73+ static void init_params (List * options ,Form_pg_sequence new , bool isInit );
7474static void do_setval (RangeVar * sequence ,int64 next ,bool iscalled );
7575
7676/*
@@ -94,16 +94,8 @@ DefineSequence(CreateSeqStmt *seq)
9494int i ;
9595NameData name ;
9696
97- /* Values are NULL (or false) by default */
98- new .last_value = 0 ;
99- new .increment_by = 0 ;
100- new .max_value = 0 ;
101- new .min_value = 0 ;
102- new .cache_value = 0 ;
103- new .is_cycled = false;
104-
105- /* Check and set values */
106- init_params (seq -> options ,& new );
97+ /* Check and set all option values */
98+ init_params (seq -> options ,& new , true);
10799
108100/*
109101 * Create relation (and fill *null & *value)
@@ -299,7 +291,7 @@ DefineSequence(CreateSeqStmt *seq)
299291/*
300292 * AlterSequence
301293 *
302- * Modify thedefition of a sequence relation
294+ * Modify thedefinition of a sequence relation
303295 */
304296void
305297AlterSequence (AlterSeqStmt * stmt )
@@ -314,7 +306,7 @@ AlterSequence(AlterSeqStmt *stmt)
314306/* open and AccessShareLock sequence */
315307init_sequence (stmt -> sequence ,& elm ,& seqrel );
316308
317- /* allowDROP to sequence owner only */
309+ /* allowALTER to sequence owner only */
318310if (!pg_class_ownercheck (elm -> relid ,GetUserId ()))
319311aclcheck_error (ACLCHECK_NOT_OWNER ,ACL_KIND_CLASS ,
320312stmt -> sequence -> relname );
@@ -323,16 +315,18 @@ AlterSequence(AlterSeqStmt *stmt)
323315seq = read_info (elm ,seqrel ,& buf );
324316page = BufferGetPage (buf );
325317
318+ /* copy old values of options */
326319new .increment_by = seq -> increment_by ;
327320new .max_value = seq -> max_value ;
328321new .min_value = seq -> min_value ;
329322new .cache_value = seq -> cache_value ;
330323new .is_cycled = seq -> is_cycled ;
331324new .last_value = seq -> last_value ;
332325
333- /* Check and set values */
334- init_params (stmt -> options ,& new );
326+ /* Check and setnew values */
327+ init_params (stmt -> options ,& new , false );
335328
329+ /* Now okay to update the on-disk tuple */
336330seq -> increment_by = new .increment_by ;
337331seq -> max_value = new .max_value ;
338332seq -> min_value = new .min_value ;
@@ -871,16 +865,22 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
871865return seq ;
872866}
873867
874-
868+ /*
869+ * init_params: process the options list of CREATE or ALTER SEQUENCE,
870+ * and store the values into appropriate fields of *new.
871+ *
872+ * If isInit is true, fill any unspecified options with default values;
873+ * otherwise, do not change existing options that aren't explicitly overridden.
874+ */
875875static void
876- init_params (List * options ,Form_pg_sequence new )
876+ init_params (List * options ,Form_pg_sequence new , bool isInit )
877877{
878878DefElem * last_value = NULL ;
879879DefElem * increment_by = NULL ;
880880DefElem * max_value = NULL ;
881881DefElem * min_value = NULL ;
882882DefElem * cache_value = NULL ;
883- bool is_cycled_set = false ;
883+ DefElem * is_cycled = NULL ;
884884List * option ;
885885
886886foreach (option ,options )
@@ -934,54 +934,65 @@ init_params(List *options, Form_pg_sequence new)
934934}
935935else if (strcmp (defel -> defname ,"cycle" )== 0 )
936936{
937- if (is_cycled_set )
937+ if (is_cycled )
938938ereport (ERROR ,
939939(errcode (ERRCODE_SYNTAX_ERROR ),
940940errmsg ("conflicting or redundant options" )));
941- is_cycled_set = true;
942- new -> is_cycled = (defel -> arg != NULL );
941+ is_cycled = defel ;
943942}
944943else
945944elog (ERROR ,"option \"%s\" not recognized" ,
946945defel -> defname );
947946}
948947
949948/* INCREMENT BY */
950- if (new -> increment_by == 0 && increment_by == (DefElem * )NULL )
951- new -> increment_by = 1 ;
952- else if (increment_by != (DefElem * )NULL )
949+ if (increment_by != (DefElem * )NULL )
953950{
954951new -> increment_by = defGetInt64 (increment_by );
955952if (new -> increment_by == 0 )
956953ereport (ERROR ,
957954(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
958955errmsg ("INCREMENT must not be zero" )));
959956}
957+ else if (isInit )
958+ new -> increment_by = 1 ;
959+
960+ /* CYCLE */
961+ if (is_cycled != (DefElem * )NULL )
962+ {
963+ new -> is_cycled = intVal (is_cycled -> arg );
964+ Assert (new -> is_cycled == false|| new -> is_cycled == true);
965+ }
966+ else if (isInit )
967+ new -> is_cycled = false;
960968
961- /* MAXVALUE */
962- if ((new -> max_value == 0 && max_value == (DefElem * )NULL )
963- || (max_value != (DefElem * )NULL && !max_value -> arg ))
969+ /* MAXVALUE (null arg means NO MAXVALUE) */
970+ if (max_value != (DefElem * )NULL && max_value -> arg )
971+ {
972+ new -> max_value = defGetInt64 (max_value );
973+ }
974+ else if (isInit || max_value != (DefElem * )NULL )
964975{
965976if (new -> increment_by > 0 )
966977new -> max_value = SEQ_MAXVALUE ;/* ascending seq */
967978else
968- new -> max_value = -1 ;/* descending seq */
979+ new -> max_value = -1 ;/* descending seq */
969980}
970- else if (max_value != (DefElem * )NULL )
971- new -> max_value = defGetInt64 (max_value );
972981
973- /* MINVALUE */
974- if ((new -> min_value == 0 && min_value == (DefElem * )NULL )
975- || (min_value != (DefElem * )NULL && !min_value -> arg ))
982+ /* MINVALUE (null arg means NO MINVALUE) */
983+ if (min_value != (DefElem * )NULL && min_value -> arg )
984+ {
985+ new -> min_value = defGetInt64 (min_value );
986+ }
987+ else if (isInit || min_value != (DefElem * )NULL )
976988{
977989if (new -> increment_by > 0 )
978- new -> min_value = 1 ;/* ascending seq */
990+ new -> min_value = 1 ;/* ascending seq */
979991else
980992new -> min_value = SEQ_MINVALUE ;/* descending seq */
981993}
982- else if (min_value != (DefElem * )NULL )
983- new -> min_value = defGetInt64 (min_value );
984994
995+ /* crosscheck min/max */
985996if (new -> min_value >=new -> max_value )
986997{
987998char bufm [100 ],
@@ -996,16 +1007,17 @@ init_params(List *options, Form_pg_sequence new)
9961007}
9971008
9981009/* START WITH */
999- if (new -> last_value == 0 && last_value == (DefElem * )NULL )
1010+ if (last_value != (DefElem * )NULL )
1011+ new -> last_value = defGetInt64 (last_value );
1012+ else if (isInit )
10001013{
10011014if (new -> increment_by > 0 )
10021015new -> last_value = new -> min_value ;/* ascending seq */
10031016else
10041017new -> last_value = new -> max_value ;/* descending seq */
10051018}
1006- else if (last_value != (DefElem * )NULL )
1007- new -> last_value = defGetInt64 (last_value );
10081019
1020+ /* crosscheck */
10091021if (new -> last_value < new -> min_value )
10101022{
10111023char bufs [100 ],
@@ -1032,17 +1044,22 @@ init_params(List *options, Form_pg_sequence new)
10321044}
10331045
10341046/* CACHE */
1035- if (cache_value == (DefElem * )NULL )
1036- new -> cache_value = 1 ;
1037- else if ((new -> cache_value = defGetInt64 (cache_value )) <=0 )
1047+ if (cache_value != (DefElem * )NULL )
10381048{
1039- char buf [100 ];
1049+ new -> cache_value = defGetInt64 (cache_value );
1050+ if (new -> cache_value <=0 )
1051+ {
1052+ char buf [100 ];
10401053
1041- snprintf (buf ,sizeof (buf ),INT64_FORMAT ,new -> cache_value );
1042- ereport (ERROR ,
1043- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1044- errmsg ("CACHE (%s) must be greater than zero" ,buf )));
1054+ snprintf (buf ,sizeof (buf ),INT64_FORMAT ,new -> cache_value );
1055+ ereport (ERROR ,
1056+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1057+ errmsg ("CACHE (%s) must be greater than zero" ,
1058+ buf )));
1059+ }
10451060}
1061+ else if (isInit )
1062+ new -> cache_value = 1 ;
10461063}
10471064
10481065