diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 6bc59ca9fb176b0edbfd6565b5ee3d1a619f0ac5..c9076e85b462fa30731203cbcba41192b0c11116 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.103 2003/09/25 06:57:58 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.104 2003/11/24 16:54:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -70,7 +70,7 @@ static SeqTable seqtab = NULL;	/* Head of list of SeqTable items */
 static void init_sequence(RangeVar *relation,
 			  SeqTable *p_elm, Relation *p_rel);
 static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
-static void init_params(List *options, Form_pg_sequence new);
+static void init_params(List *options, Form_pg_sequence new, bool isInit);
 static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
 
 /*
@@ -94,16 +94,8 @@ DefineSequence(CreateSeqStmt *seq)
 	int			i;
 	NameData	name;
 
-	/* Values are NULL (or false) by default */
-	new.last_value = 0;
-	new.increment_by = 0;
-	new.max_value = 0;
-	new.min_value = 0;
-	new.cache_value = 0;
-	new.is_cycled = false;
-
-	/* Check and set values */
-	init_params(seq->options, &new);
+	/* Check and set all option values */
+	init_params(seq->options, &new, true);
 
 	/*
 	 * Create relation (and fill *null & *value)
@@ -299,7 +291,7 @@ DefineSequence(CreateSeqStmt *seq)
 /*
  * AlterSequence
  *
- * Modify the defition of a sequence relation
+ * Modify the definition of a sequence relation
  */
 void
 AlterSequence(AlterSeqStmt *stmt)
@@ -314,7 +306,7 @@ AlterSequence(AlterSeqStmt *stmt)
 	/* open and AccessShareLock sequence */
 	init_sequence(stmt->sequence, &elm, &seqrel);
 
-	/* allow DROP to sequence owner only */
+	/* allow ALTER to sequence owner only */
 	if (!pg_class_ownercheck(elm->relid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
 					   stmt->sequence->relname);
@@ -323,6 +315,7 @@ AlterSequence(AlterSeqStmt *stmt)
 	seq = read_info(elm, seqrel, &buf);
 	page = BufferGetPage(buf);
 
+	/* copy old values of options */
 	new.increment_by = seq->increment_by;
 	new.max_value = seq->max_value;
 	new.min_value = seq->min_value;
@@ -330,9 +323,10 @@ AlterSequence(AlterSeqStmt *stmt)
 	new.is_cycled = seq->is_cycled;
 	new.last_value = seq->last_value;
 
-	/* Check and set values */
-	init_params(stmt->options, &new);
+	/* Check and set new values */
+	init_params(stmt->options, &new, false);
 
+	/* Now okay to update the on-disk tuple */
 	seq->increment_by = new.increment_by;
 	seq->max_value = new.max_value;
 	seq->min_value = new.min_value;
@@ -871,16 +865,22 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
 	return seq;
 }
 
-
+/*
+ * init_params: process the options list of CREATE or ALTER SEQUENCE,
+ * and store the values into appropriate fields of *new.
+ *
+ * If isInit is true, fill any unspecified options with default values;
+ * otherwise, do not change existing options that aren't explicitly overridden.
+ */
 static void
-init_params(List *options, Form_pg_sequence new)
+init_params(List *options, Form_pg_sequence new, bool isInit)
 {
 	DefElem    *last_value = NULL;
 	DefElem    *increment_by = NULL;
 	DefElem    *max_value = NULL;
 	DefElem    *min_value = NULL;
 	DefElem    *cache_value = NULL;
-	bool		is_cycled_set = false;
+	DefElem    *is_cycled = NULL;
 	List	   *option;
 
 	foreach(option, options)
@@ -934,12 +934,11 @@ init_params(List *options, Form_pg_sequence new)
 		}
 		else if (strcmp(defel->defname, "cycle") == 0)
 		{
-			if (is_cycled_set)
+			if (is_cycled)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
 						 errmsg("conflicting or redundant options")));
-			is_cycled_set = true;
-			new->is_cycled = (defel->arg != NULL);
+			is_cycled = defel;
 		}
 		else
 			elog(ERROR, "option \"%s\" not recognized",
@@ -947,9 +946,7 @@ init_params(List *options, Form_pg_sequence new)
 	}
 
 	/* INCREMENT BY */
-	if (new->increment_by == 0 && increment_by == (DefElem *) NULL)
-		new->increment_by = 1;
-	else if (increment_by != (DefElem *) NULL)
+	if (increment_by != (DefElem *) NULL)
 	{
 		new->increment_by = defGetInt64(increment_by);
 		if (new->increment_by == 0)
@@ -957,31 +954,45 @@ init_params(List *options, Form_pg_sequence new)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("INCREMENT must not be zero")));
 	}
+	else if (isInit)
+		new->increment_by = 1;
+
+	/* CYCLE */
+	if (is_cycled != (DefElem *) NULL)
+	{
+		new->is_cycled = intVal(is_cycled->arg);
+		Assert(new->is_cycled == false || new->is_cycled == true);
+	}
+	else if (isInit)
+		new->is_cycled = false;
 
-	/* MAXVALUE */
-	if ((new->max_value == 0 && max_value == (DefElem *) NULL)
-		|| (max_value != (DefElem *) NULL && !max_value->arg))
+	/* MAXVALUE (null arg means NO MAXVALUE) */
+	if (max_value != (DefElem *) NULL && max_value->arg)
+	{
+		new->max_value = defGetInt64(max_value);
+	}
+	else if (isInit || max_value != (DefElem *) NULL)
 	{
 		if (new->increment_by > 0)
 			new->max_value = SEQ_MAXVALUE;		/* ascending seq */
 		else
-			new->max_value = -1;	/* descending seq */
+			new->max_value = -1;				/* descending seq */
 	}
-	else if (max_value != (DefElem *) NULL)
-		new->max_value = defGetInt64(max_value);
 
-	/* MINVALUE */
-	if ((new->min_value == 0 && min_value == (DefElem *) NULL)
-		|| (min_value != (DefElem *) NULL && !min_value->arg))
+	/* MINVALUE (null arg means NO MINVALUE) */
+	if (min_value != (DefElem *) NULL && min_value->arg)
+	{
+		new->min_value = defGetInt64(min_value);
+	}
+	else if (isInit || min_value != (DefElem *) NULL)
 	{
 		if (new->increment_by > 0)
-			new->min_value = 1; /* ascending seq */
+			new->min_value = 1;					/* ascending seq */
 		else
 			new->min_value = SEQ_MINVALUE;		/* descending seq */
 	}
-	else if (min_value != (DefElem *) NULL)
-		new->min_value = defGetInt64(min_value);
 
+	/* crosscheck min/max */
 	if (new->min_value >= new->max_value)
 	{
 		char		bufm[100],
@@ -996,16 +1007,17 @@ init_params(List *options, Form_pg_sequence new)
 	}
 
 	/* START WITH */
-	if (new->last_value == 0 && last_value == (DefElem *) NULL)
+	if (last_value != (DefElem *) NULL)
+		new->last_value = defGetInt64(last_value);
+	else if (isInit)
 	{
 		if (new->increment_by > 0)
 			new->last_value = new->min_value;	/* ascending seq */
 		else
 			new->last_value = new->max_value;	/* descending seq */
 	}
-	else if (last_value != (DefElem *) NULL)
-		new->last_value = defGetInt64(last_value);
 
+	/* crosscheck */
 	if (new->last_value < new->min_value)
 	{
 		char		bufs[100],
@@ -1032,17 +1044,22 @@ init_params(List *options, Form_pg_sequence new)
 	}
 
 	/* CACHE */
-	if (cache_value == (DefElem *) NULL)
-		new->cache_value = 1;
-	else if ((new->cache_value = defGetInt64(cache_value)) <= 0)
+	if (cache_value != (DefElem *) NULL)
 	{
-		char		buf[100];
+		new->cache_value = defGetInt64(cache_value);
+		if (new->cache_value <= 0)
+		{
+			char		buf[100];
 
-		snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value);
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("CACHE (%s) must be greater than zero", buf)));
+			snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value);
+			ereport(ERROR,
+					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+					 errmsg("CACHE (%s) must be greater than zero",
+							buf)));
+		}
 	}
+	else if (isInit)
+		new->cache_value = 1;
 }
 
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 337eef4480c8d52d4bde79bb2babf93b7ef11a74..3452b50fb03c33fad6e4453c1ec36970454e9072 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.438 2003/11/21 22:32:49 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.439 2003/11/24 16:54:07 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -1926,11 +1926,11 @@ OptSeqElem: CACHE NumericOnly
 				}
 			| CYCLE
 				{
-					$$ = makeDefElem("cycle", (Node *)true);
+					$$ = makeDefElem("cycle", (Node *)makeInteger(TRUE));
 				}
 			| NO CYCLE
 				{
-					$$ = makeDefElem("cycle", (Node *)false);
+					$$ = makeDefElem("cycle", (Node *)makeInteger(FALSE));
 				}
 			| INCREMENT opt_by NumericOnly
 				{