mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +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:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.140 2002/07/12 18:43:12 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.141 2002/07/16 22:12:18 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<appendix id="release">
|
<appendix id="release">
|
||||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
|||||||
worries about funny characters.
|
worries about funny characters.
|
||||||
-->
|
-->
|
||||||
<literallayout><![CDATA[
|
<literallayout><![CDATA[
|
||||||
|
Sequences created by SERIAL column definitions now auto-drop with the column
|
||||||
Most forms of DROP now support RESTRICT and CASCADE options
|
Most forms of DROP now support RESTRICT and CASCADE options
|
||||||
Recursive SQL functions can be defined
|
Recursive SQL functions can be defined
|
||||||
User-defined procedural languages can register a validator function to check new functions as they are created
|
User-defined procedural languages can register a validator function to check new functions as they are created
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.208 2002/07/16 05:53:33 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.209 2002/07/16 22:12:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel);
|
|||||||
static FormData_pg_attribute a1 = {
|
static FormData_pg_attribute a1 = {
|
||||||
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
|
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
|
||||||
SelfItemPointerAttributeNumber, 0, -1, -1,
|
SelfItemPointerAttributeNumber, 0, -1, -1,
|
||||||
false, 'p', false, 'i', false, false
|
false, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static FormData_pg_attribute a2 = {
|
static FormData_pg_attribute a2 = {
|
||||||
0, {"oid"}, OIDOID, 0, sizeof(Oid),
|
0, {"oid"}, OIDOID, 0, sizeof(Oid),
|
||||||
ObjectIdAttributeNumber, 0, -1, -1,
|
ObjectIdAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static FormData_pg_attribute a3 = {
|
static FormData_pg_attribute a3 = {
|
||||||
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
|
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
|
||||||
MinTransactionIdAttributeNumber, 0, -1, -1,
|
MinTransactionIdAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static FormData_pg_attribute a4 = {
|
static FormData_pg_attribute a4 = {
|
||||||
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
|
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
|
||||||
MinCommandIdAttributeNumber, 0, -1, -1,
|
MinCommandIdAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static FormData_pg_attribute a5 = {
|
static FormData_pg_attribute a5 = {
|
||||||
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
|
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
|
||||||
MaxTransactionIdAttributeNumber, 0, -1, -1,
|
MaxTransactionIdAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static FormData_pg_attribute a6 = {
|
static FormData_pg_attribute a6 = {
|
||||||
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
|
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
|
||||||
MaxCommandIdAttributeNumber, 0, -1, -1,
|
MaxCommandIdAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = {
|
|||||||
static FormData_pg_attribute a7 = {
|
static FormData_pg_attribute a7 = {
|
||||||
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
|
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
|
||||||
TableOidAttributeNumber, 0, -1, -1,
|
TableOidAttributeNumber, 0, -1, -1,
|
||||||
true, 'p', false, 'i', false, false
|
true, 'p', false, 'i', true, false
|
||||||
};
|
};
|
||||||
|
|
||||||
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
|
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
|
||||||
@ -416,6 +416,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|||||||
bool hasindex;
|
bool hasindex;
|
||||||
Relation idescs[Num_pg_attr_indices];
|
Relation idescs[Num_pg_attr_indices];
|
||||||
int natts = tupdesc->natts;
|
int natts = tupdesc->natts;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open pg_attribute
|
* open pg_attribute
|
||||||
@ -430,7 +432,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|||||||
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
|
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first we add the user attributes..
|
* First we add the user attributes. This is also a convenient place
|
||||||
|
* to add dependencies on their datatypes.
|
||||||
*/
|
*/
|
||||||
dpp = tupdesc->attrs;
|
dpp = tupdesc->attrs;
|
||||||
for (i = 0; i < natts; i++)
|
for (i = 0; i < natts; i++)
|
||||||
@ -451,11 +454,22 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|||||||
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
|
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
|
||||||
|
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
|
myself.classId = RelOid_pg_class;
|
||||||
|
myself.objectId = new_rel_oid;
|
||||||
|
myself.objectSubId = i+1;
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = (*dpp)->atttypid;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
dpp++;
|
dpp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* next we add the system attributes. Skip OID if rel has no OIDs.
|
* Next we add the system attributes. Skip OID if rel has no OIDs.
|
||||||
|
* Skip all for a view. We don't bother with making datatype
|
||||||
|
* dependencies here, since presumably all these types are pinned.
|
||||||
*/
|
*/
|
||||||
if (relkind != RELKIND_VIEW)
|
if (relkind != RELKIND_VIEW)
|
||||||
{
|
{
|
||||||
@ -493,7 +507,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* close pg_attribute indices
|
* clean up
|
||||||
*/
|
*/
|
||||||
if (hasindex)
|
if (hasindex)
|
||||||
CatalogCloseIndices(Num_pg_attr_indices, idescs);
|
CatalogCloseIndices(Num_pg_attr_indices, idescs);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.49 2002/06/20 20:29:26 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.50 2002/07/16 22:12:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_aggregate.h"
|
#include "catalog/pg_aggregate.h"
|
||||||
@ -53,6 +54,8 @@ AggregateCreate(const char *aggName,
|
|||||||
Oid procOid;
|
Oid procOid;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
int i;
|
int i;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if (!aggName)
|
if (!aggName)
|
||||||
@ -187,4 +190,29 @@ AggregateCreate(const char *aggName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
heap_close(aggdesc, RowExclusiveLock);
|
heap_close(aggdesc, RowExclusiveLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create dependencies for the aggregate (above and beyond those
|
||||||
|
* already made by ProcedureCreate). Note: we don't need an explicit
|
||||||
|
* dependency on aggTransType since we depend on it indirectly through
|
||||||
|
* transfn.
|
||||||
|
*/
|
||||||
|
myself.classId = RelOid_pg_proc;
|
||||||
|
myself.objectId = procOid;
|
||||||
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
|
/* Depends on transition function */
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = transfn;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
|
/* Depends on final function, if any */
|
||||||
|
if (OidIsValid(finalfn))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = finalfn;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.2 2002/07/16 05:53:33 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.3 2002/07/16 22:12:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -198,17 +198,11 @@ CreateConstraintEntry(const char *constraintName,
|
|||||||
if (OidIsValid(foreignRelId))
|
if (OidIsValid(foreignRelId))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Register dependency from constraint to foreign relation,
|
* Register normal dependency from constraint to foreign relation,
|
||||||
* or to specific column(s) if any are mentioned.
|
* or to specific column(s) if any are mentioned.
|
||||||
*
|
|
||||||
* In normal case of two separate relations, make this a NORMAL
|
|
||||||
* dependency (so dropping the FK table would require CASCADE).
|
|
||||||
* However, for a self-reference just make it AUTO.
|
|
||||||
*/
|
*/
|
||||||
DependencyType deptype;
|
|
||||||
ObjectAddress relobject;
|
ObjectAddress relobject;
|
||||||
|
|
||||||
deptype = (foreignRelId == relId) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL;
|
|
||||||
relobject.classId = RelOid_pg_class;
|
relobject.classId = RelOid_pg_class;
|
||||||
relobject.objectId = foreignRelId;
|
relobject.objectId = foreignRelId;
|
||||||
if (foreignNKeys > 0)
|
if (foreignNKeys > 0)
|
||||||
@ -217,14 +211,14 @@ CreateConstraintEntry(const char *constraintName,
|
|||||||
{
|
{
|
||||||
relobject.objectSubId = foreignKey[i];
|
relobject.objectSubId = foreignKey[i];
|
||||||
|
|
||||||
recordDependencyOn(&conobject, &relobject, deptype);
|
recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
relobject.objectSubId = 0;
|
relobject.objectSubId = 0;
|
||||||
|
|
||||||
recordDependencyOn(&conobject, &relobject, deptype);
|
recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.2 2002/07/16 05:53:33 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.3 2002/07/16 22:12:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -121,6 +121,43 @@ recordMultipleDependencies(const ObjectAddress *depender,
|
|||||||
heap_close(dependDesc, RowExclusiveLock);
|
heap_close(dependDesc, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* deleteDependencyRecordsFor -- delete all records with given depender
|
||||||
|
* classId/objectId.
|
||||||
|
*
|
||||||
|
* This is used when redefining an existing object. Links leading to the
|
||||||
|
* object do not change, and links leading from it will be recreated
|
||||||
|
* (possibly with some differences from before).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
deleteDependencyRecordsFor(Oid classId, Oid objectId)
|
||||||
|
{
|
||||||
|
Relation depRel;
|
||||||
|
ScanKeyData key[2];
|
||||||
|
SysScanDesc scan;
|
||||||
|
HeapTuple tup;
|
||||||
|
|
||||||
|
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
ScanKeyEntryInitialize(&key[0], 0x0,
|
||||||
|
Anum_pg_depend_classid, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(classId));
|
||||||
|
ScanKeyEntryInitialize(&key[1], 0x0,
|
||||||
|
Anum_pg_depend_objid, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(objectId));
|
||||||
|
|
||||||
|
scan = systable_beginscan(depRel, DependDependerIndex, true,
|
||||||
|
SnapshotNow, 2, key);
|
||||||
|
|
||||||
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
simple_heap_delete(depRel, &tup->t_self);
|
||||||
|
}
|
||||||
|
|
||||||
|
systable_endscan(scan);
|
||||||
|
|
||||||
|
heap_close(depRel, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* isObjectPinned()
|
* isObjectPinned()
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.70 2002/06/20 20:29:26 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.71 2002/07/16 22:12:18 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* these routines moved here from commands/define.c and somewhat cleaned up.
|
* these routines moved here from commands/define.c and somewhat cleaned up.
|
||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
@ -56,6 +57,8 @@ static Oid get_other_operator(List *otherOp,
|
|||||||
Oid leftTypeId, Oid rightTypeId,
|
Oid leftTypeId, Oid rightTypeId,
|
||||||
bool isCommutator);
|
bool isCommutator);
|
||||||
|
|
||||||
|
static void makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether a proposed operator name is legal
|
* Check whether a proposed operator name is legal
|
||||||
@ -271,6 +274,9 @@ OperatorShellMake(const char *operatorName,
|
|||||||
CatalogCloseIndices(Num_pg_operator_indices, idescs);
|
CatalogCloseIndices(Num_pg_operator_indices, idescs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add dependencies for the entry */
|
||||||
|
makeOperatorDependencies(tup, RelationGetRelid(pg_operator_desc));
|
||||||
|
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -659,6 +665,9 @@ OperatorCreate(const char *operatorName,
|
|||||||
CatalogCloseIndices(Num_pg_operator_indices, idescs);
|
CatalogCloseIndices(Num_pg_operator_indices, idescs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add dependencies for the entry */
|
||||||
|
makeOperatorDependencies(tup, RelationGetRelid(pg_operator_desc));
|
||||||
|
|
||||||
heap_close(pg_operator_desc, RowExclusiveLock);
|
heap_close(pg_operator_desc, RowExclusiveLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -893,3 +902,89 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
|
|||||||
|
|
||||||
heap_close(pg_operator_desc, RowExclusiveLock);
|
heap_close(pg_operator_desc, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create dependencies for a new operator (either a freshly inserted
|
||||||
|
* complete operator, a new shell operator, or a just-updated shell).
|
||||||
|
*
|
||||||
|
* NB: the OidIsValid tests in this routine are *all* necessary, in case
|
||||||
|
* the given operator is a shell.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid)
|
||||||
|
{
|
||||||
|
Form_pg_operator oper = (Form_pg_operator) GETSTRUCT(tuple);
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
|
myself.classId = pg_operator_relid;
|
||||||
|
myself.objectId = tuple->t_data->t_oid;
|
||||||
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
|
/* In case we are updating a shell, delete any existing entries */
|
||||||
|
deleteDependencyRecordsFor(myself.classId, myself.objectId);
|
||||||
|
|
||||||
|
/* Dependency on left type */
|
||||||
|
if (OidIsValid(oper->oprleft))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = oper->oprleft;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dependency on right type */
|
||||||
|
if (OidIsValid(oper->oprright))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = oper->oprright;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dependency on result type */
|
||||||
|
if (OidIsValid(oper->oprresult))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = oper->oprresult;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: we do not consider the operator to depend on the associated
|
||||||
|
* operators oprcom, oprnegate, oprlsortop, oprrsortop, oprltcmpop,
|
||||||
|
* oprgtcmpop. We would not want to delete this operator if those
|
||||||
|
* go away, but only reset the link fields; which is not a function
|
||||||
|
* that the dependency code can presently handle. (Something could
|
||||||
|
* perhaps be done with objectSubId though.) For now, it's okay to
|
||||||
|
* let those links dangle if a referenced operator is removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Dependency on implementation function */
|
||||||
|
if (OidIsValid(oper->oprcode))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = oper->oprcode;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dependency on restriction selectivity function */
|
||||||
|
if (OidIsValid(oper->oprrest))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = oper->oprrest;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dependency on join selectivity function */
|
||||||
|
if (OidIsValid(oper->oprjoin))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = oper->oprjoin;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.76 2002/06/20 20:29:26 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.77 2002/07/16 22:12:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_language.h"
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
@ -76,6 +77,9 @@ ProcedureCreate(const char *procedureName,
|
|||||||
NameData procname;
|
NameData procname;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
Oid retval;
|
Oid retval;
|
||||||
|
bool is_update;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sanity checks
|
* sanity checks
|
||||||
@ -227,6 +231,7 @@ ProcedureCreate(const char *procedureName,
|
|||||||
simple_heap_update(rel, &tup->t_self, tup);
|
simple_heap_update(rel, &tup->t_self, tup);
|
||||||
|
|
||||||
ReleaseSysCache(oldtup);
|
ReleaseSysCache(oldtup);
|
||||||
|
is_update = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -237,6 +242,7 @@ ProcedureCreate(const char *procedureName,
|
|||||||
|
|
||||||
tup = heap_formtuple(tupDesc, values, nulls);
|
tup = heap_formtuple(tupDesc, values, nulls);
|
||||||
simple_heap_insert(rel, tup);
|
simple_heap_insert(rel, tup);
|
||||||
|
is_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to update indices for either the insert or update case */
|
/* Need to update indices for either the insert or update case */
|
||||||
@ -250,6 +256,45 @@ ProcedureCreate(const char *procedureName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
retval = tup->t_data->t_oid;
|
retval = tup->t_data->t_oid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create dependencies for the new function. If we are updating an
|
||||||
|
* existing function, first delete any existing pg_depend entries.
|
||||||
|
*/
|
||||||
|
if (is_update)
|
||||||
|
deleteDependencyRecordsFor(RelOid_pg_proc, retval);
|
||||||
|
|
||||||
|
myself.classId = RelOid_pg_proc;
|
||||||
|
myself.objectId = retval;
|
||||||
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
|
/* dependency on implementation language */
|
||||||
|
referenced.classId = get_system_catalog_relid(LanguageRelationName);
|
||||||
|
referenced.objectId = languageObjectId;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
|
/* dependency on return type */
|
||||||
|
if (OidIsValid(returnType))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = returnType;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dependency on input types */
|
||||||
|
for (i = 0; i < parameterCount; i++)
|
||||||
|
{
|
||||||
|
if (OidIsValid(typev[i]))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = typev[i];
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
HeapTuple tup;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
int i;
|
int i;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check permission
|
* Check permission
|
||||||
@ -91,7 +93,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
NameListToString(stmt->plvalidator));
|
NameListToString(stmt->plvalidator));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
valProcOid = 0;
|
valProcOid = InvalidOid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert the new language into pg_language
|
* Insert the new language into pg_language
|
||||||
@ -128,6 +130,28 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
CatalogCloseIndices(Num_pg_language_indices, idescs);
|
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);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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->setof = FALSE;
|
||||||
typnam->arrayBounds = NIL;
|
typnam->arrayBounds = NIL;
|
||||||
typnam->typmod = -1;
|
typnam->typmod = -1;
|
||||||
|
|
||||||
coldef = makeNode(ColumnDef);
|
coldef = makeNode(ColumnDef);
|
||||||
coldef->typename = typnam;
|
coldef->typename = typnam;
|
||||||
|
coldef->is_not_null = true;
|
||||||
coldef->raw_default = NULL;
|
coldef->raw_default = NULL;
|
||||||
coldef->cooked_default = NULL;
|
coldef->cooked_default = NULL;
|
||||||
coldef->is_not_null = false;
|
coldef->constraints = NIL;
|
||||||
|
coldef->support = NULL;
|
||||||
|
|
||||||
null[i - 1] = ' ';
|
null[i - 1] = ' ';
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* So, the transformation has to be postponed to this final step of
|
||||||
* CREATE TABLE.
|
* 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.
|
* First, scan schema to find new column defaults.
|
||||||
*/
|
*/
|
||||||
rawDefaults = NIL;
|
rawDefaults = NIL;
|
||||||
@ -247,12 +251,13 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
foreach(listptr, schema)
|
foreach(listptr, schema)
|
||||||
{
|
{
|
||||||
ColumnDef *colDef = lfirst(listptr);
|
ColumnDef *colDef = lfirst(listptr);
|
||||||
RawColumnDefault *rawEnt;
|
|
||||||
|
|
||||||
attnum++;
|
attnum++;
|
||||||
|
|
||||||
if (colDef->raw_default == NULL)
|
if (colDef->raw_default != NULL)
|
||||||
continue;
|
{
|
||||||
|
RawColumnDefault *rawEnt;
|
||||||
|
|
||||||
Assert(colDef->cooked_default == NULL);
|
Assert(colDef->cooked_default == NULL);
|
||||||
|
|
||||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||||
@ -261,6 +266,22 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
rawDefaults = lappend(rawDefaults, rawEnt);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse and add the defaults/constraints, if any.
|
* Parse and add the defaults/constraints, if any.
|
||||||
*/
|
*/
|
||||||
@ -533,6 +554,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
|||||||
def->raw_default = NULL;
|
def->raw_default = NULL;
|
||||||
def->cooked_default = NULL;
|
def->cooked_default = NULL;
|
||||||
def->constraints = NIL;
|
def->constraints = NIL;
|
||||||
|
def->support = NULL;
|
||||||
inhSchema = lappend(inhSchema, def);
|
inhSchema = lappend(inhSchema, def);
|
||||||
newattno[parent_attno - 1] = ++child_attno;
|
newattno[parent_attno - 1] = ++child_attno;
|
||||||
}
|
}
|
||||||
@ -1524,6 +1546,8 @@ AlterTableAddColumn(Oid myrelid,
|
|||||||
HeapTuple typeTuple;
|
HeapTuple typeTuple;
|
||||||
Form_pg_type tform;
|
Form_pg_type tform;
|
||||||
int attndims;
|
int attndims;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab an exclusive lock on the target table, which we will NOT
|
* 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! */
|
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.
|
* Make our catalog updates visible for subsequent steps.
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -358,15 +358,18 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
char typtype;
|
char typtype;
|
||||||
Datum datum;
|
Datum datum;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
|
Node *defaultExpr = NULL;
|
||||||
char *defaultValue = NULL;
|
char *defaultValue = NULL;
|
||||||
char *defaultValueBin = NULL;
|
char *defaultValueBin = NULL;
|
||||||
bool typNotNull = false;
|
bool typNotNull = false;
|
||||||
|
bool nullDefined = false;
|
||||||
Oid basetypelem;
|
Oid basetypelem;
|
||||||
int32 typNDims = length(stmt->typename->arrayBounds);
|
int32 typNDims = length(stmt->typename->arrayBounds);
|
||||||
HeapTuple typeTup;
|
HeapTuple typeTup;
|
||||||
List *schema = stmt->constraints;
|
List *schema = stmt->constraints;
|
||||||
List *listptr;
|
List *listptr;
|
||||||
Oid basetypeoid;
|
Oid basetypeoid;
|
||||||
|
Oid domainoid;
|
||||||
Form_pg_type baseType;
|
Form_pg_type baseType;
|
||||||
|
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
@ -459,8 +462,6 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
foreach(listptr, schema)
|
foreach(listptr, schema)
|
||||||
{
|
{
|
||||||
Constraint *colDef = lfirst(listptr);
|
Constraint *colDef = lfirst(listptr);
|
||||||
bool nullDefined = false;
|
|
||||||
Node *expr;
|
|
||||||
ParseState *pstate;
|
ParseState *pstate;
|
||||||
|
|
||||||
switch (colDef->contype)
|
switch (colDef->contype)
|
||||||
@ -473,13 +474,15 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
* don't want to cook or fiddle too much.
|
* don't want to cook or fiddle too much.
|
||||||
*/
|
*/
|
||||||
case CONSTR_DEFAULT:
|
case CONSTR_DEFAULT:
|
||||||
|
if (defaultExpr)
|
||||||
|
elog(ERROR, "CREATE DOMAIN has multiple DEFAULT expressions");
|
||||||
/* Create a dummy ParseState for transformExpr */
|
/* Create a dummy ParseState for transformExpr */
|
||||||
pstate = make_parsestate(NULL);
|
pstate = make_parsestate(NULL);
|
||||||
/*
|
/*
|
||||||
* Cook the colDef->raw_expr into an expression.
|
* Cook the colDef->raw_expr into an expression.
|
||||||
* Note: Name is strictly for error message
|
* Note: Name is strictly for error message
|
||||||
*/
|
*/
|
||||||
expr = cookDefault(pstate, colDef->raw_expr,
|
defaultExpr = cookDefault(pstate, colDef->raw_expr,
|
||||||
basetypeoid,
|
basetypeoid,
|
||||||
stmt->typename->typmod,
|
stmt->typename->typmod,
|
||||||
domainName);
|
domainName);
|
||||||
@ -488,32 +491,28 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
* but we also require a valid textual representation
|
* but we also require a valid textual representation
|
||||||
* (mainly to make life easier for pg_dump).
|
* (mainly to make life easier for pg_dump).
|
||||||
*/
|
*/
|
||||||
defaultValue = deparse_expression(expr,
|
defaultValue = deparse_expression(defaultExpr,
|
||||||
deparse_context_for(domainName,
|
deparse_context_for(domainName,
|
||||||
InvalidOid),
|
InvalidOid),
|
||||||
false);
|
false);
|
||||||
defaultValueBin = nodeToString(expr);
|
defaultValueBin = nodeToString(defaultExpr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the NULL constraint.
|
* Find the NULL constraint.
|
||||||
*/
|
*/
|
||||||
case CONSTR_NOTNULL:
|
case CONSTR_NOTNULL:
|
||||||
if (nullDefined) {
|
if (nullDefined)
|
||||||
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
||||||
} else {
|
|
||||||
typNotNull = true;
|
typNotNull = true;
|
||||||
nullDefined = true;
|
nullDefined = true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONSTR_NULL:
|
case CONSTR_NULL:
|
||||||
if (nullDefined) {
|
if (nullDefined)
|
||||||
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
|
||||||
} else {
|
|
||||||
typNotNull = false;
|
typNotNull = false;
|
||||||
nullDefined = true;
|
nullDefined = true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONSTR_UNIQUE:
|
case CONSTR_UNIQUE:
|
||||||
@ -544,6 +543,7 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
/*
|
/*
|
||||||
* Have TypeCreate do all the real work.
|
* Have TypeCreate do all the real work.
|
||||||
*/
|
*/
|
||||||
|
domainoid =
|
||||||
TypeCreate(domainName, /* type name */
|
TypeCreate(domainName, /* type name */
|
||||||
domainNamespace, /* namespace */
|
domainNamespace, /* namespace */
|
||||||
InvalidOid, /* preassigned type oid (none here) */
|
InvalidOid, /* preassigned type oid (none here) */
|
||||||
@ -567,6 +567,21 @@ DefineDomain(CreateDomainStmt *stmt)
|
|||||||
typNDims, /* Array dimensions for base type */
|
typNDims, /* Array dimensions for base type */
|
||||||
typNotNull); /* Type NOT NULL */
|
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.
|
* Now we can clean up.
|
||||||
*/
|
*/
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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->raw_default = NULL;
|
||||||
def->cooked_default = NULL;
|
def->cooked_default = NULL;
|
||||||
def->constraints = NIL;
|
def->constraints = NIL;
|
||||||
|
def->support = NULL;
|
||||||
|
|
||||||
attrList = lappend(attrList, def);
|
attrList = lappend(attrList, def);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.193 2002/07/12 18:43:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.194 2002/07/16 22:12:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1749,6 +1749,7 @@ _copyColumnDef(ColumnDef *from)
|
|||||||
if (from->cooked_default)
|
if (from->cooked_default)
|
||||||
newnode->cooked_default = pstrdup(from->cooked_default);
|
newnode->cooked_default = pstrdup(from->cooked_default);
|
||||||
Node_Copy(from, newnode, constraints);
|
Node_Copy(from, newnode, constraints);
|
||||||
|
Node_Copy(from, newnode, support);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.140 2002/07/12 18:43:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.141 2002/07/16 22:12:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1636,6 +1636,8 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b)
|
|||||||
return false;
|
return false;
|
||||||
if (!equal(a->constraints, b->constraints))
|
if (!equal(a->constraints, b->constraints))
|
||||||
return false;
|
return false;
|
||||||
|
if (!equal(a->support, b->support))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.162 2002/07/12 18:43:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.163 2002/07/16 22:12:19 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every (plan) node in POSTGRES has an associated "out" routine which
|
* Every (plan) node in POSTGRES has an associated "out" routine which
|
||||||
@ -183,6 +183,8 @@ _outColumnDef(StringInfo str, ColumnDef *node)
|
|||||||
_outToken(str, node->cooked_default);
|
_outToken(str, node->cooked_default);
|
||||||
appendStringInfo(str, " :constraints ");
|
appendStringInfo(str, " :constraints ");
|
||||||
_outNode(str, node->constraints);
|
_outNode(str, node->constraints);
|
||||||
|
appendStringInfo(str, " :support ");
|
||||||
|
_outNode(str, node->support);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.238 2002/07/12 18:43:17 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.239 2002/07/16 22:12:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -847,6 +847,12 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
|
|||||||
|
|
||||||
cxt->blist = lappend(cxt->blist, seqstmt);
|
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.
|
||||||
|
*/
|
||||||
|
column->support = makeRangeVar(snamespace, sname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create appropriate constraints for SERIAL. We do this in full,
|
* Create appropriate constraints for SERIAL. We do this in full,
|
||||||
* rather than shortcutting, so that we will detect any
|
* rather than shortcutting, so that we will detect any
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.340 2002/07/14 23:38:13 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.341 2002/07/16 22:12:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -1852,10 +1852,11 @@ CreateAsElement:
|
|||||||
ColumnDef *n = makeNode(ColumnDef);
|
ColumnDef *n = makeNode(ColumnDef);
|
||||||
n->colname = $1;
|
n->colname = $1;
|
||||||
n->typename = NULL;
|
n->typename = NULL;
|
||||||
|
n->is_not_null = false;
|
||||||
n->raw_default = NULL;
|
n->raw_default = NULL;
|
||||||
n->cooked_default = NULL;
|
n->cooked_default = NULL;
|
||||||
n->is_not_null = FALSE;
|
n->constraints = NIL;
|
||||||
n->constraints = NULL;
|
n->support = NULL;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: dependency.h,v 1.2 2002/07/16 05:53:34 tgl Exp $
|
* $Id: dependency.h,v 1.3 2002/07/16 22:12:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -98,4 +98,6 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
|
|||||||
int nreferenced,
|
int nreferenced,
|
||||||
DependencyType behavior);
|
DependencyType behavior);
|
||||||
|
|
||||||
|
extern void deleteDependencyRecordsFor(Oid classId, Oid objectId);
|
||||||
|
|
||||||
#endif /* DEPENDENCY_H */
|
#endif /* DEPENDENCY_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: parsenodes.h,v 1.186 2002/07/14 23:38:13 tgl Exp $
|
* $Id: parsenodes.h,v 1.187 2002/07/16 22:12:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -269,6 +269,10 @@ typedef struct BooleanTest
|
|||||||
* parsetree produced by gram.y, but transformCreateStmt will remove
|
* parsetree produced by gram.y, but transformCreateStmt will remove
|
||||||
* the item and set raw_default instead. CONSTR_DEFAULT items
|
* the item and set raw_default instead. CONSTR_DEFAULT items
|
||||||
* should not appear in any subsequent processing.
|
* should not appear in any subsequent processing.
|
||||||
|
*
|
||||||
|
* The "support" field, if not null, denotes a supporting relation that
|
||||||
|
* should be linked by an internal dependency to the column. Currently
|
||||||
|
* this is only used to link a SERIAL column's sequence to the column.
|
||||||
*/
|
*/
|
||||||
typedef struct ColumnDef
|
typedef struct ColumnDef
|
||||||
{
|
{
|
||||||
@ -280,6 +284,7 @@ typedef struct ColumnDef
|
|||||||
* tree) */
|
* tree) */
|
||||||
char *cooked_default; /* nodeToString representation */
|
char *cooked_default; /* nodeToString representation */
|
||||||
List *constraints; /* other constraints on column */
|
List *constraints; /* other constraints on column */
|
||||||
|
RangeVar *support; /* supporting relation, if any */
|
||||||
} ColumnDef;
|
} ColumnDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user