mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Fix all known problems with pg_dump's handling of serial sequences
by abandoning the idea that it should say SERIAL in the dump. Instead, dump serial sequences and column defaults just like regular ones. Add a new backend command ALTER SEQUENCE OWNED BY to let pg_dump recreate the sequence-to-column dependency that was formerly created "behind the scenes" by SERIAL. This restores SERIAL to being truly "just a macro" consisting of component operations that can be stated explicitly in SQL. Furthermore, the new command allows sequence ownership to be reassigned, so that old mistakes can be cleaned up. Also, downgrade the OWNED-BY dependency from INTERNAL to AUTO, since there is no longer any very compelling argument why the sequence couldn't be dropped while keeping the column. (This forces initdb, to be sure the right kinds of dependencies are in there.) Along the way, add checks to prevent ALTER OWNER or SET SCHEMA on an owned sequence; you can now only do this indirectly by changing the owning table's owner or schema. This is an oversight in previous releases, but probably not worth back-patching.
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.346 2006/08/12 20:05:55 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.347 2006/08/21 00:57:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -980,6 +980,14 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* transformIndexConstraints wants cxt.alist to contain only index
|
||||
* statements, so transfer anything we already have into extras_after
|
||||
* immediately.
|
||||
*/
|
||||
*extras_after = list_concat(cxt.alist, *extras_after);
|
||||
cxt.alist = NIL;
|
||||
|
||||
Assert(stmt->constraints == NIL);
|
||||
|
||||
/*
|
||||
@ -1052,6 +1060,8 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
|
||||
A_Const *snamenode;
|
||||
FuncCall *funccallnode;
|
||||
CreateSeqStmt *seqstmt;
|
||||
AlterSeqStmt *altseqstmt;
|
||||
List *attnamelist;
|
||||
|
||||
/*
|
||||
* Determine namespace and name to use for the sequence.
|
||||
@ -1088,10 +1098,19 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
|
||||
cxt->blist = lappend(cxt->blist, seqstmt);
|
||||
|
||||
/*
|
||||
* Mark the ColumnDef so that during execution, an appropriate
|
||||
* dependency will be added from the sequence to the column.
|
||||
* Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence
|
||||
* as owned by this column, and add it to the list of things to be
|
||||
* done after this CREATE/ALTER TABLE.
|
||||
*/
|
||||
column->support = makeRangeVar(snamespace, sname);
|
||||
altseqstmt = makeNode(AlterSeqStmt);
|
||||
altseqstmt->sequence = makeRangeVar(snamespace, sname);
|
||||
attnamelist = list_make3(makeString(snamespace),
|
||||
makeString(cxt->relation->relname),
|
||||
makeString(column->colname));
|
||||
altseqstmt->options = list_make1(makeDefElem("owned_by",
|
||||
(Node *) attnamelist));
|
||||
|
||||
cxt->alist = lappend(cxt->alist, altseqstmt);
|
||||
|
||||
/*
|
||||
* Create appropriate constraints for SERIAL. We do this in full,
|
||||
@ -1349,7 +1368,6 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->constraints = NIL;
|
||||
def->support = NULL;
|
||||
|
||||
/*
|
||||
* Add to column list
|
||||
@ -1604,7 +1622,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
|
||||
* XXX in ALTER TABLE case, it'd be nice to look for duplicate
|
||||
* pre-existing indexes, too.
|
||||
*/
|
||||
cxt->alist = NIL;
|
||||
Assert(cxt->alist == NIL);
|
||||
if (cxt->pkey != NULL)
|
||||
{
|
||||
/* Make sure we keep the PKEY index in preference to others... */
|
||||
@ -3041,6 +3059,14 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* transformIndexConstraints wants cxt.alist to contain only index
|
||||
* statements, so transfer anything we already have into extras_after
|
||||
* immediately.
|
||||
*/
|
||||
*extras_after = list_concat(cxt.alist, *extras_after);
|
||||
cxt.alist = NIL;
|
||||
|
||||
/* Postprocess index and FK constraints */
|
||||
transformIndexConstraints(pstate, &cxt);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.556 2006/08/12 18:58:54 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.557 2006/08/21 00:57:25 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -95,7 +95,6 @@ static Node *makeIntConst(int val);
|
||||
static Node *makeFloatConst(char *str);
|
||||
static Node *makeAConst(Value *v);
|
||||
static Node *makeRowNullTest(NullTestType test, RowExpr *row);
|
||||
static DefElem *makeDefElem(char *name, Node *arg);
|
||||
static A_Const *makeBoolAConst(bool state);
|
||||
static FuncCall *makeOverlaps(List *largs, List *rargs, int location);
|
||||
static void check_qualified_name(List *names);
|
||||
@ -2275,7 +2274,6 @@ CreateAsElement:
|
||||
n->raw_default = NULL;
|
||||
n->cooked_default = NULL;
|
||||
n->constraints = NIL;
|
||||
n->support = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@ -2346,6 +2344,10 @@ OptSeqElem: CACHE NumericOnly
|
||||
{
|
||||
$$ = makeDefElem("minvalue", NULL);
|
||||
}
|
||||
| OWNED BY any_name
|
||||
{
|
||||
$$ = makeDefElem("owned_by", (Node *)$3);
|
||||
}
|
||||
| START opt_with NumericOnly
|
||||
{
|
||||
$$ = makeDefElem("start", (Node *)$3);
|
||||
@ -8977,19 +8979,6 @@ makeAConst(Value *v)
|
||||
return n;
|
||||
}
|
||||
|
||||
/* makeDefElem()
|
||||
* Create a DefElem node and set contents.
|
||||
* Could be moved to nodes/makefuncs.c if this is useful elsewhere.
|
||||
*/
|
||||
static DefElem *
|
||||
makeDefElem(char *name, Node *arg)
|
||||
{
|
||||
DefElem *f = makeNode(DefElem);
|
||||
f->defname = name;
|
||||
f->arg = arg;
|
||||
return f;
|
||||
}
|
||||
|
||||
/* makeBoolAConst()
|
||||
* Create an A_Const node and initialize to a boolean constant.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user