Commit 1c5f223e authored by Tom Lane's avatar Tom Lane

Overdue code review for ALTER SEQUENCE patch. Don't generate illegal Node

tree for CYCLE option; don't assume zeros are invalid values for sequence
fields other than increment_by; don't reset cache_value when not told to;
simplify code for testing whether to apply defaults.
parent b3d72d3e
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 */ ...@@ -70,7 +70,7 @@ static SeqTable seqtab = NULL; /* Head of list of SeqTable items */
static void init_sequence(RangeVar *relation, static void init_sequence(RangeVar *relation,
SeqTable *p_elm, Relation *p_rel); SeqTable *p_elm, Relation *p_rel);
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf); 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); static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
/* /*
...@@ -94,16 +94,8 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -94,16 +94,8 @@ DefineSequence(CreateSeqStmt *seq)
int i; int i;
NameData name; NameData name;
/* Values are NULL (or false) by default */ /* Check and set all option values */
new.last_value = 0; init_params(seq->options, &new, true);
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);
/* /*
* Create relation (and fill *null & *value) * Create relation (and fill *null & *value)
...@@ -299,7 +291,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -299,7 +291,7 @@ DefineSequence(CreateSeqStmt *seq)
/* /*
* AlterSequence * AlterSequence
* *
* Modify the defition of a sequence relation * Modify the definition of a sequence relation
*/ */
void void
AlterSequence(AlterSeqStmt *stmt) AlterSequence(AlterSeqStmt *stmt)
...@@ -314,7 +306,7 @@ AlterSequence(AlterSeqStmt *stmt) ...@@ -314,7 +306,7 @@ AlterSequence(AlterSeqStmt *stmt)
/* open and AccessShareLock sequence */ /* open and AccessShareLock sequence */
init_sequence(stmt->sequence, &elm, &seqrel); 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())) if (!pg_class_ownercheck(elm->relid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
stmt->sequence->relname); stmt->sequence->relname);
...@@ -323,6 +315,7 @@ AlterSequence(AlterSeqStmt *stmt) ...@@ -323,6 +315,7 @@ AlterSequence(AlterSeqStmt *stmt)
seq = read_info(elm, seqrel, &buf); seq = read_info(elm, seqrel, &buf);
page = BufferGetPage(buf); page = BufferGetPage(buf);
/* copy old values of options */
new.increment_by = seq->increment_by; new.increment_by = seq->increment_by;
new.max_value = seq->max_value; new.max_value = seq->max_value;
new.min_value = seq->min_value; new.min_value = seq->min_value;
...@@ -330,9 +323,10 @@ AlterSequence(AlterSeqStmt *stmt) ...@@ -330,9 +323,10 @@ AlterSequence(AlterSeqStmt *stmt)
new.is_cycled = seq->is_cycled; new.is_cycled = seq->is_cycled;
new.last_value = seq->last_value; new.last_value = seq->last_value;
/* Check and set values */ /* Check and set new values */
init_params(stmt->options, &new); init_params(stmt->options, &new, false);
/* Now okay to update the on-disk tuple */
seq->increment_by = new.increment_by; seq->increment_by = new.increment_by;
seq->max_value = new.max_value; seq->max_value = new.max_value;
seq->min_value = new.min_value; seq->min_value = new.min_value;
...@@ -871,16 +865,22 @@ read_info(SeqTable elm, Relation rel, Buffer *buf) ...@@ -871,16 +865,22 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
return seq; 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 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 *last_value = NULL;
DefElem *increment_by = NULL; DefElem *increment_by = NULL;
DefElem *max_value = NULL; DefElem *max_value = NULL;
DefElem *min_value = NULL; DefElem *min_value = NULL;
DefElem *cache_value = NULL; DefElem *cache_value = NULL;
bool is_cycled_set = false; DefElem *is_cycled = NULL;
List *option; List *option;
foreach(option, options) foreach(option, options)
...@@ -934,12 +934,11 @@ init_params(List *options, Form_pg_sequence new) ...@@ -934,12 +934,11 @@ init_params(List *options, Form_pg_sequence new)
} }
else if (strcmp(defel->defname, "cycle") == 0) else if (strcmp(defel->defname, "cycle") == 0)
{ {
if (is_cycled_set) if (is_cycled)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options"))); errmsg("conflicting or redundant options")));
is_cycled_set = true; is_cycled = defel;
new->is_cycled = (defel->arg != NULL);
} }
else else
elog(ERROR, "option \"%s\" not recognized", elog(ERROR, "option \"%s\" not recognized",
...@@ -947,9 +946,7 @@ init_params(List *options, Form_pg_sequence new) ...@@ -947,9 +946,7 @@ init_params(List *options, Form_pg_sequence new)
} }
/* INCREMENT BY */ /* INCREMENT BY */
if (new->increment_by == 0 && increment_by == (DefElem *) NULL) if (increment_by != (DefElem *) NULL)
new->increment_by = 1;
else if (increment_by != (DefElem *) NULL)
{ {
new->increment_by = defGetInt64(increment_by); new->increment_by = defGetInt64(increment_by);
if (new->increment_by == 0) if (new->increment_by == 0)
...@@ -957,31 +954,45 @@ init_params(List *options, Form_pg_sequence new) ...@@ -957,31 +954,45 @@ init_params(List *options, Form_pg_sequence new)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("INCREMENT must not be zero"))); 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 */ /* MAXVALUE (null arg means NO MAXVALUE) */
if ((new->max_value == 0 && max_value == (DefElem *) NULL) if (max_value != (DefElem *) NULL && max_value->arg)
|| (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) if (new->increment_by > 0)
new->max_value = SEQ_MAXVALUE; /* ascending seq */ new->max_value = SEQ_MAXVALUE; /* ascending seq */
else 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 */ /* MINVALUE (null arg means NO MINVALUE) */
if ((new->min_value == 0 && min_value == (DefElem *) NULL) if (min_value != (DefElem *) NULL && min_value->arg)
|| (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) if (new->increment_by > 0)
new->min_value = 1; /* ascending seq */ new->min_value = 1; /* ascending seq */
else else
new->min_value = SEQ_MINVALUE; /* descending seq */ 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) if (new->min_value >= new->max_value)
{ {
char bufm[100], char bufm[100],
...@@ -996,16 +1007,17 @@ init_params(List *options, Form_pg_sequence new) ...@@ -996,16 +1007,17 @@ init_params(List *options, Form_pg_sequence new)
} }
/* START WITH */ /* 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) if (new->increment_by > 0)
new->last_value = new->min_value; /* ascending seq */ new->last_value = new->min_value; /* ascending seq */
else else
new->last_value = new->max_value; /* descending seq */ 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) if (new->last_value < new->min_value)
{ {
char bufs[100], char bufs[100],
...@@ -1032,17 +1044,22 @@ init_params(List *options, Form_pg_sequence new) ...@@ -1032,17 +1044,22 @@ init_params(List *options, Form_pg_sequence new)
} }
/* CACHE */ /* CACHE */
if (cache_value == (DefElem *) NULL) if (cache_value != (DefElem *) NULL)
new->cache_value = 1; {
else if ((new->cache_value = defGetInt64(cache_value)) <= 0) new->cache_value = defGetInt64(cache_value);
if (new->cache_value <= 0)
{ {
char buf[100]; char buf[100];
snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value); snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value);
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("CACHE (%s) must be greater than zero", buf))); errmsg("CACHE (%s) must be greater than zero",
buf)));
}
} }
else if (isInit)
new->cache_value = 1;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -1926,11 +1926,11 @@ OptSeqElem: CACHE NumericOnly ...@@ -1926,11 +1926,11 @@ OptSeqElem: CACHE NumericOnly
} }
| CYCLE | CYCLE
{ {
$$ = makeDefElem("cycle", (Node *)true); $$ = makeDefElem("cycle", (Node *)makeInteger(TRUE));
} }
| NO CYCLE | NO CYCLE
{ {
$$ = makeDefElem("cycle", (Node *)false); $$ = makeDefElem("cycle", (Node *)makeInteger(FALSE));
} }
| INCREMENT opt_by NumericOnly | INCREMENT opt_by NumericOnly
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment