mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Add more dependency insertions --- this completes the basic pg_depend
functionality. Of note: dropping a table that has a SERIAL column defined now drops the associated sequence automatically.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.35 2002/07/12 18:43:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.36 2002/07/16 22:12:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -49,6 +49,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||
HeapTuple tup;
|
||||
TupleDesc tupDesc;
|
||||
int i;
|
||||
ObjectAddress myself,
|
||||
referenced;
|
||||
|
||||
/*
|
||||
* Check permission
|
||||
@ -91,7 +93,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||
NameListToString(stmt->plvalidator));
|
||||
}
|
||||
else
|
||||
valProcOid = 0;
|
||||
valProcOid = InvalidOid;
|
||||
|
||||
/*
|
||||
* Insert the new language into pg_language
|
||||
@ -128,6 +130,28 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||
CatalogCloseIndices(Num_pg_language_indices, idescs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create dependencies for language
|
||||
*/
|
||||
myself.classId = RelationGetRelid(rel);
|
||||
myself.objectId = tup->t_data->t_oid;
|
||||
myself.objectSubId = 0;
|
||||
|
||||
/* dependency on the PL handler function */
|
||||
referenced.classId = RelOid_pg_proc;
|
||||
referenced.objectId = procOid;
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
|
||||
/* dependency on the validator function, if any */
|
||||
if (OidIsValid(valProcOid))
|
||||
{
|
||||
referenced.classId = RelOid_pg_proc;
|
||||
referenced.objectId = valProcOid;
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.82 2002/06/20 20:29:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.83 2002/07/16 22:12:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -124,11 +124,15 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
typnam->setof = FALSE;
|
||||
typnam->arrayBounds = NIL;
|
||||
typnam->typmod = -1;
|
||||
|
||||
coldef = makeNode(ColumnDef);
|
||||
coldef->typename = typnam;
|
||||
coldef->is_not_null = true;
|
||||
coldef->raw_default = NULL;
|
||||
coldef->cooked_default = NULL;
|
||||
coldef->is_not_null = false;
|
||||
coldef->constraints = NIL;
|
||||
coldef->support = NULL;
|
||||
|
||||
null[i - 1] = ' ';
|
||||
|
||||
switch (i)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.22 2002/07/16 05:53:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.23 2002/07/16 22:12:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -239,6 +239,10 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
* So, the transformation has to be postponed to this final step of
|
||||
* CREATE TABLE.
|
||||
*
|
||||
* Another task that's conveniently done at this step is to add
|
||||
* dependency links between columns and supporting relations (such
|
||||
* as SERIAL sequences).
|
||||
*
|
||||
* First, scan schema to find new column defaults.
|
||||
*/
|
||||
rawDefaults = NIL;
|
||||
@ -247,18 +251,35 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
foreach(listptr, schema)
|
||||
{
|
||||
ColumnDef *colDef = lfirst(listptr);
|
||||
RawColumnDefault *rawEnt;
|
||||
|
||||
attnum++;
|
||||
|
||||
if (colDef->raw_default == NULL)
|
||||
continue;
|
||||
Assert(colDef->cooked_default == NULL);
|
||||
if (colDef->raw_default != NULL)
|
||||
{
|
||||
RawColumnDefault *rawEnt;
|
||||
|
||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||
rawEnt->attnum = attnum;
|
||||
rawEnt->raw_default = colDef->raw_default;
|
||||
rawDefaults = lappend(rawDefaults, rawEnt);
|
||||
Assert(colDef->cooked_default == NULL);
|
||||
|
||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||
rawEnt->attnum = attnum;
|
||||
rawEnt->raw_default = colDef->raw_default;
|
||||
rawDefaults = lappend(rawDefaults, rawEnt);
|
||||
}
|
||||
|
||||
if (colDef->support != NULL)
|
||||
{
|
||||
/* Create dependency for supporting relation for this column */
|
||||
ObjectAddress colobject,
|
||||
suppobject;
|
||||
|
||||
colobject.classId = RelOid_pg_class;
|
||||
colobject.objectId = relationId;
|
||||
colobject.objectSubId = attnum;
|
||||
suppobject.classId = RelOid_pg_class;
|
||||
suppobject.objectId = RangeVarGetRelid(colDef->support, false);
|
||||
suppobject.objectSubId = 0;
|
||||
recordDependencyOn(&suppobject, &colobject, DEPENDENCY_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -533,6 +554,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->constraints = NIL;
|
||||
def->support = NULL;
|
||||
inhSchema = lappend(inhSchema, def);
|
||||
newattno[parent_attno - 1] = ++child_attno;
|
||||
}
|
||||
@ -1524,6 +1546,8 @@ AlterTableAddColumn(Oid myrelid,
|
||||
HeapTuple typeTuple;
|
||||
Form_pg_type tform;
|
||||
int attndims;
|
||||
ObjectAddress myself,
|
||||
referenced;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
@ -1697,6 +1721,17 @@ AlterTableAddColumn(Oid myrelid,
|
||||
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
* Add datatype dependency for the new column.
|
||||
*/
|
||||
myself.classId = RelOid_pg_class;
|
||||
myself.objectId = myrelid;
|
||||
myself.objectSubId = i;
|
||||
referenced.classId = RelOid_pg_type;
|
||||
referenced.objectId = attribute->atttypid;
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
|
||||
/*
|
||||
* Make our catalog updates visible for subsequent steps.
|
||||
*/
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.5 2002/07/12 18:43:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.6 2002/07/16 22:12:19 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -358,15 +358,18 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||
char typtype;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
Node *defaultExpr = NULL;
|
||||
char *defaultValue = NULL;
|
||||
char *defaultValueBin = NULL;
|
||||
bool typNotNull = false;
|
||||
bool nullDefined = false;
|
||||
Oid basetypelem;
|
||||
int32 typNDims = length(stmt->typename->arrayBounds);
|
||||
HeapTuple typeTup;
|
||||
List *schema = stmt->constraints;
|
||||
List *listptr;
|
||||
Oid basetypeoid;
|
||||
Oid domainoid;
|
||||
Form_pg_type baseType;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
@ -459,8 +462,6 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||
foreach(listptr, schema)
|
||||
{
|
||||
Constraint *colDef = lfirst(listptr);
|
||||
bool nullDefined = false;
|
||||
Node *expr;
|
||||
ParseState *pstate;
|
||||
|
||||
switch (colDef->contype)
|
||||
@ -473,47 +474,45 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||
* don't want to cook or fiddle too much.
|
||||
*/
|
||||
case CONSTR_DEFAULT:
|
||||
if (defaultExpr)
|
||||
elog(ERROR, "CREATE DOMAIN has multiple DEFAULT expressions");
|
||||
/* Create a dummy ParseState for transformExpr */
|
||||
pstate = make_parsestate(NULL);
|
||||
/*
|
||||
* Cook the colDef->raw_expr into an expression.
|
||||
* Note: Name is strictly for error message
|
||||
*/
|
||||
expr = cookDefault(pstate, colDef->raw_expr,
|
||||
basetypeoid,
|
||||
stmt->typename->typmod,
|
||||
domainName);
|
||||
defaultExpr = cookDefault(pstate, colDef->raw_expr,
|
||||
basetypeoid,
|
||||
stmt->typename->typmod,
|
||||
domainName);
|
||||
/*
|
||||
* Expression must be stored as a nodeToString result,
|
||||
* but we also require a valid textual representation
|
||||
* (mainly to make life easier for pg_dump).
|
||||
*/
|
||||
defaultValue = deparse_expression(expr,
|
||||
defaultValue = deparse_expression(defaultExpr,
|
||||
deparse_context_for(domainName,
|
||||
InvalidOid),
|
||||
false);
|
||||
defaultValueBin = nodeToString(expr);
|
||||
defaultValueBin = nodeToString(defaultExpr);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Find the NULL constraint.
|
||||
*/
|
||||
case CONSTR_NOTNULL:
|
||||
if (nullDefined) {
|
||||
if (nullDefined)
|
||||
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
||||
} else {
|
||||
typNotNull = true;
|
||||
nullDefined = true;
|
||||
}
|
||||
typNotNull = true;
|
||||
nullDefined = true;
|
||||
break;
|
||||
|
||||
case CONSTR_NULL:
|
||||
if (nullDefined) {
|
||||
if (nullDefined)
|
||||
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
||||
} else {
|
||||
typNotNull = false;
|
||||
nullDefined = true;
|
||||
}
|
||||
typNotNull = false;
|
||||
nullDefined = true;
|
||||
break;
|
||||
|
||||
case CONSTR_UNIQUE:
|
||||
@ -544,28 +543,44 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||
/*
|
||||
* Have TypeCreate do all the real work.
|
||||
*/
|
||||
TypeCreate(domainName, /* type name */
|
||||
domainNamespace, /* namespace */
|
||||
InvalidOid, /* preassigned type oid (none here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
internalLength, /* internal size */
|
||||
externalLength, /* external size */
|
||||
'd', /* type-type (domain type) */
|
||||
delimiter, /* array element delimiter */
|
||||
inputProcedure, /* input procedure */
|
||||
outputProcedure, /* output procedure */
|
||||
receiveProcedure, /* receive procedure */
|
||||
sendProcedure, /* send procedure */
|
||||
basetypelem, /* element type ID */
|
||||
basetypeoid, /* base type ID */
|
||||
defaultValue, /* default type value (text) */
|
||||
defaultValueBin, /* default type value (binary) */
|
||||
byValue, /* passed by value */
|
||||
alignment, /* required alignment */
|
||||
storage, /* TOAST strategy */
|
||||
stmt->typename->typmod, /* typeMod value */
|
||||
typNDims, /* Array dimensions for base type */
|
||||
typNotNull); /* Type NOT NULL */
|
||||
domainoid =
|
||||
TypeCreate(domainName, /* type name */
|
||||
domainNamespace, /* namespace */
|
||||
InvalidOid, /* preassigned type oid (none here) */
|
||||
InvalidOid, /* relation oid (n/a here) */
|
||||
internalLength, /* internal size */
|
||||
externalLength, /* external size */
|
||||
'd', /* type-type (domain type) */
|
||||
delimiter, /* array element delimiter */
|
||||
inputProcedure, /* input procedure */
|
||||
outputProcedure, /* output procedure */
|
||||
receiveProcedure, /* receive procedure */
|
||||
sendProcedure, /* send procedure */
|
||||
basetypelem, /* element type ID */
|
||||
basetypeoid, /* base type ID */
|
||||
defaultValue, /* default type value (text) */
|
||||
defaultValueBin, /* default type value (binary) */
|
||||
byValue, /* passed by value */
|
||||
alignment, /* required alignment */
|
||||
storage, /* TOAST strategy */
|
||||
stmt->typename->typmod, /* typeMod value */
|
||||
typNDims, /* Array dimensions for base type */
|
||||
typNotNull); /* Type NOT NULL */
|
||||
|
||||
/*
|
||||
* Add any dependencies needed for the default expression.
|
||||
*/
|
||||
if (defaultExpr)
|
||||
{
|
||||
ObjectAddress domobject;
|
||||
|
||||
domobject.classId = RelOid_pg_type;
|
||||
domobject.objectId = domainoid;
|
||||
domobject.objectSubId = 0;
|
||||
|
||||
recordDependencyOnExpr(&domobject, defaultExpr, NIL,
|
||||
DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we can clean up.
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: view.c,v 1.66 2002/07/12 18:43:16 tgl Exp $
|
||||
* $Id: view.c,v 1.67 2002/07/16 22:12:19 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -72,6 +72,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist)
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->constraints = NIL;
|
||||
def->support = NULL;
|
||||
|
||||
attrList = lappend(attrList, def);
|
||||
}
|
||||
|
Reference in New Issue
Block a user