提交 e18f5011 编写于 作者: T Tom Lane

Complain if the same column name is inherited from multiple parents

with different default values, unless the child table redeclares the
column with an explicit default.  This was judged to be the approach
least likely to cause unpleasant surprises.
上级 39f0357b
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.75 2001/03/30 20:50:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.76 2001/04/02 18:30:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -276,6 +276,20 @@ TruncateRelation(char *name)
*
* If the same attribute name appears multiple times, then it appears
* in the result table in the proper location for its first appearance.
*
* Constraints (including NOT NULL constraints) for the child table
* are the union of all relevant constraints, from both the child schema
* and parent tables.
*
* The default value for a child column is defined as:
* (1) If the child schema specifies a default, that value is used.
* (2) If neither the child nor any parent specifies a default, then
* the column will not have a default.
* (3) If conflicting defaults are inherited from different parents
* (and not overridden by the child), an error is raised.
* (4) Otherwise the inherited default is used.
* Rule (3) is new in Postgres 7.1; in earlier releases you got a
* rather arbitrary choice of which parent default to use.
*----------
*/
static List *
......@@ -286,6 +300,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
List *inhSchema = NIL;
List *parentOids = NIL;
List *constraints = NIL;
bool have_bogus_defaults = false;
char *bogus_marker = "Bogus!"; /* marks conflicting defaults */
int child_attno;
/*
......@@ -305,12 +321,10 @@ MergeAttributes(List *schema, List *supers, bool istemp,
ColumnDef *restdef = lfirst(rest);
if (strcmp(coldef->colname, restdef->colname) == 0)
{
elog(ERROR, "CREATE TABLE: attribute \"%s\" duplicated",
coldef->colname);
}
}
}
/*
* Reject duplicate names in the list of parents, too.
*/
......@@ -321,12 +335,10 @@ MergeAttributes(List *schema, List *supers, bool istemp,
foreach(rest, lnext(entry))
{
if (strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))) == 0)
{
elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated",
strVal(lfirst(entry)));
}
}
}
/*
* Scan the parents left-to-right, and merge their attributes to form
......@@ -436,31 +448,44 @@ MergeAttributes(List *schema, List *supers, bool istemp,
newattno[parent_attno - 1] = ++child_attno;
}
/*
* Copy default if any, overriding any default from earlier parent
* Copy default if any
*/
if (attribute->atthasdef)
{
char *this_default = NULL;
AttrDefault *attrdef;
int i;
def->raw_default = NULL;
def->cooked_default = NULL;
/* Find default in constraint structure */
Assert(constr != NULL);
attrdef = constr->defval;
for (i = 0; i < constr->num_defval; i++)
{
if (attrdef[i].adnum == parent_attno)
{
/*
* if default expr could contain any vars, we'd
* need to fix 'em, but it can't ...
*/
def->cooked_default = pstrdup(attrdef[i].adbin);
this_default = attrdef[i].adbin;
break;
}
}
Assert(def->cooked_default != NULL);
Assert(this_default != NULL);
/*
* If default expr could contain any vars, we'd need to fix
* 'em, but it can't; so default is ready to apply to child.
*
* If we already had a default from some prior parent,
* check to see if they are the same. If so, no problem;
* if not, mark the column as having a bogus default.
* Below, we will complain if the bogus default isn't
* overridden by the child schema.
*/
Assert(def->raw_default == NULL);
if (def->cooked_default == NULL)
def->cooked_default = pstrdup(this_default);
else if (strcmp(def->cooked_default, this_default) != 0)
{
def->cooked_default = bogus_marker;
have_bogus_defaults = true;
}
}
}
/*
......@@ -555,6 +580,23 @@ MergeAttributes(List *schema, List *supers, bool istemp,
schema = inhSchema;
}
/*
* If we found any conflicting parent default values, check to make
* sure they were overridden by the child.
*/
if (have_bogus_defaults)
{
foreach(entry, schema)
{
ColumnDef *def = lfirst(entry);
if (def->cooked_default == bogus_marker)
elog(ERROR, "CREATE TABLE: attribute \"%s\" inherits conflicting default values"
"\n\tTo resolve the conflict, specify a default explicitly",
def->colname);
}
}
*supOids = parentOids;
*supconstr = constraints;
return schema;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册