? src/backend/catalog/pg_depend.c ? src/bin/pg_passwd/pg_passwd ? src/include/catalog/pg_depend.h ? src/test/regress/expected/drop.out 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/21 01:51:36 *************** *** 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/genbki.sh =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/genbki.sh,v retrieving revision 1.26 diff -c -r1.26 genbki.sh *** src/backend/catalog/genbki.sh 2002/03/26 19:15:24 1.26 --- src/backend/catalog/genbki.sh 2002/04/21 01:51:36 *************** *** 223,228 **** --- 223,232 ---- comment_level = 0; nextbkioid = ENVIRON["BKIOBJECTID"]; oid = 0; + pin = ""; + pindata[-1] = ""; + pinoid = 0; + pinwrite = ""; } # ---------------- *************** *** 250,255 **** --- 254,263 ---- # stripping off the DATA( and the ) on the end. However, # if we see "OID = 0" then we should assign an oid from nextbkioid. # Remember any explicit or assigned OID for use by DESCR(). + # + # If this is a base table with a PIN id recorded, dump the dependency + # information to a depend file which will be appended onto the data + # for the pg_depend table. # ---------------- /^DATA\(/ { data = substr($0, 6, length($0) - 6); *************** *** 264,269 **** --- 272,284 ---- nextbkioid++; sub("OID *= *0", "OID = " oid, data); } + + if (pin != "") + { + pinoid = pincount; + pindata[pinoid] = sprintf("insert (%d %d 0 0 0 0 f)", pin, oid); + pincount++; + } } print data; next; *************** *** 284,289 **** --- 299,305 ---- # end any prior catalog data insertions before starting a define index # ---- if (reln_open == 1) { + pinwritedata(pinwrite); # print "show"; print "close " catalog; reln_open = 0; *************** *** 298,303 **** --- 314,320 ---- # end any prior catalog data insertions before starting a define unique index # ---- if (reln_open == 1) { + pinwritedata(pinwrite); # print "show"; print "close " catalog; reln_open = 0; *************** *** 308,314 **** } /^BUILD_INDICES/ { print "build indices"; } ! # ---------------- # CATALOG() definitions take some more work. # ---------------- --- 325,339 ---- } /^BUILD_INDICES/ { print "build indices"; } ! ! /^PINTABLE\(/ { ! ret = match($0, /[0-9]+/); ! pin = substr($0, RSTART, RLENGTH); ! ! pinwrite = ""; ! next; ! } ! # ---------------- # CATALOG() definitions take some more work. # ---------------- *************** *** 317,322 **** --- 342,348 ---- # end any prior catalog data insertions before starting a new one.. # ---- if (reln_open == 1) { + pinwritedata(pinwrite); # print "show"; print "close " catalog; reln_open = 0; *************** *** 331,340 **** --- 357,375 ---- if ($0 ~ /BOOTSTRAP/) { bootstrap = "bootstrap "; } + if ($0 ~ /BKI_WITHOUT_OIDS/) { without_oids = "without_oids "; } + if ($0 ~ /PINWRITE/) { + pinwrite = "pinwrite"; + } else { + pinwrite = ""; + } + + pin = ""; + i = 1; inside = 1; nc++; *************** *** 397,405 **** --- 432,452 ---- END { if (reln_open == 1) { + pinwritedata(pinwrite); # print "show"; print "close " catalog; reln_open = 0; + } + } + + ## + # write out PINd records + function pinwritedata(pinwrite) + { + if (pinwrite == "pinwrite") { + for (i=0; i < pincount; i++) { + print pindata[i]; + } } } ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" > $TMPFILE || exit 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/21 01:51:38 *************** *** 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,56 ---- #include "optimizer/planmain.h" #include "optimizer/prep.h" #include "optimizer/var.h" + #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, --- 70,75 ---- *************** *** 415,420 **** --- 415,422 ---- bool hasindex; Relation idescs[Num_pg_attr_indices]; int natts = tupdesc->natts; + ObjectAddress myself, + dependee; /* * open pg_attribute *************** *** 428,433 **** --- 430,440 ---- 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 **** --- 456,469 ---- 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 **** --- 500,516 ---- 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 * --- 848,853 ---- *************** *** 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 --- 1041,1058 ---- 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 *************** *** 1176,1186 **** */ void heap_drop_with_catalog(Oid rid, ! bool allow_system_table_mods) { Relation rel; Oid toasttableOid; ! int i; /* * Open and lock the relation. --- 1073,1087 ---- */ void heap_drop_with_catalog(Oid rid, ! bool allow_system_table_mods, ! int behavior) { Relation rel; Oid toasttableOid; ! int i, natts; ! ObjectAddress myself; ! HeapTuple tuple; ! bool relHasOids; /* * Open and lock the relation. *************** *** 1206,1228 **** 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 --- 1107,1157 ---- 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; ! relHasOids = ((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 column first due to abilities like Primary Key on Oid. */ ! 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. */ ! if (relHasOids) ! { ! myself.objectSubId = ObjectIdAttributeNumber; ! dependDelete(&myself, behavior); ! } ! ! for (i = natts; i >= 0; i--) ! { ! myself.objectSubId = i; ! dependDelete(&myself, behavior); ! } /* * delete attribute tuples *************** *** 1236,1247 **** RemoveStatistics(rel); - RemoveConstraints(rel); - /* ! * delete type tuple */ ! DeleteTypeTuple(rel); /* * delete relation tuple --- 1165,1176 ---- RemoveStatistics(rel); /* ! * Remove constraints if necessary ! * ! * Should be updated to use pg_depend methods */ ! RemoveConstraints(rel); /* * delete relation tuple *************** *** 1265,1274 **** * flush the relation from the relcache */ RelationForgetRelation(rid); - - /* If it has a toast table, recurse to get rid of that too */ - if (OidIsValid(toasttableOid)) - heap_drop_with_catalog(toasttableOid, true); } --- 1194,1199 ---- 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/21 01:51:41 *************** *** 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" *************** *** 563,568 **** --- 565,572 ---- 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); /* --- 602,608 ---- else indexTupDesc = ConstructTupleDescriptor(heapRelation, indexInfo->ii_NumKeyAttrs, ! indexInfo->ii_KeyAttrNumbers, classObjectId); /* *************** *** 632,637 **** --- 636,669 ---- */ 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 */ *************** *** 700,706 **** * ---------------------------------------------------------------- */ void ! index_drop(Oid indexId) { Oid heapId; Relation userHeapRelation; --- 732,738 ---- * ---------------------------------------------------------------- */ void ! index_drop(Oid indexId, int behavior) { Oid heapId; Relation userHeapRelation; *************** *** 711,716 **** --- 743,750 ---- HeapTuple tuple; int16 attnum; int i; + + ObjectAddress myself; Assert(OidIsValid(indexId)); *************** *** 820,825 **** --- 854,864 ---- heap_close(userHeapRelation, NoLock); RelationForgetRelation(indexId); + + myself.classId = RelOid_pg_class; + myself.objectId = indexId; + myself.objectSubId = 0; + dependDelete(&myself, behavior); } /* ---------------------------------------------------------------- Index: src/backend/catalog/indexing.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/indexing.c,v retrieving revision 1.92 diff -c -r1.92 indexing.c *** src/backend/catalog/indexing.c 2002/04/19 16:36:08 1.92 --- src/backend/catalog/indexing.c 2002/04/21 01:51:42 *************** *** 47,52 **** --- 47,54 ---- {ClassNameNspIndex, ClassOidIndex}; char *Name_pg_database_indices[Num_pg_database_indices] = {DatabaseNameIndex, DatabaseOidIndex}; + char *Name_pg_depend_indices[Num_pg_depend_indices] = + {DependDependerIndex, DependDependeeIndex}; char *Name_pg_group_indices[Num_pg_group_indices] = {GroupNameIndex, GroupSysidIndex}; char *Name_pg_index_indices[Num_pg_index_indices] = Index: src/backend/catalog/namespace.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/namespace.c,v retrieving revision 1.11 diff -c -r1.11 namespace.c *** src/backend/catalog/namespace.c 2002/04/17 20:57:56 1.11 --- src/backend/catalog/namespace.c 2002/04/21 01:51:43 *************** *** 25,30 **** --- 25,31 ---- #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/namespace.h" + #include "catalog/pg_depend.h" #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" *************** *** 1023,1029 **** { Oid reloid = (Oid) lfirsti(lptr); ! heap_drop_with_catalog(reloid, true); /* * Advance cmd counter to make catalog changes visible, in case * a later entry depends on this one. --- 1024,1034 ---- { Oid reloid = (Oid) lfirsti(lptr); ! /* ! * Cascade through all objects which depend on this one, ! * temporary or otherwise. ! */ ! heap_drop_with_catalog(reloid, true, DEPEND_CASCADE); /* * Advance cmd counter to make catalog changes visible, in case * a later entry depends on this one. 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/21 01:51:44 *************** *** 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,224 ---- 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 */ + if (values[Anum_pg_aggregate_aggfinalfn - 1] != InvalidOid) + { + 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.66 diff -c -r1.66 pg_operator.c *** src/backend/catalog/pg_operator.c 2002/04/16 23:08:10 1.66 --- src/backend/catalog/pg_operator.c 2002/04/21 01:51:44 *************** *** 21,26 **** --- 21,28 ---- #include "catalog/catname.h" #include "catalog/indexing.h" #include "catalog/namespace.h" + #include "catalog/pg_depend.h" + #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" #include "miscadmin.h" *************** *** 262,267 **** --- 264,270 ---- heap_insert(pg_operator_desc, tup); operatorObjectId = tup->t_data->t_oid; + /* Keep indexes up to date */ if (RelationGetForm(pg_operator_desc)->relhasindex) { Relation idescs[Num_pg_operator_indices]; *************** *** 403,408 **** --- 406,414 ---- TupleDesc tupDesc; int i; + ObjectAddress myself, + dependee; + /* * Sanity checks */ *************** *** 658,663 **** --- 664,765 ---- 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/21 01:51:45 *************** *** 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,361 ---- } 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 Types are skipped in it's an InvalidOid (opaque) or if + * the type is a shell type (prevent a type <-> function dependency) + */ + if (returnType != InvalidOid && get_typisdefined(returnType)) + { + 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/21 01:51:45 *************** *** 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/21 01:51:46 *************** *** 26,31 **** --- 26,32 ---- #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" *************** *** 135,141 **** void ! RemoveAggregate(List *aggName, TypeName *aggType) { Relation relation; HeapTuple tup; --- 136,142 ---- void ! RemoveAggregate(List *aggName, TypeName *aggType, int behavior) { Relation relation; HeapTuple tup; *************** *** 179,184 **** --- 180,188 ---- 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, behavior); /* Delete any comments associated with this function */ DeleteComments(procOid, RelationGetRelid(relation)); Index: src/backend/commands/cluster.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/cluster.c,v retrieving revision 1.78 diff -c -r1.78 cluster.c *** src/backend/commands/cluster.c 2002/04/15 05:22:03 1.78 --- src/backend/commands/cluster.c 2002/04/21 01:51:48 *************** *** 26,31 **** --- 26,32 ---- #include "access/heapam.h" #include "catalog/heap.h" #include "catalog/index.h" + #include "catalog/pg_depend.h" #include "catalog/pg_index.h" #include "catalog/pg_proc.h" #include "commands/cluster.h" *************** *** 118,125 **** CommandCounterIncrement(); ! /* Destroy old heap (along with its index) and rename new. */ ! heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods); CommandCounterIncrement(); --- 119,129 ---- CommandCounterIncrement(); ! /* ! * Destroy old heap (along with its index) and rename new without ! * blowing away objects which depend on this one. ! */ ! heap_drop_with_catalog(OIDOldHeap, allowSystemTableMods, DEPEND_IMPLICITONLY); CommandCounterIncrement(); Index: src/backend/commands/functioncmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/functioncmds.c,v retrieving revision 1.2 diff -c -r1.2 functioncmds.c *** src/backend/commands/functioncmds.c 2002/04/21 00:26:42 1.2 --- src/backend/commands/functioncmds.c 2002/04/21 01:51:48 *************** *** 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" *************** *** 377,382 **** --- 378,384 ---- /* * RemoveFunction + * RemoveFunctionById * Deletes a function. * * Exceptions: *************** *** 386,400 **** */ void RemoveFunction(List *functionName, /* function name to be removed */ ! List *argTypes) /* list of TypeName nodes */ { Oid funcOid; - Relation relation; - HeapTuple tup; funcOid = LookupFuncNameTypeNames(functionName, argTypes, true, "RemoveFunction"); relation = heap_openr(ProcedureRelationName, RowExclusiveLock); tup = SearchSysCache(PROCOID, --- 388,410 ---- */ void RemoveFunction(List *functionName, /* function name to be removed */ ! List *argTypes, /* list of TypeName nodes */ ! int behavior) { Oid funcOid; funcOid = LookupFuncNameTypeNames(functionName, argTypes, true, "RemoveFunction"); + RemoveFunctionById(funcOid, behavior); + }; + + void + RemoveFunctionById(Oid funcOid, int behavior) + { + Relation relation; + HeapTuple tup; + relation = heap_openr(ProcedureRelationName, RowExclusiveLock); tup = SearchSysCache(PROCOID, *************** *** 402,424 **** 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "RemoveFunction: couldn't find tuple for function %s", ! NameListToString(functionName)); if (!pg_proc_ownercheck(funcOid, GetUserId())) elog(ERROR, "RemoveFunction: function '%s': permission denied", ! NameListToString(functionName)); if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) elog(ERROR, "RemoveFunction: function '%s' is an aggregate" "\n\tUse DROP AGGREGATE to remove it", ! NameListToString(functionName)); ! if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId) ! { ! /* "Helpful" WARNING when removing a builtin function ... */ ! elog(WARNING, "Removing built-in function \"%s\"", ! NameListToString(functionName)); ! } /* Delete any comments associated with this function */ DeleteComments(funcOid, RelationGetRelid(relation)); --- 412,433 ---- 0, 0, 0); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "RemoveFunction: couldn't find tuple for function %s", ! get_func_name(funcOid)); if (!pg_proc_ownercheck(funcOid, GetUserId())) elog(ERROR, "RemoveFunction: function '%s': permission denied", ! get_func_name(funcOid)); if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) elog(ERROR, "RemoveFunction: function '%s' is an aggregate" "\n\tUse DROP AGGREGATE to remove it", ! get_func_name(funcOid)); ! /* ! * Deal with dependencies ! * Manages system function restrictions for us as well. ! */ ! dependDeleteTuple(tup, relation, behavior); /* Delete any comments associated with this function */ DeleteComments(funcOid, RelationGetRelid(relation)); Index: src/backend/commands/indexcmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/indexcmds.c,v retrieving revision 1.71 diff -c -r1.71 indexcmds.c *** src/backend/commands/indexcmds.c 2002/04/17 20:57:56 1.71 --- src/backend/commands/indexcmds.c 2002/04/21 01:51:49 *************** *** 547,553 **** * ... */ void ! RemoveIndex(RangeVar *relation) { Oid indOid; HeapTuple tuple; --- 547,553 ---- * ... */ void ! RemoveIndex(RangeVar *relation, int behavior) { Oid indOid; HeapTuple tuple; *************** *** 565,571 **** ReleaseSysCache(tuple); ! index_drop(indOid); } /* --- 565,571 ---- ReleaseSysCache(tuple); ! index_drop(indOid, behavior); } /* Index: src/backend/commands/operatorcmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/operatorcmds.c,v retrieving revision 1.2 diff -c -r1.2 operatorcmds.c *** src/backend/commands/operatorcmds.c 2002/04/16 23:08:10 1.2 --- src/backend/commands/operatorcmds.c 2002/04/21 01:51:49 *************** *** 37,42 **** --- 37,43 ---- #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" *************** *** 44,49 **** --- 45,51 ---- #include "parser/parse_oper.h" #include "parser/parse_type.h" #include "utils/acl.h" + #include "utils/lsyscache.h" #include "utils/syscache.h" *************** *** 201,206 **** --- 203,209 ---- /* * RemoveOperator + * RemoveOperatorById * Deletes an operator. * * Exceptions: *************** *** 212,226 **** void RemoveOperator(List *operatorName, /* operator name */ TypeName *typeName1, /* left argument type name */ ! TypeName *typeName2) /* right argument type name */ { Oid operOid; - Relation relation; - HeapTuple tup; operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2, "RemoveOperator"); relation = heap_openr(OperatorRelationName, RowExclusiveLock); tup = SearchSysCacheCopy(OPEROID, --- 215,236 ---- void RemoveOperator(List *operatorName, /* operator name */ TypeName *typeName1, /* left argument type name */ ! TypeName *typeName2, /* right argument type name */ ! int behavior) { Oid operOid; operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2, "RemoveOperator"); + RemoveOperatorById(operOid, behavior); + } + + void + RemoveOperatorById(Oid operOid, int behavior) + { + Relation relation; + HeapTuple tup; relation = heap_openr(OperatorRelationName, RowExclusiveLock); tup = SearchSysCacheCopy(OPEROID, *************** *** 229,240 **** if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'", ! NameListToString(operatorName)); if (!pg_oper_ownercheck(operOid, GetUserId())) elog(ERROR, "RemoveOperator: operator '%s': permission denied", ! NameListToString(operatorName)); /* Delete any comments associated with this operator */ DeleteComments(operOid, RelationGetRelid(relation)); --- 239,253 ---- if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'", ! get_opname(operOid)); if (!pg_oper_ownercheck(operOid, GetUserId())) elog(ERROR, "RemoveOperator: operator '%s': permission denied", ! get_opname(operOid)); + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, behavior); + /* Delete any comments associated with this operator */ DeleteComments(operOid, 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/21 01:51:49 *************** *** 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" *************** *** 48,53 **** --- 49,57 ---- TupleDesc tupDesc; int i; + ObjectAddress myself, + dependee; + /* * Check permission */ *************** *** 79,84 **** --- 83,93 ---- 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 **** --- 122,135 ---- 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 **** --- 169,177 ---- if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl) elog(ERROR, "Language %s isn't a created procedural language", languageName); + + /* Deal with Dependencies */ + dependDeleteTuple(langTup, rel, stmt->behavior); 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.5 diff -c -r1.5 tablecmds.c *** src/backend/commands/tablecmds.c 2002/04/19 23:13:54 1.5 --- src/backend/commands/tablecmds.c 2002/04/21 01:51:53 *************** *** 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" *************** *** 124,130 **** 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. --- 125,132 ---- 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. *************** *** 261,266 **** --- 263,278 ---- 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) { *************** *** 1800,1805 **** --- 1812,1819 ---- * CREATE TABLE. * * First, scan schema to find new column defaults. + * + * At the same time we'll store column dependencies */ rawDefaults = NIL; attnum = 0; *************** *** 1811,1816 **** --- 1825,1848 ---- attnum++; + /* + * Seek for serial dependency + * The sequence must have been created first! + */ + if (colDef->typename->serial != NULL) { + ObjectAddress myself, + depender; + + myself.classId = RelOid_pg_class; + myself.objectId = relationId; + myself.objectSubId = attnum; + + depender.classId = RelOid_pg_class; + depender.objectId = RangeVarGetRelid(colDef->typename->serial, false); + depender.objectSubId = 0; + dependCreate(&depender, &myself, true); + } + if (colDef->raw_default == NULL) continue; Assert(colDef->cooked_default == NULL); *************** *** 1848,1859 **** * themselves will be destroyed, too. */ void ! RemoveRelation(const RangeVar *relation) { Oid relOid; relOid = RangeVarGetRelid(relation, false); ! heap_drop_with_catalog(relOid, allowSystemTableMods); } /* --- 1880,1891 ---- * themselves will be destroyed, too. */ void ! RemoveRelation(const RangeVar *relation, int behavior) { Oid relOid; relOid = RangeVarGetRelid(relation, false); ! heap_drop_with_catalog(relOid, allowSystemTableMods, behavior); } /* Index: src/backend/commands/trigger.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v retrieving revision 1.114 diff -c -r1.114 trigger.c *** src/backend/commands/trigger.c 2002/04/19 16:36:08 1.114 --- src/backend/commands/trigger.c 2002/04/21 01:51:57 *************** *** 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" *************** *** 73,78 **** --- 74,82 ---- char constrtrigname[NAMEDATALEN]; char *constrname = ""; Oid constrrelid = InvalidOid; + Oid insertOid, insertTupOid; + ObjectAddress myself, + dependee; rel = heap_openrv(stmt->relation, AccessExclusiveLock); *************** *** 266,271 **** --- 270,277 ---- tuple = heap_formtuple(tgrel->rd_att, values, nulls); + insertOid = tgrel->rd_id; + /* * Insert tuple into pg_trigger. */ *************** *** 273,278 **** --- 279,288 ---- 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); *************** *** 301,306 **** --- 311,344 ---- 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... *************** *** 314,320 **** * DropTrigger - drop an individual trigger by name */ void ! DropTrigger(Oid relid, const char *trigname) { Relation rel; Relation tgrel; --- 352,358 ---- * DropTrigger - drop an individual trigger by name */ void ! DropTrigger(Oid relid, const char *trigname, int behavior) { Relation rel; Relation tgrel; *************** *** 361,368 **** --- 399,410 ---- { 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, behavior); + /* Delete any comments associated with this trigger */ DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel)); *************** *** 408,507 **** } /* ! * 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, TriggerRelidNameIndex, 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. --- 450,535 ---- } /* ! * DropTriggerById - Drop a trigger by it's OID */ void ! DropTriggerById(Oid trigId, int behavior) { ! 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, behavior); ! /* 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/21 01:51:59 *************** *** 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" *************** *** 260,271 **** * only work on scalar types. */ void ! 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); --- 261,269 ---- * only work on scalar types. */ void ! RemoveType(List *names, int behavior) { TypeName *typename; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeNode(TypeName); *************** *** 273,278 **** --- 271,290 ---- typename->typmod = -1; typename->arrayBounds = NIL; + RemoveTypeByTypeName(typename, behavior); + } + + /* + * TypeRemove + * Removes a datatype by the typename struct + */ + void + RemoveTypeByTypeName(TypeName *typename, int behavior) + { + Relation relation; + Oid typeoid; + HeapTuple tup; + relation = heap_openr(TypeRelationName, RowExclusiveLock); /* Use LookupTypeName here so that shell types can be removed. */ *************** *** 292,320 **** 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)); simple_heap_delete(relation, &tup->t_self); --- 304,312 ---- elog(ERROR, "RemoveType: type '%s': permission denied", TypeNameToString(typename)); ! /* Deal with dependencies */ ! dependDeleteTuple(tup, relation, behavior); DeleteComments(typeoid, RelationGetRelid(relation)); simple_heap_delete(relation, &tup->t_self); *************** *** 565,574 **** HeapTuple tup; char typtype; - /* CASCADE unsupported */ - if (behavior == CASCADE) - elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword"); - /* Make a TypeName so we can use standard type lookup machinery */ typename = makeNode(TypeName); typename->names = names; --- 557,562 ---- *************** *** 596,601 **** --- 584,592 ---- if (typtype != 'd') elog(ERROR, "%s is not a domain", TypeNameToString(typename)); + + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, behavior); /* Delete any comments associated with this type */ DeleteComments(typeoid, RelationGetRelid(relation)); Index: src/backend/commands/view.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/view.c,v retrieving revision 1.63 diff -c -r1.63 view.c *** src/backend/commands/view.c 2002/04/19 23:13:54 1.63 --- src/backend/commands/view.c 2002/04/21 01:52:00 *************** *** 255,261 **** *------------------------------------------------------------------ */ void ! RemoveView(const RangeVar *view) { Oid viewOid; --- 255,261 ---- *------------------------------------------------------------------ */ void ! RemoveView(const RangeVar *view, int behavior) { Oid viewOid; *************** *** 264,268 **** * We just have to drop the relation; the associated rules will be * cleaned up automatically. */ ! heap_drop_with_catalog(viewOid, allowSystemTableMods); } --- 264,268 ---- * We just have to drop the relation; the associated rules will be * cleaned up automatically. */ ! heap_drop_with_catalog(viewOid, allowSystemTableMods, behavior); } Index: src/backend/nodes/copyfuncs.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v retrieving revision 1.180 diff -c -r1.180 copyfuncs.c *** src/backend/nodes/copyfuncs.c 2002/04/18 20:01:09 1.180 --- src/backend/nodes/copyfuncs.c 2002/04/21 01:52:03 *************** *** 1637,1642 **** --- 1637,1643 ---- newnode->setof = from->setof; newnode->pct_type = from->pct_type; newnode->typmod = from->typmod; + newnode->serial = from->serial; Node_Copy(from, newnode, arrayBounds); return newnode; Index: src/backend/nodes/equalfuncs.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v retrieving revision 1.128 diff -c -r1.128 equalfuncs.c *** src/backend/nodes/equalfuncs.c 2002/04/18 20:01:09 1.128 --- src/backend/nodes/equalfuncs.c 2002/04/21 01:52:06 *************** *** 1588,1593 **** --- 1588,1595 ---- return false; if (!equal(a->arrayBounds, b->arrayBounds)) return false; + if (a->serial != b->serial) + return false; return true; } Index: src/backend/parser/analyze.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v retrieving revision 1.231 diff -c -r1.231 analyze.c *** src/backend/parser/analyze.c 2002/04/17 20:57:56 1.231 --- src/backend/parser/analyze.c 2002/04/21 01:52:09 *************** *** 824,835 **** --- 824,837 ---- A_Const *snamenode; FuncCall *funccallnode; CreateSeqStmt *seqstmt; + RangeVar *srvar; /* * Determine name and namespace to use for the sequence. */ sname = makeObjectName(cxt->relation->relname, column->colname, "seq"); snamespace = get_namespace_name(RangeVarGetCreationNamespace(cxt->relation)); + srvar=makeRangeVar(snamespace, sname); elog(NOTICE, "%s will create implicit sequence '%s' for SERIAL column '%s.%s'", cxt->stmtType, sname, cxt->relation->relname, column->colname); *************** *** 840,849 **** * CREATE/ALTER TABLE. */ seqstmt = makeNode(CreateSeqStmt); ! seqstmt->sequence = makeRangeVar(snamespace, sname); seqstmt->options = NIL; cxt->blist = lappend(cxt->blist, seqstmt); /* * Create appropriate constraints for SERIAL. We do this in full, --- 842,857 ---- * CREATE/ALTER TABLE. */ seqstmt = makeNode(CreateSeqStmt); ! seqstmt->sequence = srvar; seqstmt->options = NIL; cxt->blist = lappend(cxt->blist, seqstmt); + + /* + * Keep the serial name so that lateron the table can create an + * implicit dependency to drop the serial with the table + */ + column->typename->serial = srvar; /* * Create appropriate constraints for SERIAL. We do this in full, Index: src/backend/parser/gram.y =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.306 diff -c -r2.306 gram.y *** src/backend/parser/gram.y 2002/04/21 00:26:43 2.306 --- src/backend/parser/gram.y 2002/04/21 01:52:16 *************** *** 52,57 **** --- 52,58 ---- #include "access/htup.h" #include "catalog/index.h" + #include "catalog/pg_depend.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/params.h" *************** *** 1224,1236 **** | DROP DEFAULT { $$ = NULL; } ; ! drop_behavior: CASCADE { $$ = CASCADE; } ! | RESTRICT { $$ = RESTRICT; } ; ! opt_drop_behavior: CASCADE { $$ = CASCADE; } ! | RESTRICT { $$ = RESTRICT; } ! | /* EMPTY */ { $$ = RESTRICT; /* default */ } ; --- 1225,1237 ---- | DROP DEFAULT { $$ = NULL; } ; ! drop_behavior: CASCADE { $$ = DEPEND_CASCADE; } ! | RESTRICT { $$ = DEPEND_RESTRICT; } ; ! opt_drop_behavior: CASCADE { $$ = DEPEND_CASCADE; } ! | RESTRICT { $$ = DEPEND_RESTRICT; } ! | /* EMPTY */ { $$ = DEPEND_RESTRICT; /* default */ } ; *************** *** 1846,1852 **** n->plname = $5; n->plhandler = $7; n->plcompiler = $8; ! n->pltrusted = $2; $$ = (Node *)n; } ; --- 1847,1853 ---- n->plname = $5; n->plhandler = $7; n->plcompiler = $8; ! n->pltrusted = $2; $$ = (Node *)n; } ; *************** *** 1869,1878 **** | /*EMPTY*/ { $$ = ""; } ; ! DropPLangStmt: DROP opt_procedural LANGUAGE ColId_or_Sconst { DropPLangStmt *n = makeNode(DropPLangStmt); n->plname = $4; $$ = (Node *)n; } ; --- 1870,1880 ---- | /*EMPTY*/ { $$ = ""; } ; ! DropPLangStmt: DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior { DropPLangStmt *n = makeNode(DropPLangStmt); n->plname = $4; + n->behavior = $5; $$ = (Node *)n; } ; *************** *** 2061,2071 **** ; ! DropTrigStmt: DROP TRIGGER name ON qualified_name { DropPropertyStmt *n = makeNode(DropPropertyStmt); n->relation = $5; n->property = $3; n->removeType = DROP_TRIGGER; $$ = (Node *) n; } --- 2063,2074 ---- ; ! DropTrigStmt: DROP TRIGGER name ON qualified_name opt_drop_behavior { DropPropertyStmt *n = makeNode(DropPropertyStmt); n->relation = $5; n->property = $3; + n->behavior = $6; n->removeType = DROP_TRIGGER; $$ = (Node *) n; } *************** *** 2834,2853 **** * *****************************************************************************/ ! RemoveFuncStmt: DROP FUNCTION func_name func_args { RemoveFuncStmt *n = makeNode(RemoveFuncStmt); n->funcname = $3; n->args = $4; $$ = (Node *)n; } ; ! RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')' { RemoveAggrStmt *n = makeNode(RemoveAggrStmt); n->aggname = $3; n->aggtype = $5; $$ = (Node *)n; } ; --- 2837,2858 ---- * *****************************************************************************/ ! RemoveFuncStmt: DROP FUNCTION func_name func_args opt_drop_behavior { RemoveFuncStmt *n = makeNode(RemoveFuncStmt); n->funcname = $3; n->args = $4; + n->behavior = $5; $$ = (Node *)n; } ; ! RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')' opt_drop_behavior { RemoveAggrStmt *n = makeNode(RemoveAggrStmt); n->aggname = $3; n->aggtype = $5; + n->behavior = $7; $$ = (Node *)n; } ; *************** *** 2856,2866 **** | '*' { $$ = NULL; } ; ! RemoveOperStmt: DROP OPERATOR any_operator '(' oper_argtypes ')' { RemoveOperStmt *n = makeNode(RemoveOperStmt); n->opname = $3; n->args = $5; $$ = (Node *)n; } ; --- 2861,2872 ---- | '*' { $$ = NULL; } ; ! RemoveOperStmt: DROP OPERATOR any_operator '(' oper_argtypes ')' opt_drop_behavior { RemoveOperStmt *n = makeNode(RemoveOperStmt); n->opname = $3; n->args = $5; + n->behavior = $7; $$ = (Node *)n; } ; *************** *** 3015,3025 **** ; ! DropRuleStmt: DROP RULE name ON qualified_name { DropPropertyStmt *n = makeNode(DropPropertyStmt); n->relation = $5; n->property = $3; n->removeType = DROP_RULE; $$ = (Node *) n; } --- 3021,3032 ---- ; ! DropRuleStmt: DROP RULE name ON qualified_name opt_drop_behavior { DropPropertyStmt *n = makeNode(DropPropertyStmt); n->relation = $5; n->property = $3; + n->behavior = $6; n->removeType = DROP_RULE; $$ = (Node *) n; } Index: src/backend/rewrite/rewriteDefine.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v retrieving revision 1.68 diff -c -r1.68 rewriteDefine.c *** src/backend/rewrite/rewriteDefine.c 2002/04/19 23:13:54 1.68 --- src/backend/rewrite/rewriteDefine.c 2002/04/21 01:52:17 *************** *** 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(eventrel_oid, 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(eventrel_oid, 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.48 diff -c -r1.48 rewriteRemove.c *** src/backend/rewrite/rewriteRemove.c 2002/04/18 20:01:09 1.48 --- src/backend/rewrite/rewriteRemove.c 2002/04/21 01:52:17 *************** *** 17,32 **** --- 17,35 ---- #include "access/genam.h" #include "access/heapam.h" #include "catalog/catname.h" + #include "catalog/pg_depend.h" #include "catalog/indexing.h" #include "catalog/pg_rewrite.h" #include "commands/comment.h" #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, int behavior); /* * RemoveRewriteRule *************** *** 34,48 **** * Delete a rule given its name. */ void ! RemoveRewriteRule(Oid owningRel, const char *ruleName) { Relation RewriteRelation; - Relation event_relation; HeapTuple tuple; - Oid ruleId; - Oid eventRelationOid; - bool hasMoreRules; - int32 aclcheck_result; /* * Open the pg_rewrite relation. --- 37,46 ---- * Delete a rule given its name. */ void ! RemoveRewriteRule(Oid owningRel, const char *ruleName, int behavior) { Relation RewriteRelation; HeapTuple tuple; /* * Open the pg_rewrite relation. *************** *** 58,68 **** 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 --- 56,125 ---- 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, behavior); + + heap_freetuple(tuple); + + heap_close(RewriteRelation, RowExclusiveLock); + } + + void + RemoveRewriteRuleById(Oid ruleId, int behavior) + { + 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, behavior); + } + + 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, int behavior) + { + + 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 *************** *** 90,116 **** 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. * --- 147,171 ---- 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, behavior); + /* * 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. * *************** *** 122,171 **** /* 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; ! SysScanDesc scanDesc; ! ScanKeyData scanKeyData; ! HeapTuple tuple; ! ! /* ! * Open the pg_rewrite relation. ! */ ! RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock); ! ! /* ! * Scan pg_rewrite for all the tuples that have the same ev_class ! * as relid (the relation to be removed). ! */ ! ScanKeyEntryInitialize(&scanKeyData, ! 0, ! Anum_pg_rewrite_ev_class, ! F_OIDEQ, ! ObjectIdGetDatum(relid)); ! ! scanDesc = systable_beginscan(RewriteRelation, ! RewriteRelRulenameIndex, ! true, SnapshotNow, ! 1, &scanKeyData); ! ! while (HeapTupleIsValid(tuple = systable_getnext(scanDesc))) ! { ! /* Delete any comments associated with this rule */ ! DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation)); ! ! simple_heap_delete(RewriteRelation, &tuple->t_self); ! } ! ! systable_endscan(scanDesc); ! ! heap_close(RewriteRelation, RowExclusiveLock); ! } --- 177,180 ---- /* Close rel, but keep lock till commit... */ heap_close(event_relation, NoLock); ! } \ No newline at end of file Index: src/backend/tcop/utility.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/tcop/utility.c,v retrieving revision 1.150 diff -c -r1.150 utility.c *** src/backend/tcop/utility.c 2002/04/18 20:01:09 1.150 --- src/backend/tcop/utility.c 2002/04/21 01:52:18 *************** *** 291,320 **** case DROP_TABLE: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_RELATION); ! RemoveRelation(rel); break; case DROP_SEQUENCE: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_SEQUENCE); ! RemoveRelation(rel); break; case DROP_VIEW: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_VIEW); ! RemoveView(rel); break; case DROP_INDEX: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_INDEX); ! RemoveIndex(rel); break; case DROP_TYPE: /* RemoveType does its own permissions checks */ ! RemoveType(names); break; case DROP_DOMAIN: --- 291,320 ---- case DROP_TABLE: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_RELATION); ! RemoveRelation(rel, stmt->behavior); break; case DROP_SEQUENCE: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_SEQUENCE); ! RemoveRelation(rel, stmt->behavior); break; case DROP_VIEW: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_VIEW); ! RemoveView(rel, stmt->behavior); break; case DROP_INDEX: rel = makeRangeVarFromNameList(names); CheckDropPermissions(rel, RELKIND_INDEX); ! RemoveIndex(rel, stmt->behavior); break; case DROP_TYPE: /* RemoveType does its own permissions checks */ ! RemoveType(names, stmt->behavior); break; case DROP_DOMAIN: *************** *** 574,580 **** { RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree; ! RemoveAggregate(stmt->aggname, stmt->aggtype); } break; --- 574,580 ---- { RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree; ! RemoveAggregate(stmt->aggname, stmt->aggtype, stmt->behavior); } break; *************** *** 582,588 **** { RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree; ! RemoveFunction(stmt->funcname, stmt->args); } break; --- 582,588 ---- { RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree; ! RemoveFunction(stmt->funcname, stmt->args, stmt->behavior); } break; *************** *** 592,598 **** TypeName *typenode1 = (TypeName *) lfirst(stmt->args); TypeName *typenode2 = (TypeName *) lsecond(stmt->args); ! RemoveOperator(stmt->opname, typenode1, typenode2); } break; --- 592,598 ---- TypeName *typenode1 = (TypeName *) lfirst(stmt->args); TypeName *typenode2 = (TypeName *) lsecond(stmt->args); ! RemoveOperator(stmt->opname, typenode1, typenode2, stmt->behavior); } break; *************** *** 720,730 **** { case DROP_RULE: /* RemoveRewriteRule checks permissions */ ! RemoveRewriteRule(relId, stmt->property); break; case DROP_TRIGGER: /* DropTrigger checks permissions */ ! DropTrigger(relId, stmt->property); break; } } --- 720,730 ---- { case DROP_RULE: /* RemoveRewriteRule checks permissions */ ! RemoveRewriteRule(relId, stmt->property, stmt->behavior); break; case DROP_TRIGGER: /* DropTrigger checks permissions */ ! DropTrigger(relId, stmt->property, stmt->behavior); break; } } Index: src/backend/utils/cache/lsyscache.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v retrieving revision 1.70 diff -c -r1.70 lsyscache.c *** src/backend/utils/cache/lsyscache.c 2002/04/16 23:08:11 1.70 --- src/backend/utils/cache/lsyscache.c 2002/04/21 01:52:20 *************** *** 586,591 **** --- 586,616 ---- } /* + * get_func_name + * Given procedure id, return the function's result name. + */ + char * + get_func_name(Oid funcid) + { + HeapTuple tp; + + tp = SearchSysCache(PROCOID, + ObjectIdGetDatum(funcid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_proc funcTup = (Form_pg_proc) GETSTRUCT(tp); + char *result; + + result = pstrdup(NameStr(funcTup->proname)); + ReleaseSysCache(tp); + return result; + } + else + return NULL; + } + + /* * func_volatile * Given procedure id, return the function's provolatile flag. */ Index: src/include/postgres.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/postgres.h,v retrieving revision 1.56 diff -c -r1.56 postgres.h *** src/include/postgres.h 2001/11/05 17:46:31 1.56 --- src/include/postgres.h 2002/04/21 01:52:23 *************** *** 598,608 **** --- 598,611 ---- #define BOOTSTRAP + #define PINWRITE + #define BKI_WITHOUT_OIDS /* these need to expand into some harmless, repeatable declaration */ #define DATA(x) extern int errno #define DESCR(x) extern int errno + #define PINTABLE(x) extern int errno #define BKI_BEGIN #define BKI_END 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/21 01:52:23 *************** *** 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/heap.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/heap.h,v retrieving revision 1.49 diff -c -r1.49 heap.h *** src/include/catalog/heap.h 2002/03/31 06:26:32 1.49 --- src/include/catalog/heap.h 2002/04/21 01:52:23 *************** *** 42,48 **** bool relhasoids, bool allow_system_table_mods); ! extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods); extern void heap_truncate(Oid rid); --- 42,48 ---- bool relhasoids, bool allow_system_table_mods); ! extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods, int behavior); extern void heap_truncate(Oid rid); Index: src/include/catalog/index.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/index.h,v retrieving revision 1.47 diff -c -r1.47 index.h *** src/include/catalog/index.h 2002/03/31 06:26:32 1.47 --- src/include/catalog/index.h 2002/04/21 01:52:24 *************** *** 37,43 **** bool primary, bool allow_system_table_mods); ! extern void index_drop(Oid indexId); extern IndexInfo *BuildIndexInfo(Form_pg_index indexStruct); --- 37,43 ---- bool primary, bool allow_system_table_mods); ! extern void index_drop(Oid indexId, int behavior); extern IndexInfo *BuildIndexInfo(Form_pg_index indexStruct); Index: src/include/catalog/indexing.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/indexing.h,v retrieving revision 1.66 diff -c -r1.66 indexing.h *** src/include/catalog/indexing.h 2002/04/19 16:36:08 1.66 --- src/include/catalog/indexing.h 2002/04/21 01:52:24 *************** *** 28,33 **** --- 28,34 ---- #define Num_pg_attrdef_indices 1 #define Num_pg_class_indices 2 #define Num_pg_database_indices 2 + #define Num_pg_depend_indices 2 #define Num_pg_description_indices 1 #define Num_pg_group_indices 2 #define Num_pg_index_indices 2 *************** *** 61,66 **** --- 62,69 ---- #define ClassOidIndex "pg_class_oid_index" #define DatabaseNameIndex "pg_database_datname_index" #define DatabaseOidIndex "pg_database_oid_index" + #define DependDependerIndex "pg_depend_depender_index" + #define DependDependeeIndex "pg_depend_dependee_index" #define DescriptionObjIndex "pg_description_o_c_o_index" #define GroupNameIndex "pg_group_name_index" #define GroupSysidIndex "pg_group_sysid_index" *************** *** 100,105 **** --- 103,109 ---- extern char *Name_pg_attrdef_indices[]; extern char *Name_pg_class_indices[]; extern char *Name_pg_database_indices[]; + extern char *Name_pg_depend_indices[]; extern char *Name_pg_description_indices[]; extern char *Name_pg_group_indices[]; extern char *Name_pg_index_indices[]; *************** *** 190,195 **** --- 194,204 ---- DECLARE_UNIQUE_INDEX(pg_trigger_oid_index on pg_trigger using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index on pg_type using btree(typname name_ops, typnamespace oid_ops)); + + /* This following index is not used for a cache and is not unique */ + DECLARE_INDEX(pg_depend_depender_index on pg_depend using btree(classid oid_ops, objid oid_ops, objsubid int4_ops)); + /* This following index is not used for a cache and is not unique */ + DECLARE_INDEX(pg_depend_dependee_index on pg_depend using btree(depclassid oid_ops, depobjid oid_ops, depobjsubid int4_ops)); /* last step of initialization script: build the indices declared above */ BUILD_INDICES Index: src/include/catalog/pg_class.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_class.h,v retrieving revision 1.67 diff -c -r1.67 pg_class.h *** src/include/catalog/pg_class.h 2002/04/21 00:26:43 1.67 --- src/include/catalog/pg_class.h 2002/04/21 01:52:24 *************** *** 127,132 **** --- 127,133 ---- #define Anum_pg_class_relhassubclass 23 #define Anum_pg_class_relacl 24 + /* ---------------- * initial contents of pg_class * Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v retrieving revision 1.228 diff -c -r1.228 pg_proc.h *** src/include/catalog/pg_proc.h 2002/04/18 20:01:10 1.228 --- src/include/catalog/pg_proc.h 2002/04/21 01:52:35 *************** *** 94,99 **** --- 94,102 ---- #define Anum_pg_proc_probin 19 #define Anum_pg_proc_proacl 20 + /* Make the below functions permenant */ + PINTABLE(1255); + /* ---------------- * initial contents of pg_proc * ---------------- Index: src/include/catalog/pg_type.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_type.h,v retrieving revision 1.120 diff -c -r1.120 pg_type.h *** src/include/catalog/pg_type.h 2002/04/21 00:26:43 1.120 --- src/include/catalog/pg_type.h 2002/04/21 01:52:36 *************** *** 228,233 **** --- 228,235 ---- #define Anum_pg_type_typdefaultbin 22 #define Anum_pg_type_typdefault 23 + /* Make the below types permenant */ + PINTABLE(1247); /* ---------------- * initial contents of pg_type Index: src/include/commands/defrem.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/commands/defrem.h,v retrieving revision 1.36 diff -c -r1.36 defrem.h *** src/include/commands/defrem.h 2002/04/16 23:08:12 1.36 --- src/include/commands/defrem.h 2002/04/21 01:52:36 *************** *** 29,35 **** bool primary, Expr *predicate, List *rangetable); ! extern void RemoveIndex(RangeVar *relation); extern void ReindexIndex(RangeVar *indexRelation, bool force); extern void ReindexTable(RangeVar *relation, bool force); extern void ReindexDatabase(const char *databaseName, bool force, bool all); --- 29,35 ---- bool primary, Expr *predicate, List *rangetable); ! extern void RemoveIndex(RangeVar *relation, int behavior); extern void ReindexIndex(RangeVar *indexRelation, bool force); extern void ReindexTable(RangeVar *relation, bool force); extern void ReindexDatabase(const char *databaseName, bool force, bool all); *************** *** 39,61 **** */ extern void CreateFunction(ProcedureStmt *stmt); ! extern void RemoveFunction(List *functionName, List *argTypes); extern void DefineOperator(List *names, List *parameters); extern void RemoveOperator(List *operatorName, ! TypeName *typeName1, TypeName *typeName2); extern void DefineAggregate(List *names, List *parameters); ! extern void RemoveAggregate(List *aggName, TypeName *aggType); 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); --- 39,62 ---- */ extern void CreateFunction(ProcedureStmt *stmt); ! extern void RemoveFunction(List *functionName, List *argTypes, int behavior); ! extern void RemoveFunctionById(Oid funcOid, int behavior); extern void DefineOperator(List *names, List *parameters); extern void RemoveOperator(List *operatorName, ! TypeName *typeName1, TypeName *typeName2, int behavior); ! extern void RemoveOperatorById(Oid operOid, int behavior); extern void DefineAggregate(List *names, List *parameters); ! extern void RemoveAggregate(List *aggName, TypeName *aggType, int behavior); extern void DefineType(List *names, List *parameters); ! extern void RemoveType(List *names, int behavior); ! extern void RemoveTypeByTypeName(TypeName *typename, int behavior); 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/tablecmds.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/commands/tablecmds.h,v retrieving revision 1.1 diff -c -r1.1 tablecmds.h *** src/include/commands/tablecmds.h 2002/04/15 05:22:04 1.1 --- src/include/commands/tablecmds.h 2002/04/21 01:52:36 *************** *** 48,54 **** extern Oid DefineRelation(CreateStmt *stmt, char relkind); ! extern void RemoveRelation(const RangeVar *relation); extern void TruncateRelation(const RangeVar *relation); --- 48,54 ---- extern Oid DefineRelation(CreateStmt *stmt, char relkind); ! extern void RemoveRelation(const RangeVar *relation, int behavior); extern void TruncateRelation(const RangeVar *relation); 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/21 01:52:36 *************** *** 102,109 **** extern void CreateTrigger(CreateTrigStmt *stmt); ! extern void DropTrigger(Oid relid, const char *trigname); ! extern void RelationRemoveTriggers(Relation rel); extern void RelationBuildTriggers(Relation relation); --- 102,109 ---- extern void CreateTrigger(CreateTrigStmt *stmt); ! extern void DropTrigger(Oid relid, const char *trigname, int behavior); ! extern void DropTriggerById(Oid trigId, int behavior); extern void RelationBuildTriggers(Relation relation); Index: src/include/commands/view.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/commands/view.h,v retrieving revision 1.14 diff -c -r1.14 view.h *** src/include/commands/view.h 2002/03/29 19:06:22 1.14 --- src/include/commands/view.h 2002/04/21 01:52:36 *************** *** 17,22 **** #include "nodes/parsenodes.h" extern void DefineView(const RangeVar *view, Query *view_parse); ! extern void RemoveView(const RangeVar *view); #endif /* VIEW_H */ --- 17,22 ---- #include "nodes/parsenodes.h" extern void DefineView(const RangeVar *view, Query *view_parse); ! extern void RemoveView(const RangeVar *view, int behavior); #endif /* VIEW_H */ Index: src/include/nodes/parsenodes.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v retrieving revision 1.173 diff -c -r1.173 parsenodes.h *** src/include/nodes/parsenodes.h 2002/04/21 00:26:43 1.173 --- src/include/nodes/parsenodes.h 2002/04/21 01:52:39 *************** *** 123,128 **** --- 123,129 ---- bool pct_type; /* %TYPE specified? */ int32 typmod; /* type modifier */ List *arrayBounds; /* array bounds */ + RangeVar *serial; /* Serial sequence reference*/ } TypeName; /* *************** *** 985,990 **** --- 986,992 ---- { NodeTag type; char *plname; /* PL name */ + int behavior; } DropPLangStmt; /* ---------------------- *************** *** 1117,1122 **** --- 1119,1125 ---- RangeVar *relation; /* owning relation */ char *property; /* name of rule, trigger, etc */ int removeType; + int behavior; } DropPropertyStmt; /* ---------------------- *************** *** 1208,1213 **** --- 1211,1217 ---- NodeTag type; List *aggname; /* aggregate to drop */ TypeName *aggtype; /* TypeName for input datatype, or NULL */ + int behavior; } RemoveAggrStmt; /* ---------------------- *************** *** 1219,1224 **** --- 1223,1229 ---- NodeTag type; List *funcname; /* function to drop */ List *args; /* types of the arguments */ + int behavior; } RemoveFuncStmt; /* ---------------------- *************** *** 1230,1235 **** --- 1235,1241 ---- NodeTag type; List *opname; /* operator to drop */ List *args; /* types of the arguments */ + int behavior; } RemoveOperStmt; /* ---------------------- Index: src/include/rewrite/rewriteRemove.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/rewrite/rewriteRemove.h,v retrieving revision 1.13 diff -c -r1.13 rewriteRemove.h *** src/include/rewrite/rewriteRemove.h 2002/04/18 20:01:11 1.13 --- src/include/rewrite/rewriteRemove.h 2002/04/21 01:52:39 *************** *** 14,20 **** #ifndef REWRITEREMOVE_H #define REWRITEREMOVE_H ! extern void RemoveRewriteRule(Oid owningRel, const char *ruleName); ! extern void RelationRemoveRules(Oid relid); #endif /* REWRITEREMOVE_H */ --- 14,20 ---- #ifndef REWRITEREMOVE_H #define REWRITEREMOVE_H ! extern void RemoveRewriteRule(Oid owningRel, const char *ruleName, int behavior); ! extern void RemoveRewriteRuleById(Oid ruleId, int behavior); #endif /* REWRITEREMOVE_H */ Index: src/include/utils/lsyscache.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/lsyscache.h,v retrieving revision 1.49 diff -c -r1.49 lsyscache.h *** src/include/utils/lsyscache.h 2002/04/05 00:31:35 1.49 --- src/include/utils/lsyscache.h 2002/04/21 01:52:39 *************** *** 38,43 **** --- 38,44 ---- extern RegProcedure get_oprrest(Oid opno); extern RegProcedure get_oprjoin(Oid opno); extern Oid get_func_rettype(Oid funcid); + extern char *get_func_name(Oid funcid); extern char func_volatile(Oid funcid); extern Oid get_relname_relid(const char *relname, Oid relnamespace); extern char *get_rel_name(Oid relid); Index: src/test/regress/parallel_schedule =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/parallel_schedule,v retrieving revision 1.9 diff -c -r1.9 parallel_schedule *** src/test/regress/parallel_schedule 2002/04/05 11:56:55 1.9 --- src/test/regress/parallel_schedule 2002/04/21 01:52:40 *************** *** 75,77 **** --- 75,79 ---- # ---------- # "plpgsql" cannot run concurrently with "rules" test: limit plpgsql temp domain + + test: drop Index: src/test/regress/serial_schedule =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/serial_schedule,v retrieving revision 1.9 diff -c -r1.9 serial_schedule *** src/test/regress/serial_schedule 2002/04/05 11:56:55 1.9 --- src/test/regress/serial_schedule 2002/04/21 01:52:40 *************** *** 82,85 **** --- 82,86 ---- test: plpgsql test: temp test: domain + test: drop 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/21 01:52:42 *************** *** 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/create_misc.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/create_misc.out,v retrieving revision 1.13 diff -c -r1.13 create_misc.out *** src/test/regress/expected/create_misc.out 2002/03/06 06:10:52 1.13 --- src/test/regress/expected/create_misc.out 2002/04/21 01:52:42 *************** *** 151,153 **** --- 151,159 ---- force | 100 (3 rows) + DROP TABLE serialTest; + -- Ensure that Serial sequences are dropped with the table + CREATE TABLE serialTest (f1 text, f2 serial); + NOTICE: CREATE TABLE will create implicit sequence 'serialtest_f2_seq' for SERIAL column 'serialtest.f2' + NOTICE: CREATE TABLE / UNIQUE will create implicit index 'serialtest_f2_key' for table 'serialtest' + DROP TABLE serialTest; Index: src/test/regress/expected/domain.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/domain.out,v retrieving revision 1.2 diff -c -r1.2 domain.out *** src/test/regress/expected/domain.out 2002/03/20 19:45:12 1.2 --- src/test/regress/expected/domain.out 2002/04/21 01:52:42 *************** *** 3,10 **** comment on domain domaindroptest is 'About to drop this..'; create domain basetypetest domaindroptest; ERROR: DefineDomain: domaindroptest is not a basetype - drop domain domaindroptest cascade; - ERROR: DROP DOMAIN does not support the CASCADE keyword drop domain domaindroptest; -- TEST Domains. create domain domainvarchar varchar(5); --- 3,8 ---- *************** *** 135,144 **** 3 | 12 | 5 | 3 | 3 | 88 | 8000 | 12.12 (3 rows) - drop sequence ddef4_seq; - drop table defaulttest; - drop domain ddef1 restrict; - drop domain ddef2 restrict; - drop domain ddef3 restrict; - drop domain ddef4 restrict; - drop domain ddef5 restrict; --- 133,135 ---- Index: src/test/regress/expected/foreign_key.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/foreign_key.out,v retrieving revision 1.15 diff -c -r1.15 foreign_key.out *** src/test/regress/expected/foreign_key.out 2002/04/19 16:36:08 1.15 --- src/test/regress/expected/foreign_key.out 2002/04/21 01:52:46 *************** *** 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 ---- Index: src/test/regress/expected/sanity_check.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/sanity_check.out,v retrieving revision 1.17 diff -c -r1.17 sanity_check.out *** src/test/regress/expected/sanity_check.out 2002/03/22 21:34:44 1.17 --- src/test/regress/expected/sanity_check.out 2002/04/21 01:52:46 *************** *** 39,44 **** --- 39,45 ---- pg_attribute | t pg_class | t pg_database | t + pg_depend | t pg_description | t pg_group | t pg_index | t *************** *** 56,62 **** pg_trigger | t pg_type | t road | t - serialtest | t shighway | t tenk1 | t tenk2 | t --- 57,62 ---- Index: src/test/regress/sql/create_misc.sql =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/create_misc.sql,v retrieving revision 1.9 diff -c -r1.9 create_misc.sql *** src/test/regress/sql/create_misc.sql 2001/05/21 16:54:46 1.9 --- src/test/regress/sql/create_misc.sql 2002/04/21 01:52:46 *************** *** 217,219 **** --- 217,226 ---- INSERT INTO serialTest VALUES ('wrong', NULL); SELECT * FROM serialTest; + + DROP TABLE serialTest; + + -- Ensure that Serial sequences are dropped with the table + CREATE TABLE serialTest (f1 text, f2 serial); + + DROP TABLE serialTest; Index: src/test/regress/sql/create_view.sql =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/create_view.sql,v retrieving revision 1.3 diff -c -r1.3 create_view.sql *** src/test/regress/sql/create_view.sql 2000/06/10 05:19:26 1.3 --- src/test/regress/sql/create_view.sql 2002/04/21 01:52:46 *************** *** 17,21 **** CREATE VIEW toyemp AS SELECT name, age, location, 12*salary AS annualsal ! FROM emp; ! --- 17,20 ---- CREATE VIEW toyemp AS SELECT name, age, location, 12*salary AS annualsal ! FROM emp; \ No newline at end of file Index: src/test/regress/sql/domain.sql =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/domain.sql,v retrieving revision 1.2 diff -c -r1.2 domain.sql *** src/test/regress/sql/domain.sql 2002/03/20 19:45:13 1.2 --- src/test/regress/sql/domain.sql 2002/04/21 01:52:46 *************** *** 6,12 **** create domain basetypetest domaindroptest; - drop domain domaindroptest cascade; drop domain domaindroptest; --- 6,11 ---- *************** *** 108,118 **** insert into defaulttest default values; insert into defaulttest default values; select * from defaulttest; - - drop sequence ddef4_seq; - drop table defaulttest; - drop domain ddef1 restrict; - drop domain ddef2 restrict; - drop domain ddef3 restrict; - drop domain ddef4 restrict; - drop domain ddef5 restrict; --- 107,109 ---- Index: src/test/regress/sql/drop.sql =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/drop.sql,v retrieving revision 1.5 diff -c -r1.5 drop.sql *** src/test/regress/sql/drop.sql 2001/10/03 20:54:22 1.5 --- src/test/regress/sql/drop.sql 2002/04/21 01:52:46 *************** *** 1,247 **** -- ! -- drop.source -- ! -- ! -- this will fail if the user is not the postgres superuser. ! -- if it does, don't worry about it (you can turn usersuper ! -- back on as "postgres"). too many people don't follow ! -- directions and run this as "postgres", though... ! -- ! UPDATE pg_user ! SET usesuper = 't'::bool ! WHERE usename = 'postgres'; ! ! ! -- ! -- FUNCTION REMOVAL ! -- ! DROP FUNCTION hobbies(person); ! ! DROP FUNCTION hobby_construct(text,text); ! ! DROP FUNCTION equipment(hobbies_r); ! ! DROP FUNCTION user_relns(); ! ! DROP FUNCTION widget_in(opaque); ! ! DROP FUNCTION widget_out(opaque); ! ! DROP FUNCTION pt_in_widget(point,widget); ! ! DROP FUNCTION overpaid(emp); ! ! DROP FUNCTION boxarea(box); ! ! DROP FUNCTION interpt_pp(path,path); ! ! DROP FUNCTION reverse_name(name); ! ! DROP FUNCTION oldstyle_length(int4, text); ! ! -- ! -- OPERATOR REMOVAL ! -- ! DROP OPERATOR ## (path, path); ! ! DROP OPERATOR <% (point, widget); ! ! -- left unary ! DROP OPERATOR @#@ (none, int4); ! ! -- right unary ! DROP OPERATOR #@# (int4, none); ! ! -- right unary ! DROP OPERATOR #%# (int4, none); ! ! ! -- ! -- ABSTRACT DATA TYPE REMOVAL ! -- ! DROP TYPE city_budget; ! ! DROP TYPE widget; ! ! ! -- ! -- RULE REMOVAL ! -- (is also tested in queries.source) ! -- ! ! -- ! -- AGGREGATE REMOVAL ! -- ! DROP AGGREGATE newavg (int4); ! ! DROP AGGREGATE newsum (int4); ! ! DROP AGGREGATE newcnt (int4); ! ! ! -- ! -- CLASS REMOVAL ! -- (inheritance hierarchies are deleted in reverse order) ! -- ! ! -- ! -- DROP ancillary data structures (i.e. indices) ! -- ! DROP INDEX onek_unique1; ! ! DROP INDEX onek_unique2; ! ! DROP INDEX onek_hundred; ! ! DROP INDEX onek_stringu1; ! ! DROP INDEX tenk1_unique1; ! ! DROP INDEX tenk1_unique2; ! ! DROP INDEX tenk1_hundred; ! ! DROP INDEX tenk2_unique1; ! ! DROP INDEX tenk2_unique2; ! ! DROP INDEX tenk2_hundred; ! ! -- DROP INDEX onek2_u1_prtl; ! ! -- DROP INDEX onek2_u2_prtl; ! ! -- DROP INDEX onek2_stu1_prtl; ! ! DROP INDEX rect2ind; ! ! DROP INDEX rix; ! ! DROP INDEX iix; - DROP INDEX six; ! DROP INDEX hash_i4_index; - DROP INDEX hash_name_index; ! DROP INDEX hash_txt_index; - DROP INDEX hash_f8_index; - - -- DROP INDEX hash_ovfl_index; - - DROP INDEX bt_i4_index; - - DROP INDEX bt_name_index; - - DROP INDEX bt_txt_index; - - DROP INDEX bt_f8_index; - - - DROP TABLE onek; - - DROP TABLE onek2; - - DROP TABLE tenk1; - - DROP TABLE tenk2; - - DROP TABLE Bprime; - - - DROP TABLE hobbies_r; - - DROP TABLE equipment_r; - - - DROP TABLE aggtest; - - DROP TABLE xacttest; - - DROP TABLE arrtest; - - DROP TABLE iportaltest; - - - DROP TABLE f_star; - - DROP TABLE e_star; - - DROP TABLE d_star; - - DROP TABLE c_star; - - DROP TABLE b_star; - - DROP TABLE a_star; - - - -- - -- must be in reverse inheritance order - -- - DROP TABLE stud_emp; - - DROP TABLE student; - - DROP TABLE slow_emp4000; - - DROP TABLE fast_emp4000; - - DROP TABLE emp; - - DROP TABLE person; - - - DROP TABLE ramp; - - DROP TABLE real_city; - - DROP TABLE dept; - - DROP TABLE ihighway; - - DROP TABLE shighway; - - DROP TABLE road; - - DROP TABLE city; - - - DROP TABLE hash_i4_heap; - - DROP TABLE hash_name_heap; - - DROP TABLE hash_txt_heap; - - DROP TABLE hash_f8_heap; - - -- DROP TABLE hash_ovfl_heap; - - DROP TABLE bt_i4_heap; - - DROP TABLE bt_name_heap; - - DROP TABLE bt_txt_heap; - - DROP TABLE bt_f8_heap; - - - DROP TABLE ABSTIME_TBL; - - DROP TABLE RELTIME_TBL; - - DROP TABLE TINTERVAL_TBL; - - -- - -- VIRTUAL CLASS REMOVAL - -- (also tests removal of rewrite rules) - -- - DROP VIEW street; ! DROP VIEW iexit; - DROP VIEW toyemp; --- 1,34 ---- -- ! -- Test RESTRICT and CASCADE keywords. -- ! -- Ensure system types cannot be removed ! DROP TYPE int4 CASCADE; ! DROP FUNCTION nextval(text) CASCADE; ! DROP TABLE pg_type CASCADE; ! -- Function RESTRICT / CASCADE ! DROP FUNCTION widget_in(opaque) RESTRICT; -- fail ! DROP TYPE widget RESTRICT; -- fail ! DROP FUNCTION widget_in(opaque) CASCADE; ! DROP TYPE widget RESTRICT; -- doesn't exist ! DROP OPERATOR <% (point, widget) RESTRICT; -- doesn't exist ! -- Type RESTRICT / CASCADE ! DROP TYPE city_budget RESTRICT; -- fail ! DROP TYPE city_budget CASCADE; ! DROP TABLE city RESTRICT; -- doesn't exist ! -- Domain RESTRICT / CASCADE ! DROP DOMAIN ddef1 RESTRICT; -- fail ! DROP DOMAIN ddef1 CASCADE; ! DROP TABLE defaulttest RESTRICT; -- doesn't exist + -- Procedural languge RESTRICT / CASCADE + DROP LANGUAGE plpgsql RESTRICT; -- fail + DROP LANGUAGE plpgsql CASCADE; + SELECT recursion_test(2,3); -- doesn't exist \ No newline at end of file