YADP - Yet another Dependency Patch
This one has been corrected to fit in with Toms recent changes, as well
as the changes with command/ restructuring.
Please accept or reject quickly, else risk conflicts.
Attachments:
pg_depend.htext/x-c-header; charset=ISO-8859-1; name=pg_depend.hDownload
/*-------------------------------------------------------------------------
*
* pg_depend.h
* definition of the system "depend" relation (pg_depend)
* along with the relation's initial contents.
*
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header$
*
* NOTES
* the genbki.sh script reads this file and generates .bki
* information from theDATA() statements.
*
*-------------------------------------------------------------------------
*/
#ifndef PG_DEPEND_H
#define PG_DEPEND_H
/* ----------------
* postgres.h contains the system type definitions and the
* CATALOG(), BOOTSTRAP andDATA() sugar words so this file
* can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
* pg_depend definition. cpp turns this into
* typedef struct FormData_pg_depend
* ----------------
*/
CATALOG(pg_depend) BOOTSTRAP BKI_WITHOUT_OIDS
{
Oid classid; /* OID of table containing object */
Oid objid; /* OID of object itself */
int4 objsubid; /* column number, or 0 if not used */
Oid depclassid; /* OID of table containing dependee object */
Oid depobjid; /* OID of dependee object itself */
int4 depobjsubid; /* dependee column number, or 0 if not used */
/*
* Always cascade to the item, even when the RESTRICT behavior has been
* specified. Used primarily for SERIAL, and ARRAY types.
*/
bool alwayscascade;
} FormData_pg_depend;
/* ----------------
* Form_pg_depend corresponds to a pointer to a row with
* the format of pg_depend relation.
* ----------------
*/
typedef FormData_pg_depend *Form_pg_depend;
/* ----------------
* compiler constants for pg_depend
* ----------------
*/
#define Natts_pg_depend 7
#define Anum_pg_depend_classid 1
#define Anum_pg_depend_objid 2
#define Anum_pg_depend_objsubid 3
#define Anum_pg_depend_depclassid 4
#define Anum_pg_depend_depobjid 5
#define Anum_pg_depend_depobjsubid 6
#define Anum_pg_depend_alwayscascade 7
/*
* Dependencies are automatically discovered in the initdb.sh
* script via a rather large query.
*
* If you modify any system relations, be sure to modify that
* query.
*/
/* ----------------
* pg_type depends on Functions
* ----------------
**********************
***********************/
/* ----------------
* pg_attribute depends on pg_class
* ----------------
*/
/* ----------------
* pg_class depends on Complex Types (table types)
* ----------------
*/
/* ----------------
* pg_class depends on index access methods (pg_am)
* ----------------
*/
/* ----------------
* more...
* ----------------
*/
typedef struct ObjectAddress
{
Oid classId; /* Class Id from pg_class */
Oid objectId; /* OID of the object */
int32 objectSubId; /* Subitem within the object (column of table) */
} ObjectAddress;
extern void dependCreate(const ObjectAddress *depender,
const ObjectAddress *dependee, bool behavior);
extern void dependDelete(ObjectAddress *object, int behavior);
extern void dependDeleteTuple(const HeapTuple tup,
const Relation relation,
int behavior);
#endif /* PG_DEPEND_H */
depend.patch2text/plain; charset=ISO-8859-1; name=depend.patch2Download
? GNUmakefile
? config.log
? config.status
? src/Makefile.global
? src/backend/catalog/pg_depend.c
? src/bin/pg_passwd/pg_passwd
? src/include/pg_config.h
? src/include/stamp-h
? src/include/catalog/pg_depend.h
Index: src/backend/catalog/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v
retrieving revision 1.39
diff -c -r1.39 Makefile
*** src/backend/catalog/Makefile 2002/03/26 19:15:22 1.39
--- src/backend/catalog/Makefile 2002/04/15 12:22:22
***************
*** 12,18 ****
OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_largeobject.o pg_namespace.o \
! pg_operator.o pg_proc.o pg_type.o
BKIFILES = postgres.bki postgres.description
--- 12,18 ----
OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_largeobject.o pg_namespace.o \
! pg_operator.o pg_proc.o pg_type.o pg_depend.o
BKIFILES = postgres.bki postgres.description
***************
*** 26,32 ****
# indexing.h had better be last.
POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
! pg_proc.h pg_type.h pg_attribute.h pg_class.h \
pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
--- 26,32 ----
# indexing.h had better be last.
POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
! pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_depend.h \
pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
Index: src/backend/catalog/heap.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/heap.c,v
retrieving revision 1.196
diff -c -r1.196 heap.c
*** src/backend/catalog/heap.c 2002/04/12 20:38:18 1.196
--- src/backend/catalog/heap.c 2002/04/15 12:22:24
***************
*** 37,42 ****
--- 37,43 ----
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/pg_attrdef.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_relcheck.h"
#include "catalog/pg_statistic.h"
***************
*** 49,54 ****
--- 50,57 ----
#include "optimizer/planmain.h"
#include "optimizer/prep.h"
#include "optimizer/var.h"
+ #include "parser/parse.h" /* For keyword RESTRICT */
+ #include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
***************
*** 68,75 ****
char relkind, bool relhasoids);
static void DeleteAttributeTuples(Relation rel);
static void DeleteRelationTuple(Relation rel);
- static void DeleteTypeTuple(Relation rel);
- static void RelationRemoveIndexes(Relation relation);
static void RelationRemoveInheritance(Relation relation);
static void AddNewRelationType(const char *typeName,
Oid typeNamespace,
--- 71,76 ----
***************
*** 253,258 ****
--- 254,264 ----
nailme = true;
relid = RelOid_pg_proc;
}
+ else if (strcmp(DependRelationName, relname) == 0)
+ {
+ nailme = true;
+ relid = RelOid_pg_depend;
+ }
else if (strcmp(RelationRelationName, relname) == 0)
{
nailme = true;
***************
*** 415,420 ****
--- 421,428 ----
bool hasindex;
Relation idescs[Num_pg_attr_indices];
int natts = tupdesc->natts;
+ ObjectAddress myself,
+ dependee;
/*
* open pg_attribute
***************
*** 428,433 ****
--- 436,446 ----
if (hasindex)
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
+ /* Prep Static dependency values */
+ myself.classId = RelOid_pg_class;
+ myself.objectId = new_rel_oid;
+ dependee.classId = RelOid_pg_type;
+
/*
* first we add the user attributes..
*/
***************
*** 449,454 ****
--- 462,475 ----
if (hasindex)
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
+ /* Register Dependencies */
+ myself.objectSubId = (*dpp)->attnum;
+
+ dependee.objectId = (*dpp)->atttypid;
+ dependee.objectSubId = 0;
+
+ dependCreate(&myself, &dependee, false);
+
heap_freetuple(tup);
dpp++;
}
***************
*** 485,490 ****
--- 506,522 ----
heap_freetuple(tup);
}
+
+ /* Add Oid type dependency for Oid column*/
+ if (relhasoids && (*dpp)->attnum == ObjectIdAttributeNumber) {
+ myself.objectSubId = (*dpp)->attnum;
+
+ dependee.objectId = (*dpp)->atttypid;
+ dependee.objectSubId = 0;
+
+ dependCreate(&myself, &dependee, false);
+ }
+
dpp++;
}
***************
*** 822,848 ****
heap_close(catalogRelation, RowExclusiveLock);
}
- /*
- * RelationRemoveIndexes
- */
- static void
- RelationRemoveIndexes(Relation relation)
- {
- List *indexoidlist,
- *indexoidscan;
-
- indexoidlist = RelationGetIndexList(relation);
-
- foreach(indexoidscan, indexoidlist)
- {
- Oid indexoid = lfirsti(indexoidscan);
-
- index_drop(indexoid);
- }
-
- freeList(indexoidlist);
- }
-
/* --------------------------------
* DeleteRelationTuple
*
--- 854,859 ----
***************
*** 1036,1161 ****
heap_close(pg_attribute_desc, RowExclusiveLock);
}
- /* --------------------------------
- * DeleteTypeTuple
- *
- * If the user attempts to destroy a relation and there
- * exists attributes in other relations of type
- * "relation we are deleting", then we have to do something
- * special. presently we disallow the destroy.
- * --------------------------------
- */
- static void
- DeleteTypeTuple(Relation rel)
- {
- Relation pg_type_desc;
- HeapScanDesc pg_type_scan;
- Relation pg_attribute_desc;
- HeapScanDesc pg_attribute_scan;
- ScanKeyData key;
- ScanKeyData attkey;
- HeapTuple tup;
- HeapTuple atttup;
- Oid typoid;
-
- /*
- * open pg_type
- */
- pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
-
- /*
- * create a scan key to locate the type tuple corresponding to this
- * relation.
- */
- ScanKeyEntryInitialize(&key, 0,
- Anum_pg_type_typrelid,
- F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(rel)));
-
- pg_type_scan = heap_beginscan(pg_type_desc,
- 0,
- SnapshotNow,
- 1,
- &key);
-
- /*
- * use heap_getnext() to fetch the pg_type tuple. If this tuple is
- * not valid then something's wrong.
- */
- tup = heap_getnext(pg_type_scan, 0);
-
- if (!HeapTupleIsValid(tup))
- {
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc, RowExclusiveLock);
- elog(ERROR, "DeleteTypeTuple: type \"%s\" does not exist",
- RelationGetRelationName(rel));
- }
-
- /*
- * now scan pg_attribute. if any other relations have attributes of
- * the type of the relation we are deleteing then we have to disallow
- * the deletion. should talk to stonebraker about this. -cim 6/19/90
- */
- typoid = tup->t_data->t_oid;
-
- pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
-
- ScanKeyEntryInitialize(&attkey,
- 0,
- Anum_pg_attribute_atttypid,
- F_OIDEQ,
- ObjectIdGetDatum(typoid));
-
- pg_attribute_scan = heap_beginscan(pg_attribute_desc,
- 0,
- SnapshotNow,
- 1,
- &attkey);
-
- /*
- * try and get a pg_attribute tuple. if we succeed it means we can't
- * delete the relation because something depends on the schema.
- */
- atttup = heap_getnext(pg_attribute_scan, 0);
-
- if (HeapTupleIsValid(atttup))
- {
- Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
-
- heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc, RowExclusiveLock);
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc, RowExclusiveLock);
-
- elog(ERROR, "DeleteTypeTuple: column of type %s exists in relation %u",
- RelationGetRelationName(rel), relid);
- }
- heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc, RowExclusiveLock);
-
- /*
- * Ok, it's safe so we delete the relation tuple from pg_type and
- * finish up.
- */
- simple_heap_delete(pg_type_desc, &tup->t_self);
-
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc, RowExclusiveLock);
- }
/* ----------------------------------------------------------------
* heap_drop_with_catalog - removes all record of named relation from catalogs
*
* 1) open relation, check for existence, etc.
* 2) remove inheritance information
! * 3) remove indexes
* 4) remove pg_class tuple
* 5) remove pg_attribute tuples and related descriptions
* 6) remove pg_description tuples
! * 7) remove pg_type tuples
! * 8) RemoveConstraints ()
! * 9) unlink relation
*
* old comments
* Except for vital relations, removes relation from
--- 1047,1064 ----
heap_close(pg_attribute_desc, RowExclusiveLock);
}
/* ----------------------------------------------------------------
* heap_drop_with_catalog - removes all record of named relation from catalogs
*
* 1) open relation, check for existence, etc.
* 2) remove inheritance information
! * 3) remove dependencies
* 4) remove pg_class tuple
* 5) remove pg_attribute tuples and related descriptions
* 6) remove pg_description tuples
! * 7) RemoveConstraints ()
! * 8) unlink relation
*
* old comments
* Except for vital relations, removes relation from
***************
*** 1180,1186 ****
{
Relation rel;
Oid toasttableOid;
! int i;
/*
* Open and lock the relation.
--- 1083,1091 ----
{
Relation rel;
Oid toasttableOid;
! int i, natts;
! ObjectAddress myself;
! HeapTuple tuple;
/*
* Open and lock the relation.
***************
*** 1205,1229 ****
elog(ERROR, "heap_drop_with_catalog: FlushRelationBuffers returned %d",
i);
/*
! * remove rules if necessary
*/
! if (rel->rd_rules != NULL)
! RelationRemoveRules(rid);
! /* triggers */
! RelationRemoveTriggers(rel);
/*
! * remove inheritance information
*/
! RelationRemoveInheritance(rel);
/*
! * remove indexes if necessary
*/
! RelationRemoveIndexes(rel);
/*
* delete attribute tuples
*/
--- 1110,1160 ----
elog(ERROR, "heap_drop_with_catalog: FlushRelationBuffers returned %d",
i);
+ /*
+ * remove inheritance information
+ */
+ RelationRemoveInheritance(rel);
+
/*
! * Deal with dependencies
! *
! * Take care of any attributes first, then the main object
! * last when objectSubId = 0. Ignore system attributes.
*/
! tuple = SearchSysCache(RELOID, rid, 0, 0, 0);
! if (!HeapTupleIsValid(tuple))
! elog(ERROR, "Relation %s doesn't exist", RelationGetRelationName(rel));
! natts = ((Form_pg_class) GETSTRUCT(tuple))->relnatts;
!
! /* Must free before calling dependDelete */
! ReleaseSysCache(tuple);
/*
! * Drop in decending order so the table is handled after all
! * of its columns.
! *
! * Oid first due to abilities like Primary Key on Oid. This is
! * done whether it has oids or not.
*/
! myself.classId = RelOid_pg_class;
! myself.objectId = rid;
/*
! * Delete depends on Oid regardless of whether
! * the relation has Oids or not. End with the
! * relation itself.
*/
! myself.objectSubId = ObjectIdAttributeNumber;
! dependDelete(&myself, RESTRICT);
!
! for (i = natts; i >= 0; i--)
! {
! myself.objectSubId = i;
! dependDelete(&myself, RESTRICT);
! }
+
/*
* delete attribute tuples
*/
***************
*** 1236,1247 ****
RemoveStatistics(rel);
- RemoveConstraints(rel);
-
/*
! * delete type tuple
*/
! DeleteTypeTuple(rel);
/*
* delete relation tuple
--- 1167,1178 ----
RemoveStatistics(rel);
/*
! * Remove constraints if necessary
! *
! * Should be updated to use pg_depend methods
*/
! RemoveConstraints(rel);
/*
* delete relation tuple
Index: src/backend/catalog/index.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.176
diff -c -r1.176 index.c
*** src/backend/catalog/index.c 2002/04/12 20:38:19 1.176
--- src/backend/catalog/index.c 2002/04/15 12:22:27
***************
*** 32,37 ****
--- 32,39 ----
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_class.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_index.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_proc.h"
***************
*** 41,46 ****
--- 43,49 ----
#include "miscadmin.h"
#include "optimizer/clauses.h"
#include "optimizer/prep.h"
+ #include "parser/parse.h" /* For keyword RESTRICT */
#include "parser/parse_func.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
***************
*** 563,568 ****
--- 566,573 ----
TupleDesc indexTupDesc;
Oid namespaceId;
Oid indexoid;
+ ObjectAddress myself;
+ int i;
SetReindexProcessing(false);
***************
*** 598,604 ****
else
indexTupDesc = ConstructTupleDescriptor(heapRelation,
indexInfo->ii_NumKeyAttrs,
! indexInfo->ii_KeyAttrNumbers,
classObjectId);
/*
--- 603,609 ----
else
indexTupDesc = ConstructTupleDescriptor(heapRelation,
indexInfo->ii_NumKeyAttrs,
! indexInfo->ii_KeyAttrNumbers,
classObjectId);
/*
***************
*** 632,637 ****
--- 637,670 ----
*/
UpdateRelationRelation(indexRelation);
+ myself.classId = RelOid_pg_class;
+ myself.objectId = indexoid;
+ myself.objectSubId = 0;
+
+ /* Store dependencies on the attributes */
+ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+ {
+ ObjectAddress dependee;
+
+ dependee.classId = RelOid_pg_class;
+ dependee.objectId = heapRelationId;
+ dependee.objectSubId = indexInfo->ii_KeyAttrNumbers[i];
+
+ /* We always cascade index drops with attribute drops */
+ dependCreate(&myself, &dependee, true);
+ }
+
+ /* Store the dependency on the function (if appropriate) */
+ if (OidIsValid(indexInfo->ii_FuncOid)) {
+ ObjectAddress dependee;
+
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = indexInfo->ii_FuncOid;
+ dependee.objectSubId = 0;
+
+ dependCreate(&myself, &dependee, false);
+ }
+
/*
* We create the disk file for this relation here
*/
***************
*** 711,716 ****
--- 744,751 ----
HeapTuple tuple;
int16 attnum;
int i;
+
+ ObjectAddress myself;
Assert(OidIsValid(indexId));
***************
*** 820,825 ****
--- 855,865 ----
heap_close(userHeapRelation, NoLock);
RelationForgetRelation(indexId);
+
+ myself.classId = RelOid_pg_class;
+ myself.objectId = indexId;
+ myself.objectSubId = 0;
+ dependDelete(&myself, RESTRICT);
}
/* ----------------------------------------------------------------
Index: src/backend/catalog/namespace.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/namespace.c,v
retrieving revision 1.8
diff -c -r1.8 namespace.c
*** src/backend/catalog/namespace.c 2002/04/12 20:38:19 1.8
--- src/backend/catalog/namespace.c 2002/04/15 12:22:28
***************
*** 567,572 ****
--- 567,598 ----
}
/*
+ * namespaceIdGetNspname
+ * Fetch the namespace name by the namespace OID
+ */
+ char *
+ namespaceIdGetNspname(Oid namespaceId)
+ {
+ char *schemaname;
+ HeapTuple tup;
+
+ tup = SearchSysCache(NAMESPACEOID,
+ namespaceId,
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) {
+ elog(ERROR, "namespaceIdGetName(): NamespaceId %d does not exist.",
+ namespaceId);
+ }
+
+ schemaname = NameStr(((Form_pg_namespace) GETSTRUCT(tup))->nspname);
+
+ ReleaseSysCache(tup);
+
+ return(schemaname);
+ }
+
+ /*
* NameListToString
* Utility routine to convert a qualified-name list into a string.
* Used primarily to form error messages.
Index: src/backend/catalog/pg_aggregate.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v
retrieving revision 1.44
diff -c -r1.44 pg_aggregate.c
*** src/backend/catalog/pg_aggregate.c 2002/04/11 19:59:57 1.44
--- src/backend/catalog/pg_aggregate.c 2002/04/15 12:22:28
***************
*** 19,24 ****
--- 19,26 ----
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_aggregate.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "optimizer/cost.h"
***************
*** 54,59 ****
--- 56,63 ----
Oid procOid;
TupleDesc tupDesc;
int i;
+ ObjectAddress myself,
+ dependee;
/* sanity checks */
if (!aggName)
***************
*** 186,190 ****
--- 190,221 ----
CatalogCloseIndices(Num_pg_aggregate_indices, idescs);
}
+ /* Define Dependencies */
+ myself.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(AggregateRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ myself.objectId = tup->t_data->t_oid;
+ myself.objectSubId = 0;
+
+ /* Depends on transition function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtransfn - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Depends on final function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggfinalfn - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Depends on final transition type */
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtranstype - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Cleanup */
heap_close(aggdesc, RowExclusiveLock);
}
Index: src/backend/catalog/pg_operator.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_operator.c,v
retrieving revision 1.65
diff -c -r1.65 pg_operator.c
*** src/backend/catalog/pg_operator.c 2002/04/09 20:35:47 1.65
--- src/backend/catalog/pg_operator.c 2002/04/15 12:22:29
***************
*** 20,25 ****
--- 20,27 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
***************
*** 406,411 ****
--- 408,416 ----
int i,
j;
+ ObjectAddress myself,
+ dependee;
+
/*
* validate operator name
*/
***************
*** 683,688 ****
--- 688,789 ----
CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup);
CatalogCloseIndices(Num_pg_operator_indices, idescs);
+ }
+
+ /* Load our object address */
+ myself.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(OperatorRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ myself.objectId = operatorObjectId;
+ myself.objectSubId = 0;
+
+ /* Dependency on left type */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on right type */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprright - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprright - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on result type */
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprresult - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Dependency on commutator */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]) != InvalidOid) {
+ dependee.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(OperatorRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on negator */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]) != InvalidOid) {
+ dependee.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(OperatorRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on sort left hand operator */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ dependee.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(OperatorRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprlsortop - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on sort right hand operator */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]) != InvalidOid) {
+ dependee.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(OperatorRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on implementation function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcode - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Dependency on restriction selectivity function */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrest - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ /* Dependency on join selectifity function */
+ if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
}
heap_close(pg_operator_desc, RowExclusiveLock);
Index: src/backend/catalog/pg_proc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_proc.c,v
retrieving revision 1.70
diff -c -r1.70 pg_proc.c
*** src/backend/catalog/pg_proc.c 2002/04/11 19:59:57 1.70
--- src/backend/catalog/pg_proc.c 2002/04/15 12:22:31
***************
*** 17,23 ****
--- 17,25 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_language.h"
+ #include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "miscadmin.h"
***************
*** 73,78 ****
--- 75,83 ----
TupleDesc tupDesc;
Oid retval;
+ ObjectAddress myself,
+ dependee;
+
/*
* sanity checks
*/
***************
*** 312,317 ****
--- 317,358 ----
}
retval = tup->t_data->t_oid;
+
+ /* Record Dependencies */
+ myself.classId = RelOid_pg_proc;
+ myself.objectId = retval;
+ myself.objectSubId = 0;
+
+ /* Procedure on Language */
+ dependee.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(LanguageRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ dependee.objectId = languageObjectId;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Return Type */
+ if (returnType != InvalidOid)
+ {
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = returnType;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+
+ for (i = 0; i < parameterCount; i++)
+ {
+ /* Parameter Types */
+ if (typev[i] != InvalidOid)
+ {
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = typev[i];
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+ }
+ }
+
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
Index: src/backend/catalog/pg_type.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_type.c,v
retrieving revision 1.70
diff -c -r1.70 pg_type.c
*** src/backend/catalog/pg_type.c 2002/03/29 19:06:02 1.70
--- src/backend/catalog/pg_type.c 2002/04/15 12:22:31
***************
*** 17,22 ****
--- 17,23 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/builtins.h"
***************
*** 167,172 ****
--- 168,175 ----
NameData name;
TupleDesc tupDesc;
int i;
+ ObjectAddress myself,
+ dependee;
/*
* validate size specifications: either positive (fixed-length) or -1
***************
*** 299,304 ****
--- 302,363 ----
CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
CatalogCloseIndices(Num_pg_type_indices, idescs);
+ }
+
+ /*
+ * Create dependencies
+ */
+
+ /* Load our object address */
+ myself.classId = RelOid_pg_type;
+ myself.objectId = typeObjectId;
+ myself.objectSubId = 0;
+
+ /* Dependency on the input function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typinput - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Dependency on the output function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typoutput - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Dependency on the receive function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typreceive - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* Dependency on the send function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typsend - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /*
+ * Dependency on the relation for complex types. Assume it's for
+ * a relation of somekind and drop it when the relation is removed.
+ */
+ if (DatumGetObjectId(values[Anum_pg_type_typrelid - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_class;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typrelid - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, true);
+ }
+
+ /*
+ * Dependency on the element Id for arrays. We can assume that it's for
+ * an array and that we should always cascade into this type when the base
+ * type is being removed.
+ */
+ if (DatumGetObjectId(values[Anum_pg_type_typelem - 1]) != InvalidOid) {
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typelem - 1]);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, true);
}
/*
Index: src/backend/commands/aggregatecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v
retrieving revision 1.1
diff -c -r1.1 aggregatecmds.c
*** src/backend/commands/aggregatecmds.c 2002/04/15 05:22:03 1.1
--- src/backend/commands/aggregatecmds.c 2002/04/15 12:22:31
***************
*** 26,34 ****
--- 26,36 ----
#include "catalog/catname.h"
#include "catalog/namespace.h"
#include "catalog/pg_aggregate.h"
+ #include "catalog/pg_depend.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
+ #include "parser/parse.h" /* For RESTRICT */
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
***************
*** 179,184 ****
--- 181,189 ----
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveAggregate: couldn't find pg_proc tuple for %s",
NameListToString(aggName));
+
+ /* Deal with dependencies */
+ dependDeleteTuple(tup, relation, RESTRICT);
/* Delete any comments associated with this function */
DeleteComments(procOid, RelationGetRelid(relation));
Index: src/backend/commands/functioncmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/functioncmds.c,v
retrieving revision 1.1
diff -c -r1.1 functioncmds.c
*** src/backend/commands/functioncmds.c 2002/04/15 05:22:03 1.1
--- src/backend/commands/functioncmds.c 2002/04/15 12:22:33
***************
*** 34,39 ****
--- 34,40 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
***************
*** 41,46 ****
--- 42,48 ----
#include "commands/defrem.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
+ #include "parser/parse.h" /* For RESTRICT */
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
***************
*** 419,424 ****
--- 421,429 ----
elog(WARNING, "Removing built-in function \"%s\"",
NameListToString(functionName));
}
+
+ /* Deal with dependencies */
+ dependDeleteTuple(tup, relation, RESTRICT);
/* Delete any comments associated with this function */
DeleteComments(funcOid, RelationGetRelid(relation));
Index: src/backend/commands/operatorcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/operatorcmds.c,v
retrieving revision 1.1
diff -c -r1.1 operatorcmds.c
*** src/backend/commands/operatorcmds.c 2002/04/15 05:22:03 1.1
--- src/backend/commands/operatorcmds.c 2002/04/15 12:22:33
***************
*** 37,46 ****
--- 37,48 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_operator.h"
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
+ #include "parser/parse.h" /* For RESTRICT */
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/syscache.h"
***************
*** 214,219 ****
--- 216,224 ----
if (!pg_oper_ownercheck(tup->t_data->t_oid, GetUserId()))
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName);
+
+ /* Deal with dependencies */
+ dependDeleteTuple(tup, relation, RESTRICT);
/* Delete any comments associated with this operator */
DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
Index: src/backend/commands/proclang.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/proclang.c,v
retrieving revision 1.31
diff -c -r1.31 proclang.c
*** src/backend/commands/proclang.c 2002/04/15 05:22:03 1.31
--- src/backend/commands/proclang.c 2002/04/15 12:22:33
***************
*** 18,23 ****
--- 18,24 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
***************
*** 25,30 ****
--- 26,32 ----
#include "commands/defrem.h"
#include "fmgr.h"
#include "miscadmin.h"
+ #include "parser/parse.h" /* For keyword RESTRICT */
#include "parser/parse_func.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
***************
*** 48,53 ****
--- 50,58 ----
TupleDesc tupDesc;
int i;
+ ObjectAddress myself,
+ dependee;
+
/*
* Check permission
*/
***************
*** 79,84 ****
--- 84,94 ----
elog(ERROR, "PL handler function %s() isn't of return type Opaque",
NameListToString(stmt->plhandler));
+ /* Address of the PL handler function */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = procOid;
+ dependee.objectSubId = 0;
+
/*
* Insert the new language into pg_language
*/
***************
*** 113,118 ****
--- 123,136 ----
CatalogCloseIndices(Num_pg_language_indices, idescs);
}
+ /* Address of myself */
+ myself.classId = RelationGetRelid(rel);
+ myself.objectId = tup->t_data->t_oid;
+ myself.objectSubId = 0;
+
+ /* Create dependency on the language PL Handler function */
+ dependCreate(&myself, &dependee, false);
+
heap_close(rel, RowExclusiveLock);
}
***************
*** 152,157 ****
--- 170,178 ----
if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl)
elog(ERROR, "Language %s isn't a created procedural language",
languageName);
+
+ /* Deal with Dependencies */
+ dependDeleteTuple(langTup, rel, RESTRICT);
simple_heap_delete(rel, &langTup->t_self);
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.1
diff -c -r1.1 tablecmds.c
*** src/backend/commands/tablecmds.c 2002/04/15 05:22:03 1.1
--- src/backend/commands/tablecmds.c 2002/04/15 12:22:35
***************
*** 23,28 ****
--- 23,29 ----
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_attrdef.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
***************
*** 126,132 ****
HeapTuple typeTuple;
Form_pg_type tform;
int attndims;
!
/*
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
--- 127,134 ----
HeapTuple typeTuple;
Form_pg_type tform;
int attndims;
! ObjectAddress myself,
! dependee;
/*
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
***************
*** 262,267 ****
--- 264,279 ----
ReleaseSysCache(typeTuple);
heap_insert(attrdesc, attributeTuple);
+
+ /* Register Dependencies */
+ myself.classId = RelOid_pg_class;
+ myself.objectId = attribute->attrelid;
+ myself.objectSubId = attribute->attnum;
+
+ dependee.classId = RelOid_pg_type;
+ dependee.objectId = attribute->atttypid;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
/* Update indexes on pg_attribute */
if (RelationGetForm(attrdesc)->relhasindex)
Index: src/backend/commands/trigger.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.113
diff -c -r1.113 trigger.c
*** src/backend/commands/trigger.c 2002/04/12 20:38:24 1.113
--- src/backend/commands/trigger.c 2002/04/15 12:22:39
***************
*** 18,23 ****
--- 18,24 ----
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
***************
*** 26,31 ****
--- 27,33 ----
#include "commands/trigger.h"
#include "executor/executor.h"
#include "miscadmin.h"
+ #include "parser/parse.h" /* For keyword RESTRICT */
#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/builtins.h"
***************
*** 73,78 ****
--- 75,83 ----
char constrtrigname[NAMEDATALEN];
char *constrname = "";
Oid constrrelid = InvalidOid;
+ Oid insertOid, insertTupOid;
+ ObjectAddress myself,
+ dependee;
rel = heap_openrv(stmt->relation, AccessExclusiveLock);
***************
*** 260,265 ****
--- 265,272 ----
tuple = heap_formtuple(tgrel->rd_att, values, nulls);
+ insertOid = tgrel->rd_id;
+
/*
* Insert tuple into pg_trigger.
*/
***************
*** 267,272 ****
--- 274,283 ----
CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
CatalogCloseIndices(Num_pg_trigger_indices, idescs);
+
+ /* Need the Inserted Tup Oid below for the address of 'myself' */
+ insertTupOid = tuple->t_data->t_oid;
+
heap_freetuple(tuple);
heap_close(tgrel, RowExclusiveLock);
***************
*** 295,300 ****
--- 306,339 ----
heap_close(pgrel, RowExclusiveLock);
/*
+ * Insert dependencies
+ */
+ myself.classId = insertOid;
+ myself.objectId = insertTupOid;
+ myself.objectSubId = 0;
+
+ /* tgrelid */
+ dependee.classId = RelOid_pg_class;
+ dependee.objectId = RelationGetRelid(rel);
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, true);
+
+ /* tgfoid */
+ dependee.classId = RelOid_pg_proc;
+ dependee.objectId = funcoid;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, false);
+
+ /* tgconstrrelid */
+ if (constrrelid != InvalidOid)
+ {
+ dependee.classId = RelOid_pg_class;
+ dependee.objectId = constrrelid;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, true);
+ }
+
+ /*
* We used to try to update the rel's relcache entry here, but that's
* fairly pointless since it will happen as a byproduct of the
* upcoming CommandCounterIncrement...
***************
*** 350,357 ****
--- 389,400 ----
{
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
+ /* If trigOid is defined, it takes presedence over the name supplied */
if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
{
+ /* Deal with dependencies */
+ dependDeleteTuple(tuple, tgrel, RESTRICT);
+
/* Delete any comments associated with this trigger */
DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
***************
*** 396,494 ****
heap_close(rel, NoLock);
}
/*
! * Remove all triggers for a relation that's being deleted.
*/
void
! RelationRemoveTriggers(Relation rel)
{
! Relation tgrel;
! SysScanDesc tgscan;
! ScanKeyData key;
! HeapTuple tup;
! bool found = false;
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
! ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
F_OIDEQ,
! ObjectIdGetDatum(RelationGetRelid(rel)));
! tgscan = systable_beginscan(tgrel, TriggerRelidIndex, true,
! SnapshotNow, 1, &key);
! while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
! {
! /* Delete any comments associated with this trigger */
! DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel));
! simple_heap_delete(tgrel, &tup->t_self);
! found = true;
! }
! systable_endscan(tgscan);
! /*
! * If we deleted any triggers, must update pg_class entry and advance
! * command counter to make the updated entry visible. This is fairly
! * annoying, since we'e just going to drop the durn thing later, but
! * it's necessary to have a consistent state in case we do
! * CommandCounterIncrement() below --- if RelationBuildTriggers()
! * runs, it will complain otherwise. Perhaps RelationBuildTriggers()
! * shouldn't be so picky...
! */
! if (found)
! {
! Relation pgrel;
! Relation ridescs[Num_pg_class_indices];
! pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
! tup = SearchSysCacheCopy(RELOID,
! ObjectIdGetDatum(RelationGetRelid(rel)),
! 0, 0, 0);
! if (!HeapTupleIsValid(tup))
! elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
! RelationGetRelid(rel));
!
! ((Form_pg_class) GETSTRUCT(tup))->reltriggers = 0;
! simple_heap_update(pgrel, &tup->t_self, tup);
! CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
! CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tup);
! CatalogCloseIndices(Num_pg_class_indices, ridescs);
! heap_freetuple(tup);
! heap_close(pgrel, RowExclusiveLock);
! CommandCounterIncrement();
! }
! /*
! * Also drop all constraint triggers referencing this relation
! */
! ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgconstrrelid,
! F_OIDEQ,
! ObjectIdGetDatum(RelationGetRelid(rel)));
! tgscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, true,
! SnapshotNow, 1, &key);
! while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
! {
! Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
! elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"",
! get_rel_name(pg_trigger->tgrelid));
! DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname));
! /*
! * Need to do a command counter increment here to show up new
! * pg_class.reltriggers in the next loop iteration (in case there
! * are multiple referential integrity action triggers for the same
! * FK table defined on the PK table).
! */
! CommandCounterIncrement();
! }
! systable_endscan(tgscan);
! heap_close(tgrel, RowExclusiveLock);
}
/*
* Build trigger data to attach to the given relcache entry.
--- 439,527 ----
heap_close(rel, NoLock);
}
+
/*
! * DropTriggerById - Drop a trigger by it's OID
*/
void
! DropTriggerById(Oid trigId)
{
! Relation rel;
! Relation tgrel;
! HeapScanDesc tgscan;
! ScanKeyData key[1];
! Relation pgrel;
! HeapTuple tuple;
! Relation ridescs[Num_pg_class_indices];
! Form_pg_trigger pg_trigger;
! int nkeys = 0;
+ /*
+ * Search pg_trigger, delete target trigger, count remaining triggers
+ * for relation. Note this is OK only because we have
+ * AccessExclusiveLock on the rel, so no one else is creating/deleting
+ * triggers on this rel at the same time.
+ */
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
! ScanKeyEntryInitialize(&key[nkeys++], 0, ObjectIdAttributeNumber,
F_OIDEQ,
! ObjectIdGetDatum(trigId));
! tgscan = heap_beginscan(tgrel, 0, SnapshotNow, nkeys, key);
! tuple = heap_getnext(tgscan, 0);
! if (!HeapTupleIsValid(tuple))
! elog(ERROR, "DropTriggerById: TriggerID %d not valid", trigId);
! /* Grab the info, and lock the triggers relation */
! pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
! rel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock);
! /* Test Ownership */
! if (!pg_class_ownercheck(pg_trigger->tgrelid, GetUserId()))
! elog(ERROR, "%s: %s", RelationGetRelationName(rel),
! aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
! /* Deal with dependencies */
! dependDeleteTuple(tuple, tgrel, RESTRICT);
! /* Delete any comments associated with this trigger */
! DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
! simple_heap_delete(tgrel, &tuple->t_self);
! heap_endscan(tgscan);
! heap_close(tgrel, RowExclusiveLock);
! /*
! * Update relation's pg_class entry. Crucial side-effect: other
! * backends (and this one too!) are sent SI message to make them
! * rebuild relcache entries.
! */
! pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
! tuple = SearchSysCacheCopy(RELOID,
! ObjectIdGetDatum(pg_trigger->tgrelid),
! 0, 0, 0);
! if (!HeapTupleIsValid(tuple))
! elog(ERROR, "DropTriggerById: relation %s not found in pg_class",
! RelationGetRelationName(rel));
!
! /* Guarenteed to take one and only one */
! ((Form_pg_class) GETSTRUCT(tuple))->reltriggers--;
! simple_heap_update(pgrel, &tuple->t_self, tuple);
! CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
! CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple);
! CatalogCloseIndices(Num_pg_class_indices, ridescs);
! heap_freetuple(tuple);
! heap_close(pgrel, RowExclusiveLock);
!
! /* Keep lock on target rel until end of xact */
! heap_close(rel, NoLock);
}
+
/*
* Build trigger data to attach to the given relcache entry.
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.1
diff -c -r1.1 typecmds.c
*** src/backend/commands/typecmds.c 2002/04/15 05:22:03 1.1
--- src/backend/commands/typecmds.c 2002/04/15 12:22:39
***************
*** 35,40 ****
--- 35,41 ----
#include "catalog/catname.h"
#include "catalog/heap.h"
#include "catalog/namespace.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/defrem.h"
***************
*** 263,271 ****
RemoveType(List *names)
{
TypeName *typename;
- Relation relation;
- Oid typeoid;
- HeapTuple tup;
/* Make a TypeName so we can use standard type lookup machinery */
typename = makeNode(TypeName);
--- 264,269 ----
***************
*** 273,278 ****
--- 271,290 ----
typename->typmod = -1;
typename->arrayBounds = NIL;
+ RemoveTypeByTypeName(typename);
+ }
+
+ /*
+ * TypeRemove
+ * Removes a datatype by the typename struct
+ */
+ void
+ RemoveTypeByTypeName(TypeName *typename)
+ {
+ Relation relation;
+ Oid typeoid;
+ HeapTuple tup;
+
relation = heap_openr(TypeRelationName, RowExclusiveLock);
/* Use LookupTypeName here so that shell types can be removed. */
***************
*** 291,319 ****
if (!pg_type_ownercheck(typeoid, GetUserId()))
elog(ERROR, "RemoveType: type '%s': permission denied",
TypeNameToString(typename));
-
- /* Delete any comments associated with this type */
- DeleteComments(typeoid, RelationGetRelid(relation));
-
- /* Remove the type tuple from pg_type */
- simple_heap_delete(relation, &tup->t_self);
-
- ReleaseSysCache(tup);
-
- /* Now, delete the "array of" that type */
- typename->arrayBounds = makeList1(makeInteger(1));
-
- typeoid = LookupTypeName(typename);
- if (!OidIsValid(typeoid))
- elog(ERROR, "Type \"%s\" does not exist",
- TypeNameToString(typename));
! tup = SearchSysCache(TYPEOID,
! ObjectIdGetDatum(typeoid),
! 0, 0, 0);
! if (!HeapTupleIsValid(tup))
! elog(ERROR, "Type \"%s\" does not exist",
! TypeNameToString(typename));
DeleteComments(typeoid, RelationGetRelid(relation));
--- 303,311 ----
if (!pg_type_ownercheck(typeoid, GetUserId()))
elog(ERROR, "RemoveType: type '%s': permission denied",
TypeNameToString(typename));
! /* Deal with dependencies */
! dependDeleteTuple(tup, relation, RESTRICT);
DeleteComments(typeoid, RelationGetRelid(relation));
***************
*** 596,601 ****
--- 588,596 ----
if (typtype != 'd')
elog(ERROR, "%s is not a domain",
TypeNameToString(typename));
+
+ /* Deal with dependencies */
+ dependDeleteTuple(tup, relation, RESTRICT);
/* Delete any comments associated with this type */
DeleteComments(typeoid, RelationGetRelid(relation));
Index: src/backend/rewrite/rewriteDefine.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v
retrieving revision 1.66
diff -c -r1.66 rewriteDefine.c
*** src/backend/rewrite/rewriteDefine.c 2002/03/26 19:16:02 1.66
--- src/backend/rewrite/rewriteDefine.c 2002/04/15 12:22:40
***************
*** 17,22 ****
--- 17,24 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_namespace.h"
#include "catalog/pg_rewrite.h"
#include "commands/view.h"
#include "miscadmin.h"
***************
*** 49,62 ****
char *evqual,
char *actiontree)
{
! int i;
! Datum values[Natts_pg_rewrite];
! char nulls[Natts_pg_rewrite];
! NameData rname;
! Relation pg_rewrite_desc;
! TupleDesc tupDesc;
! HeapTuple tup;
! Oid rewriteObjectId;
if (IsDefinedRewriteRule(rulname))
elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists",
--- 51,66 ----
char *evqual,
char *actiontree)
{
! int i;
! Datum values[Natts_pg_rewrite];
! char nulls[Natts_pg_rewrite];
! NameData rname;
! Relation pg_rewrite_desc;
! TupleDesc tupDesc;
! HeapTuple tup;
! Oid rewriteObjectId;
! ObjectAddress myself,
! dependee;
if (IsDefinedRewriteRule(rulname))
elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists",
***************
*** 102,107 ****
--- 106,127 ----
tup);
CatalogCloseIndices(Num_pg_rewrite_indices, idescs);
}
+
+ /*
+ * Create Dependencies
+ * - Class of relation
+ */
+ myself.classId = GetSysCacheOid(RELNAMENSP,
+ CStringGetDatum(RewriteRelationName),
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ 0, 0);
+ myself.objectId = tup->t_data->t_oid;
+ myself.objectSubId = 0;
+
+ dependee.classId = RelOid_pg_class;
+ dependee.objectId = eventrel_oid;
+ dependee.objectSubId = 0;
+ dependCreate(&myself, &dependee, true);
heap_freetuple(tup);
Index: src/backend/rewrite/rewriteRemove.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v
retrieving revision 1.47
diff -c -r1.47 rewriteRemove.c
*** src/backend/rewrite/rewriteRemove.c 2002/03/29 19:06:13 1.47
--- src/backend/rewrite/rewriteRemove.c 2002/04/15 12:22:40
***************
*** 14,31 ****
*/
#include "postgres.h"
- #include "utils/builtins.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_rewrite.h"
#include "commands/comment.h"
#include "miscadmin.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
/*
* RemoveRewriteRule
--- 14,35 ----
*/
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/catname.h"
+ #include "catalog/pg_depend.h"
#include "catalog/pg_rewrite.h"
#include "commands/comment.h"
+ #include "nodes/parsenodes.h" /* Required by parser/parse.h */
+ #include "parser/parse.h" /* For keyword RESTRICT */
#include "miscadmin.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
+ #include "utils/builtins.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/syscache.h"
+ void RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force);
/*
* RemoveRewriteRule
***************
*** 37,48 ****
{
char *ruleName;
Relation RewriteRelation;
- Relation event_relation;
HeapTuple tuple;
- Oid ruleId;
- Oid eventRelationOid;
- bool hasMoreRules;
- int32 aclcheck_result;
/*
* XXX temporary until rules become schema-tized
--- 41,47 ----
***************
*** 64,74 ****
0, 0, 0);
/*
! * complain if no rule with such name existed
*/
if (!HeapTupleIsValid(tuple))
elog(ERROR, "Rule \"%s\" not found", ruleName);
/*
* Save the OID of the rule (i.e. the tuple's OID) and the event
* relation's OID
--- 63,133 ----
0, 0, 0);
/*
! * complain if no rule with such nam*e existed
*/
if (!HeapTupleIsValid(tuple))
elog(ERROR, "Rule \"%s\" not found", ruleName);
+ RemoveRewriteRuleByTuple(RewriteRelation, tuple, false);
+
+ heap_freetuple(tuple);
+
+ heap_close(RewriteRelation, RowExclusiveLock);
+ }
+
+
+ void
+ RemoveRewriteRuleById(Oid ruleId)
+ {
+ Relation RewriteRelation;
+ HeapScanDesc scanDesc = NULL;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple;
+
+ /*
+ * Open the pg_rewrite relation.
+ */
+ RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
+
+ /*
+ * Find the tuple for the target rule.
+ */
+ ScanKeyEntryInitialize(&scanKeyData,
+ 0,
+ ObjectIdAttributeNumber,
+ F_OIDEQ,
+ ObjectIdGetDatum(ruleId));
+
+ scanDesc = heap_beginscan(RewriteRelation,
+ 0, SnapshotNow, 1, &scanKeyData);
+
+ /* Assume only 1 will be found */
+ while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
+ {
+ RemoveRewriteRuleByTuple(RewriteRelation, tuple, true);
+ }
+
+ heap_endscan(scanDesc);
+
+ heap_close(RewriteRelation, RowExclusiveLock);
+ }
+
+ /*
+ * RemoveRewriteRuleByTuple
+ *
+ * If force is true then the fact that the rule is owned by a view is ignored
+ * by the system. It will remove it anyway.
+ */
+ void
+ RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force)
+ {
+
+ Relation event_relation;
+ Oid ruleId;
+ Oid eventRelationOid;
+ bool hasMoreRules;
+ int32 aclcheck_result;
+
/*
* Save the OID of the rule (i.e. the tuple's OID) and the event
* relation's OID
***************
*** 95,121 ****
aclcheck_error_strings[aclcheck_result]);
/* do not allow the removal of a view's SELECT rule */
! if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1')
! elog(ERROR, "Cannot remove a view's SELECT rule");
hasMoreRules = event_relation->rd_rules != NULL &&
event_relation->rd_rules->numLocks > 1;
/*
* Delete any comments associated with this rule
*/
! DeleteComments(ruleId, RelationGetRelid(RewriteRelation));
!
/*
* Now delete the pg_rewrite tuple for the rule
*/
! simple_heap_delete(RewriteRelation, &tuple->t_self);
- heap_freetuple(tuple);
-
- heap_close(RewriteRelation, RowExclusiveLock);
-
/*
* Set pg_class 'relhasrules' field correctly for event relation.
*
--- 154,178 ----
aclcheck_error_strings[aclcheck_result]);
/* do not allow the removal of a view's SELECT rule */
! if (force == false && event_relation->rd_rel->relkind == RELKIND_VIEW &&
((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1')
! elog(ERROR, "RemoveRewriteRuleByTuple: Cannot remove a view's SELECT rule");
hasMoreRules = event_relation->rd_rules != NULL &&
event_relation->rd_rules->numLocks > 1;
+ /* Deal with dependencies */
+ dependDeleteTuple(tuple, rewriteRelation, RESTRICT);
+
/*
* Delete any comments associated with this rule
*/
! DeleteComments(ruleId, RelationGetRelid(rewriteRelation));
/*
* Now delete the pg_rewrite tuple for the rule
*/
! simple_heap_delete(rewriteRelation, &tuple->t_self);
/*
* Set pg_class 'relhasrules' field correctly for event relation.
*
***************
*** 127,172 ****
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);
- }
-
- /*
- * RelationRemoveRules -
- * removes all rules associated with the relation when the relation is
- * being removed.
- */
- void
- RelationRemoveRules(Oid relid)
- {
- Relation RewriteRelation = NULL;
- HeapScanDesc scanDesc = NULL;
- ScanKeyData scanKeyData;
- HeapTuple tuple = NULL;
-
- /*
- * Open the pg_rewrite relation.
- */
- RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
-
- /*
- * Scan the RuleRelation ('pg_rewrite') for all the tuples that has
- * the same ev_class as relid (the relation to be removed).
- */
- ScanKeyEntryInitialize(&scanKeyData,
- 0,
- Anum_pg_rewrite_ev_class,
- F_OIDEQ,
- ObjectIdGetDatum(relid));
- scanDesc = heap_beginscan(RewriteRelation,
- 0, SnapshotNow, 1, &scanKeyData);
-
- while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
- {
- /* Delete any comments associated with this rule */
- DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation));
-
- simple_heap_delete(RewriteRelation, &tuple->t_self);
- }
-
- heap_endscan(scanDesc);
- heap_close(RewriteRelation, RowExclusiveLock);
}
--- 184,187 ----
Index: src/bin/initdb/initdb.sh
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.sh,v
retrieving revision 1.147
diff -c -r1.147 initdb.sh
*** src/bin/initdb/initdb.sh 2002/04/04 04:25:50 1.147
--- src/bin/initdb/initdb.sh 2002/04/15 12:22:44
***************
*** 599,604 ****
--- 599,1218 ----
PGSQL_OPT="$PGSQL_OPT -O"
+ $ECHO_N "initializing pg_depend... "$ECHO_C
+
+ "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
+ -- Dependencies should be inserted before any drop attempts.
+ -- It won't neccessarily break anything, but it's just the
+ -- nice thing to do.
+ --
+ -- Ensure to eliminate duplicates
+
+ -- Types depend on procedures
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_type \
+ JOIN pg_proc ON pg_proc.oid IN ( regproctooid(pg_type.typinput) \
+ , regproctooid(pg_type.typoutput) \
+ , regproctooid(pg_type.typreceive) \
+ , regproctooid(pg_type.typsend) \
+ ) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- Types depend on types (array)
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , typchild.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , typparent.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_type as typparent \
+ JOIN pg_type as typchild ON (typparent.oid = typchild.typelem) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- Types depend on relations
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_type \
+ JOIN pg_class ON (pg_class.oid = pg_type.typrelid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- Attributes depend on types
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_attribute') \
+ , attrelid \
+ , attnum \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_attribute \
+ JOIN pg_type ON (pg_attribute.atttypid = pg_type.oid) \
+ WHERE attnum > 0 \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- Toast tables depend on the relations
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , toast.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_class \
+ JOIN pg_class as toast ON (pg_class.reltoastrelid = toast.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- Indexes depend on the relation
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , idx.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_class \
+ JOIN pg_class as idx ON (pg_class.reltoastidxid = idx.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- Procedures depend on their control language
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_language') \
+ , pg_language.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_proc \
+ JOIN pg_language ON (prolang = pg_language.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- Procedures depend on their control language (*= for oid and oidvector needed)
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_proc \
+ JOIN pg_type ON (pg_type.oid IN ( proargtypes[0] \
+ , proargtypes[1] \
+ , proargtypes[2] \
+ , proargtypes[3] \
+ , prorettype \
+ )) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_trigger.tgfoid -> pg_function
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \
+ , tgfoid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_trigger \
+ JOIN pg_proc ON (pg_trigger.tgfoid = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_trigger.tgrelid -> pg_class
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \
+ , tgrelid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_trigger \
+ JOIN pg_class ON (pg_trigger.tgrelid = pg_class.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_trigger.tgconstrrelid -> pg_class (always cascade)
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \
+ , tgconstrrelid \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_trigger \
+ JOIN pg_class ON (pg_trigger.tgconstrrelid = pg_class.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- pg_rewrite.ev_class -> pg_class
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') \
+ , ev_class \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \
+ , pg_class.oid \
+ , 0 \
+ , TRUE \
+ FROM pg_rewrite \
+ JOIN pg_class ON (pg_rewrite.ev_class = pg_class.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , TRUE \
+ FROM pg_depend;
+
+ -- pg_operator.oprleft -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprleft \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_type ON (pg_operator.oprleft = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprright -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprright \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_type ON (pg_operator.oprright = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprresult -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprresult \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_type ON (pg_operator.oprresult = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprcom -> pg_operator
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , pg_operator.oprcom \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , dep.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_operator as dep ON (pg_operator.oprresult = dep.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprnegate -> pg_operator
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , pg_operator.oprnegate \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , dep.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_operator as dep ON (pg_operator.oprnegate = dep.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprlsortop -> pg_operator
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , pg_operator.oprlsortop \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , dep.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_operator as dep ON (pg_operator.oprlsortop = dep.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprrsortop -> pg_operator
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , pg_operator.oprrsortop \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , dep.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_operator as dep ON (pg_operator.oprrsortop = dep.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprcode -> pg_proc
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprcode \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_proc ON (pg_operator.oprcode = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprrest -> pg_proc
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprrest \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_proc ON (pg_operator.oprrest = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_operator.oprjoin -> pg_proc
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \
+ , oprjoin \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_operator \
+ JOIN pg_proc ON (pg_operator.oprjoin = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_aggregate.aggtransfn -> pg_proc
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \
+ , aggtransfn \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_aggregate \
+ JOIN pg_proc ON (pg_aggregate.aggtransfn = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_aggregate.aggfinalfn -> pg_proc
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \
+ , aggfinalfn \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \
+ , pg_proc.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_aggregate \
+ JOIN pg_proc ON (pg_aggregate.aggfinalfn = pg_proc.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_aggregate.aggbasetype -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \
+ , aggbasetype \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_aggregate \
+ JOIN pg_type ON (pg_aggregate.aggbasetype = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_aggregate.aggtranstype -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \
+ , aggtranstype \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_aggregate \
+ JOIN pg_type ON (pg_aggregate.aggtranstype = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+
+ -- pg_aggregate.aggfinaltype -> pg_type
+ INSERT INTO pg_depend \
+ SELECT \
+ DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \
+ , aggfinaltype \
+ , 0 \
+ , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \
+ , pg_type.oid \
+ , 0 \
+ , FALSE \
+ FROM pg_aggregate \
+ JOIN pg_type ON (pg_aggregate.aggfinaltype = pg_type.oid) \
+ EXCEPT \
+ SELECT classid \
+ , objid \
+ , objsubid \
+ , depclassid \
+ , depobjid \
+ , depobjsubid \
+ , FALSE \
+ FROM pg_depend;
+ EOF
+
$ECHO_N "initializing pg_shadow... "$ECHO_C
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
Index: src/include/catalog/catname.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/catname.h,v
retrieving revision 1.24
diff -c -r1.24 catname.h
*** src/include/catalog/catname.h 2002/03/22 21:34:44 1.24
--- src/include/catalog/catname.h 2002/04/15 12:22:45
***************
*** 21,26 ****
--- 21,27 ----
#define AccessMethodProcedureRelationName "pg_amproc"
#define AttributeRelationName "pg_attribute"
#define DatabaseRelationName "pg_database"
+ #define DependRelationName "pg_depend"
#define DescriptionRelationName "pg_description"
#define GroupRelationName "pg_group"
#define IndexRelationName "pg_index"
Index: src/include/catalog/namespace.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/namespace.h,v
retrieving revision 1.7
diff -c -r1.7 namespace.h
*** src/include/catalog/namespace.h 2002/04/09 20:35:54 1.7
--- src/include/catalog/namespace.h 2002/04/15 12:22:45
***************
*** 47,52 ****
--- 47,54 ----
extern RangeVar *makeRangeVarFromNameList(List *names);
+ extern char *namespaceIdGetNspname(Oid namespaceId);
+
extern char *NameListToString(List *names);
extern bool isTempNamespace(Oid namespaceId);
Index: src/include/catalog/pg_attribute.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_attribute.h,v
retrieving revision 1.90
diff -c -r1.90 pg_attribute.h
*** src/include/catalog/pg_attribute.h 2002/04/11 20:00:11 1.90
--- src/include/catalog/pg_attribute.h 2002/04/15 12:22:46
***************
*** 288,293 ****
--- 288,320 ----
DATA(insert ( 1262 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1262 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
+ /* ----------------
+ * pg_depend
+ * ----------------
+ */
+ #define Schema_pg_depend \
+ { 1077, {"classid"}, 26, 0, 4, 1, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"objid"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"objsubid"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"depclassid"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"depobjid"}, 26, 0, 4, 5, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"depobjsubid"}, 23, 0, 4, 6, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+ { 1077, {"alwayscascade"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }
+
+ DATA(insert ( 1077 classid 26 0 4 1 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 objid 26 0 4 2 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 objsubid 23 0 4 3 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 depclassid 26 0 4 4 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 depobjid 26 0 4 5 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 depobjsubid 23 0 4 6 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 alwayscascade 16 0 1 7 0 -1 -1 t p f c f f));
+ DATA(insert ( 1077 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
+ DATA(insert ( 1077 oid 26 0 4 -2 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
+ DATA(insert ( 1077 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
/* ----------------
* pg_proc
Index: src/include/catalog/pg_class.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_class.h,v
retrieving revision 1.66
diff -c -r1.66 pg_class.h
*** src/include/catalog/pg_class.h 2002/04/11 20:00:11 1.66
--- src/include/catalog/pg_class.h 2002/04/15 12:22:46
***************
*** 146,155 ****
DESCR("");
DATA(insert OID = 1261 ( pg_group PGNSP 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ ));
DESCR("");
! DATA(insert OID = 1262 ( pg_database PGNSP 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
DESCR("");
#define RelOid_pg_type 1247
#define RelOid_pg_attribute 1249
--- 146,159 ----
DESCR("");
DATA(insert OID = 1261 ( pg_group PGNSP 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ ));
DESCR("");
! DATA(insert OID = 1262 ( pg_database PGNSP 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
DESCR("");
+ DATA(insert OID = 1077 ( pg_depend PGNSP 90 PGUID 0 1077 0 0 0 0 f f r 7 0 0 0 0 0 f f f f _null_ ));
+ DESCR("");
+
+
#define RelOid_pg_type 1247
#define RelOid_pg_attribute 1249
***************
*** 158,163 ****
--- 162,168 ----
#define RelOid_pg_shadow 1260
#define RelOid_pg_group 1261
#define RelOid_pg_database 1262
+ #define RelOid_pg_depend 1077
/* Xact lock pseudo-table */
#define XactLockTableId 376
Index: src/include/catalog/pg_type.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_type.h,v
retrieving revision 1.119
diff -c -r1.119 pg_type.h
*** src/include/catalog/pg_type.h 2002/03/29 19:06:20 1.119
--- src/include/catalog/pg_type.h 2002/04/15 12:22:48
***************
*** 312,317 ****
--- 312,318 ----
DATA(insert OID = 86 ( pg_shadow PGNSP PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 87 ( pg_group PGNSP PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 88 ( pg_database PGNSP PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+ DATA(insert OID = 90 ( pg_depend PGNSP PGUID 4 4 t c t \054 1077 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
/* OIDS 100 - 199 */
Index: src/include/commands/defrem.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/defrem.h,v
retrieving revision 1.35
diff -c -r1.35 defrem.h
*** src/include/commands/defrem.h 2002/04/15 05:22:03 1.35
--- src/include/commands/defrem.h 2002/04/15 12:22:48
***************
*** 50,61 ****
extern void DefineType(List *names, List *parameters);
extern void RemoveType(List *names);
extern void DefineDomain(CreateDomainStmt *stmt);
extern void RemoveDomain(List *names, int behavior);
-
/* support routines in define.c */
-
extern void case_translate_language_name(const char *input, char *output);
extern char *defGetString(DefElem *def);
--- 50,60 ----
extern void DefineType(List *names, List *parameters);
extern void RemoveType(List *names);
+ extern void RemoveTypeByTypeName(TypeName *typename);
extern void DefineDomain(CreateDomainStmt *stmt);
extern void RemoveDomain(List *names, int behavior);
/* support routines in define.c */
extern void case_translate_language_name(const char *input, char *output);
extern char *defGetString(DefElem *def);
Index: src/include/commands/trigger.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/trigger.h,v
retrieving revision 1.34
diff -c -r1.34 trigger.h
*** src/include/commands/trigger.h 2002/04/01 22:36:13 1.34
--- src/include/commands/trigger.h 2002/04/15 12:22:48
***************
*** 103,109 ****
extern void CreateTrigger(CreateTrigStmt *stmt);
extern void DropTrigger(Oid relid, const char *trigname);
! extern void RelationRemoveTriggers(Relation rel);
extern void RelationBuildTriggers(Relation relation);
--- 103,109 ----
extern void CreateTrigger(CreateTrigStmt *stmt);
extern void DropTrigger(Oid relid, const char *trigname);
! extern void DropTriggerById(Oid trigId);
extern void RelationBuildTriggers(Relation relation);
Index: src/include/rewrite/rewriteRemove.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/rewrite/rewriteRemove.h,v
retrieving revision 1.12
diff -c -r1.12 rewriteRemove.h
*** src/include/rewrite/rewriteRemove.h 2002/03/29 19:06:26 1.12
--- src/include/rewrite/rewriteRemove.h 2002/04/15 12:22:49
***************
*** 15,20 ****
#define REWRITEREMOVE_H
extern void RemoveRewriteRule(List *names);
! extern void RelationRemoveRules(Oid relid);
!
#endif /* REWRITEREMOVE_H */
--- 15,19 ----
#define REWRITEREMOVE_H
extern void RemoveRewriteRule(List *names);
! extern void RemoveRewriteRuleById(Oid ruleId);
#endif /* REWRITEREMOVE_H */
Index: src/test/regress/expected/alter_table.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/alter_table.out,v
retrieving revision 1.38
diff -c -r1.38 alter_table.out
*** src/test/regress/expected/alter_table.out 2002/04/12 20:38:30 1.38
--- src/test/regress/expected/alter_table.out 2002/04/15 12:22:51
***************
*** 340,347 ****
DROP TABLE tmp5;
DROP TABLE tmp4;
DROP TABLE tmp3;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
DROP TABLE tmp2;
-- Foreign key adding test with mixed types
-- Note: these tables are TEMP to avoid name conflicts when this test
--- 340,345 ----
***************
*** 370,377 ****
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
DROP TABLE pktable;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
DROP TABLE fktable;
CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
PRIMARY KEY(ptest1, ptest2));
--- 368,373 ----
Index: src/test/regress/expected/foreign_key.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/foreign_key.out,v
retrieving revision 1.14
diff -c -r1.14 foreign_key.out
*** src/test/regress/expected/foreign_key.out 2002/04/11 20:00:17 1.14
--- src/test/regress/expected/foreign_key.out 2002/04/15 12:22:53
***************
*** 56,62 ****
(3 rows)
DROP TABLE PKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
DROP TABLE FKTABLE;
--
-- check set NULL and table constraint on multiple columns
--- 56,61 ----
***************
*** 139,145 ****
(5 rows)
DROP TABLE PKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
DROP TABLE FKTABLE;
--
-- check set default and table constraint on multiple columns
--- 138,143 ----
***************
*** 224,230 ****
(5 rows)
DROP TABLE PKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
DROP TABLE FKTABLE;
--
-- First test, check with no on delete or on update
--- 222,227 ----
***************
*** 299,305 ****
(4 rows)
DROP TABLE PKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
DROP TABLE FKTABLE;
-- MATCH unspecified
-- Base test restricting update/delete
--- 296,301 ----
***************
*** 363,370 ****
(5 rows)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
-- cascade update/delete
CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 359,364 ----
***************
*** 462,469 ****
(4 rows)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
-- set null update / set default delete
CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 456,461 ----
***************
*** 568,575 ****
(6 rows)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
-- set default update / set null delete
CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) );
--- 560,565 ----
***************
*** 687,694 ****
(7 rows)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
--- 677,682 ----
***************
*** 734,747 ****
CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable);
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
-- As should this
CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable(ptest1));
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
-- Two columns, two tables
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
--- 722,731 ----
***************
*** 775,788 ****
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
-- As does this
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
DROP TABLE FKTABLE;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
DROP TABLE PKTABLE;
-- Two columns, same table
-- Make sure this still works...
--- 759,768 ----
***************
*** 849,856 ****
delete from pktable where base1>3;
-- cleanup
drop table fktable;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
delete from pktable;
-- Now 2 columns 2 tables, matching types
create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1));
--- 829,834 ----
***************
*** 877,884 ****
delete from pktable where base1>3;
-- cleanup
drop table fktable;
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
- NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
drop table pktable;
drop table pktable_base;
-- Now we'll do one all in 1 table with 2 columns of matching types
--- 855,860 ----
Rod Taylor <rbt@zort.ca> writes:
This one has been corrected to fit in with Toms recent changes, as well
as the changes with command/ restructuring.
Please accept or reject quickly, else risk conflicts.
This is interesting but certainly far from ready for prime time.
Some random comments, in no particular order:
1. I don't like the code that installs and removes ad-hoc dependencies
from relations to type Oid. On its own terms it's wrong (if it were
right, then you'd also need to be installing dependencies for Tid, Xid,
and the types of the other system columns), but on a larger scale I
don't see the point of expending cycles, disk space, and code complexity
to record these dependencies. The system *cannot* work if you drop type
Oid. So it'd seem to make more sense to wire in a notion that certain
types, tables, etc are "pinned" and may never be dropped; then there's
no need to create explicit dependencies on them. If you want an
explicit representation of pinning in the pg_depends table, perhaps it
would work to create a row claiming that "table 0 / Oid 0 / subid 0"
depends on a pinned object.
2. Is it really necessary to treat pg_depends as a bootstrapped
relation? That adds a lot of complexity, as you've evidently already
found, and it does not seem necessary if you're going to load the system
dependencies in a later step of the initdb process. You can just make
the dependency-adding routines be no-ops in bootstrap mode; then create
pg_depends as an ordinary system catalog; and finally load the entries
post-bootstrap.
3. Isn't there a better way to find the initial dependencies? That
SELECT is truly ugly, and more to the point is highly likely to break
anytime someone rearranges the catalogs. I'd like to see it generated
automatically (maybe using a tool like findoidjoins); or perhaps we
could do the discovery of the columns to look at on-the-fly.
4. Do not use the parser's RESTRICT/CASCADE tokens as enumerated type
values. They change value every time someone tweaks the grammar.
(Yes, I know you copied from extant code; that code is on my hitlist.)
Define your own enum type instead of creating a lot of bogus
dependencies on parser/parser.h.
5. Avoid using heapscans on pg_depend; it's gonna be way too big for
that to give acceptable performance. Make sure you have indexes
available to match your searches, and use the systable_scan routines.
6. The tests on relation names in dependDelete, getObjectName are (a)
slow and (b) not schema-aware. Can you make these into OID comparisons
instead?
7. The namespaceIdGetNspname routine you added is unsafe (it would need
to pstrdup the name to be sure it's still valid after releasing the
syscache entry); but more to the point, it duplicates a routine already
present in lsyscache.c (which is where this sort of utility generally
belongs, anyway).
8. Aggregate code seems unaware that aggfinalfn is optional.
I have to leave, but reserve the right to make more comments later ;-)
In general though, this seems like a cool approach and definitely
worth pursuing. Keep at it!
regards, tom lane
[ copied to hackers ]
1. I don't like the code that installs and removes ad-hoc
dependencies
from relations to type Oid. On its own terms it's wrong (if it were
...
explicit representation of pinning in the pg_depends table, perhaps
it
would work to create a row claiming that "table 0 / Oid 0 / subid 0"
depends on a pinned object.
Yes, a pinned dependency makes much more sense.
int4, bool, varchar, and name are in the same boat.
I'll make it so dependCreate() will ignore adding any additional
dependencies on pinned types (class 0, Oid 0, SubID 0) and
dependDelete() will never allow deletion when that dependency exists.
2. Is it really necessary to treat pg_depends as a bootstrapped
relation? That adds a lot of complexity, as you've evidently
already
found, and it does not seem necessary if you're going to load the
system
dependencies in a later step of the initdb process. You can just
make
the dependency-adding routines be no-ops in bootstrap mode; then
create
pg_depends as an ordinary system catalog; and finally load the
entries
post-bootstrap.
Ack.. <sound of hand hitting head>. All that work to avoid a simple
if statement.
Ahh well.. learning at it's finest :)
3. Isn't there a better way to find the initial dependencies? That
SELECT is truly ugly, and more to the point is highly likely to
break
anytime someone rearranges the catalogs. I'd like to see it
generated
automatically (maybe using a tool like findoidjoins); or perhaps we
could do the discovery of the columns to look at on-the-fly.
I'm not entirely sure how to approach this, but it does appear that
findoidjoins would find all the relations.
So... I could create a pg_ function which will find all oid joins,
and call dependCreate() for each entry it finds. That way
dependCreate will ignore anything that was pinned (see above)
automagically. It would also make initdb quite slow, and would add a
pg_ function that one should normally avoid during normal production.
Then again, I suppose it could be used to recreate missing
dependencies if a user was manually fiddling with that table.
initdb would call SELECT pg_findSystemDepends(); or something.
4. Do not use the parser's RESTRICT/CASCADE tokens as enumerated
type
values. They change value every time someone tweaks the grammar.
(Yes, I know you copied from extant code; that code is on my
hitlist.)
Define your own enum type instead of creating a lot of bogus
dependencies on parser/parser.h.
All but one of those will go away once the functions are modified to
accept the actual RESTRICT or CASCADE bit. That was going to be step
2 of the process but I suppose I could do it now, along with a rather
large regression test. The only place that RESTRICT will be used is
dependDelete(); Nowhere else will care. It'll simply pass on what
was given to it by the calling function from utility.c or a cascading
dependDelete. Of course, gram.y will be littered with the
'opt_restrictcascade' tag.
The RESTRICT usage is more of a current placeholder. I've marked the
includes as /* FOR RESTRICT */ for that reason, make them easy to
remove later.
6. The tests on relation names in dependDelete, getObjectName are
(a)
slow and (b) not schema-aware. Can you make these into OID
comparisons
instead?
Ahh yes. Good point.
Rod Taylor wrote:
[ copied to hackers ]
1. I don't like the code that installs and removes ad-hoc
dependencies
from relations to type Oid. On its own terms it's wrong (if it were
Looks good to me. I realize this is a huge chunk of code. The only
ultra-minor thing I saw was the use of dashes for comment blocks when
not needed:
/* ----
* word
* ----
*/
We use dashes like this only for comments that shouldn't be reformatted
by pgindent.
The one thing I would like to know is what things does it track, and
what does it not track? Does it complete any TODO items, or do we save
that for later?
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Yes, I've removed all of those.
I've submitted a list of stuff it tracked earlier, but will do so
again with the next patch. Basically, anything simple and
straightforward ;)
It doesn't manage dependencies of function code, view internals,
default internals as I don't know how to find navigate an arbitrary
parse tree for that information. Some function code isn't even
available (C), so its next to impossible.
No, it doesn't directly tick off any todo item other than the first in
dependency. Make pg_depend table ;)
--
Rod Taylor
Your eyes are weary from staring at the CRT. You feel sleepy. Notice
how restful it is to watch the cursor blink. Close your eyes. The
opinions stated above are yours. You cannot imagine why you ever felt
otherwise.
----- Original Message -----
From: "Bruce Momjian" <pgman@candle.pha.pa.us>
To: "Rod Taylor" <rbt@zort.ca>
Cc: "Tom Lane" <tgl@sss.pgh.pa.us>; <pgsql-patches@postgresql.org>;
"Hackers List" <pgsql-hackers@postgresql.org>
Sent: Tuesday, April 16, 2002 1:15 AM
Subject: Re: [HACKERS] [PATCHES] YADP - Yet another Dependency Patch
Rod Taylor wrote:
[ copied to hackers ]
1. I don't like the code that installs and removes ad-hoc
dependencies
from relations to type Oid. On its own terms it's wrong (if it
were
Looks good to me. I realize this is a huge chunk of code. The only
ultra-minor thing I saw was the use of dashes for comment blocks
when
not needed:
/* ----
* word
* ----
*/We use dashes like this only for comments that shouldn't be
reformatted
by pgindent.
The one thing I would like to know is what things does it track, and
what does it not track? Does it complete any TODO items, or do we
save
that for later?
-- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania
19026
Show quoted text
Rod Taylor wrote:
Yes, I've removed all of those.
I've submitted a list of stuff it tracked earlier, but will do so
again with the next patch. Basically, anything simple and
straightforward ;)
Thanks for an updated list of tracked items. I know you posted it
earlier, but some are complaining recently that patches are coming in
too fast or with too long of a gap between discussion and patch arrival,
and they are getting confused trying to track where we are going.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
3. Isn't there a better way to find the initial dependencies? That
SELECT is truly ugly, and more to the point is highly likely to
break
anytime someone rearranges the catalogs. I'd like to see it
generated
automatically (maybe using a tool like findoidjoins); or perhaps we
could do the discovery of the columns to look at on-the-fly.
I'm having a really hard time coming up with a good method for this.
The key problems with doing what findoidjoins does is recording things
like indexes, complex types, etc. as items that should be implicitly
dropped when the table is dropped. Also, in the case of indicies the
work required to 'discover' 2 value foreign keys against pg_attribute
(attnum and attrelid) would be a royal pain in the ass -- especially
when it's in the form of a vector (ugh). There are enough of those to
warrent something other than hardcoding the relations in c code.
It might be possible to create foreign keys for the system tables and
use those to discover the associations. Any foreign key in pg_catalog
made up of an object address (table, oid column) or (table, oid
column, int column) could potentially have each foreign key tuple set
(join tables by key) recorded as a dependency.
So... Any thoughts to adding a no-op foreign key reference? A key
thats used for style purposes only.
"Rod Taylor" <rbt@zort.ca> writes:
3. Isn't there a better way to find the initial dependencies? That
SELECT is truly ugly, and more to the point is highly likely to
break anytime someone rearranges the catalogs.
I'm having a really hard time coming up with a good method for this.
Well, do we actually need an *accurate* representation of the
dependencies? You seemed to like my idea of pinning essential stuff,
and in reality all of the initial catalog structures ought to be pinned.
Maybe it would be sufficient to just make "pinned" entries for
everything that appears in the initial catalogs. Someone who's really
intent on manually deleting, say, the "box" datatype could be expected
to be bright enough to figure out how to remove the pg_depends entry
that's preventing him from doing so.
(There are a very small number of things that are specifically intended
to be droppable, like the "public" namespace, but seems like excluding
that short list from the pg_depends entries would be more maintainable
than the approach you've got now.)
regards, tom lane
Thats what I was going to propose if no-one could figure out a way of
automatically gathering system table dependencies.
It would be nice (for a minimallist db) to be able to drop a bunch of
stuff, but a number of other things would need to be done as well
(full system compression for example).
--
Rod
----- Original Message -----
From: "Tom Lane" <tgl@sss.pgh.pa.us>
To: "Rod Taylor" <rbt@zort.ca>
Cc: "Hackers List" <pgsql-hackers@postgresql.org>
Sent: Thursday, April 18, 2002 1:24 AM
Subject: Re: [HACKERS] [PATCHES] YADP - Yet another Dependency Patch
"Rod Taylor" <rbt@zort.ca> writes:
3. Isn't there a better way to find the initial dependencies?
That
SELECT is truly ugly, and more to the point is highly likely to
break anytime someone rearranges the catalogs.I'm having a really hard time coming up with a good method for
this.
Well, do we actually need an *accurate* representation of the
dependencies? You seemed to like my idea of pinning essential
stuff,
and in reality all of the initial catalog structures ought to be
pinned.
Maybe it would be sufficient to just make "pinned" entries for
everything that appears in the initial catalogs. Someone who's
really
intent on manually deleting, say, the "box" datatype could be
expected
to be bright enough to figure out how to remove the pg_depends entry
that's preventing him from doing so.(There are a very small number of things that are specifically
intended
to be droppable, like the "public" namespace, but seems like
excluding
that short list from the pg_depends entries would be more
maintainable
Show quoted text
than the approach you've got now.)
regards, tom lane