? GNUmakefile ? config.log ? config.status ? src/Makefile.global ? src/backend/catalog/pg_depend.c ? src/bin/pg_passwd/pg_passwd ? src/include/pg_config.h ? src/include/stamp-h ? src/include/catalog/pg_depend.h Index: src/backend/catalog/Makefile =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v retrieving revision 1.39 diff -c -r1.39 Makefile *** src/backend/catalog/Makefile 2002/03/26 19:15:22 1.39 --- src/backend/catalog/Makefile 2002/04/15 12:22:22 *************** *** 12,18 **** OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \ pg_aggregate.o pg_largeobject.o pg_namespace.o \ ! pg_operator.o pg_proc.o pg_type.o BKIFILES = postgres.bki postgres.description --- 12,18 ---- OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \ pg_aggregate.o pg_largeobject.o pg_namespace.o \ ! pg_operator.o pg_proc.o pg_type.o pg_depend.o BKIFILES = postgres.bki postgres.description *************** *** 26,32 **** # indexing.h had better be last. POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ ! pg_proc.h pg_type.h pg_attribute.h pg_class.h \ pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \ pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \ --- 26,32 ---- # indexing.h had better be last. POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ ! pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_depend.h \ pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \ pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \ Index: src/backend/catalog/heap.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.196 diff -c -r1.196 heap.c *** src/backend/catalog/heap.c 2002/04/12 20:38:18 1.196 --- src/backend/catalog/heap.c 2002/04/15 12:22:24 *************** *** 37,42 **** --- 37,43 ---- #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/pg_attrdef.h" + #include "catalog/pg_depend.h" #include "catalog/pg_inherits.h" #include "catalog/pg_relcheck.h" #include "catalog/pg_statistic.h" *************** *** 49,54 **** --- 50,57 ---- #include "optimizer/planmain.h" #include "optimizer/prep.h" #include "optimizer/var.h" + #include "parser/parse.h" /* For keyword RESTRICT */ + #include "parser/parse_coerce.h" #include "parser/parse_expr.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" *************** *** 68,75 **** char relkind, bool relhasoids); static void DeleteAttributeTuples(Relation rel); static void DeleteRelationTuple(Relation rel); - static void DeleteTypeTuple(Relation rel); - static void RelationRemoveIndexes(Relation relation); static void RelationRemoveInheritance(Relation relation); static void AddNewRelationType(const char *typeName, Oid typeNamespace, --- 71,76 ---- *************** *** 253,258 **** --- 254,264 ---- nailme = true; relid = RelOid_pg_proc; } + else if (strcmp(DependRelationName, relname) == 0) + { + nailme = true; + relid = RelOid_pg_depend; + } else if (strcmp(RelationRelationName, relname) == 0) { nailme = true; *************** *** 415,420 **** --- 421,428 ---- bool hasindex; Relation idescs[Num_pg_attr_indices]; int natts = tupdesc->natts; + ObjectAddress myself, + dependee; /* * open pg_attribute *************** *** 428,433 **** --- 436,446 ---- if (hasindex) CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); + /* Prep Static dependency values */ + myself.classId = RelOid_pg_class; + myself.objectId = new_rel_oid; + dependee.classId = RelOid_pg_type; + /* * first we add the user attributes.. */ *************** *** 449,454 **** --- 462,475 ---- if (hasindex) CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup); + /* Register Dependencies */ + myself.objectSubId = (*dpp)->attnum; + + dependee.objectId = (*dpp)->atttypid; + dependee.objectSubId = 0; + + dependCreate(&myself, &dependee, false); + heap_freetuple(tup); dpp++; } *************** *** 485,490 **** --- 506,522 ---- heap_freetuple(tup); } + + /* Add Oid type dependency for Oid column*/ + if (relhasoids && (*dpp)->attnum == ObjectIdAttributeNumber) { + myself.objectSubId = (*dpp)->attnum; + + dependee.objectId = (*dpp)->atttypid; + dependee.objectSubId = 0; + + dependCreate(&myself, &dependee, false); + } + dpp++; } *************** *** 822,848 **** heap_close(catalogRelation, RowExclusiveLock); } - /* - * RelationRemoveIndexes - */ - static void - RelationRemoveIndexes(Relation relation) - { - List *indexoidlist, - *indexoidscan; - - indexoidlist = RelationGetIndexList(relation); - - foreach(indexoidscan, indexoidlist) - { - Oid indexoid = lfirsti(indexoidscan); - - index_drop(indexoid); - } - - freeList(indexoidlist); - } - /* -------------------------------- * DeleteRelationTuple * --- 854,859 ---- *************** *** 1036,1161 **** heap_close(pg_attribute_desc, RowExclusiveLock); } - /* -------------------------------- - * DeleteTypeTuple - * - * If the user attempts to destroy a relation and there - * exists attributes in other relations of type - * "relation we are deleting", then we have to do something - * special. presently we disallow the destroy. - * -------------------------------- - */ - static void - DeleteTypeTuple(Relation rel) - { - Relation pg_type_desc; - HeapScanDesc pg_type_scan; - Relation pg_attribute_desc; - HeapScanDesc pg_attribute_scan; - ScanKeyData key; - ScanKeyData attkey; - HeapTuple tup; - HeapTuple atttup; - Oid typoid; - - /* - * open pg_type - */ - pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock); - - /* - * create a scan key to locate the type tuple corresponding to this - * relation. - */ - ScanKeyEntryInitialize(&key, 0, - Anum_pg_type_typrelid, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); - - pg_type_scan = heap_beginscan(pg_type_desc, - 0, - SnapshotNow, - 1, - &key); - - /* - * use heap_getnext() to fetch the pg_type tuple. If this tuple is - * not valid then something's wrong. - */ - tup = heap_getnext(pg_type_scan, 0); - - if (!HeapTupleIsValid(tup)) - { - heap_endscan(pg_type_scan); - heap_close(pg_type_desc, RowExclusiveLock); - elog(ERROR, "DeleteTypeTuple: type \"%s\" does not exist", - RelationGetRelationName(rel)); - } - - /* - * now scan pg_attribute. if any other relations have attributes of - * the type of the relation we are deleteing then we have to disallow - * the deletion. should talk to stonebraker about this. -cim 6/19/90 - */ - typoid = tup->t_data->t_oid; - - pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock); - - ScanKeyEntryInitialize(&attkey, - 0, - Anum_pg_attribute_atttypid, - F_OIDEQ, - ObjectIdGetDatum(typoid)); - - pg_attribute_scan = heap_beginscan(pg_attribute_desc, - 0, - SnapshotNow, - 1, - &attkey); - - /* - * try and get a pg_attribute tuple. if we succeed it means we can't - * delete the relation because something depends on the schema. - */ - atttup = heap_getnext(pg_attribute_scan, 0); - - if (HeapTupleIsValid(atttup)) - { - Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid; - - heap_endscan(pg_attribute_scan); - heap_close(pg_attribute_desc, RowExclusiveLock); - heap_endscan(pg_type_scan); - heap_close(pg_type_desc, RowExclusiveLock); - - elog(ERROR, "DeleteTypeTuple: column of type %s exists in relation %u", - RelationGetRelationName(rel), relid); - } - heap_endscan(pg_attribute_scan); - heap_close(pg_attribute_desc, RowExclusiveLock); - - /* - * Ok, it's safe so we delete the relation tuple from pg_type and - * finish up. - */ - simple_heap_delete(pg_type_desc, &tup->t_self); - - heap_endscan(pg_type_scan); - heap_close(pg_type_desc, RowExclusiveLock); - } /* ---------------------------------------------------------------- * heap_drop_with_catalog - removes all record of named relation from catalogs * * 1) open relation, check for existence, etc. * 2) remove inheritance information ! * 3) remove indexes * 4) remove pg_class tuple * 5) remove pg_attribute tuples and related descriptions * 6) remove pg_description tuples ! * 7) remove pg_type tuples ! * 8) RemoveConstraints () ! * 9) unlink relation * * old comments * Except for vital relations, removes relation from --- 1047,1064 ---- heap_close(pg_attribute_desc, RowExclusiveLock); } /* ---------------------------------------------------------------- * heap_drop_with_catalog - removes all record of named relation from catalogs * * 1) open relation, check for existence, etc. * 2) remove inheritance information ! * 3) remove dependencies * 4) remove pg_class tuple * 5) remove pg_attribute tuples and related descriptions * 6) remove pg_description tuples ! * 7) RemoveConstraints () ! * 8) unlink relation * * old comments * Except for vital relations, removes relation from *************** *** 1180,1186 **** { Relation rel; Oid toasttableOid; ! int i; /* * Open and lock the relation. --- 1083,1091 ---- { Relation rel; Oid toasttableOid; ! int i, natts; ! ObjectAddress myself; ! HeapTuple tuple; /* * Open and lock the relation. *************** *** 1205,1229 **** elog(ERROR, "heap_drop_with_catalog: FlushRelationBuffers returned %d", i); /* ! * remove rules if necessary */ ! if (rel->rd_rules != NULL) ! RelationRemoveRules(rid); ! /* triggers */ ! RelationRemoveTriggers(rel); /* ! * remove inheritance information */ ! RelationRemoveInheritance(rel); /* ! * remove indexes if necessary */ ! RelationRemoveIndexes(rel); /* * delete attribute tuples */ --- 1110,1160 ---- elog(ERROR, "heap_drop_with_catalog: FlushRelationBuffers returned %d", i); + /* + * remove inheritance information + */ + RelationRemoveInheritance(rel); + /* ! * Deal with dependencies ! * ! * Take care of any attributes first, then the main object ! * last when objectSubId = 0. Ignore system attributes. */ ! tuple = SearchSysCache(RELOID, rid, 0, 0, 0); ! if (!HeapTupleIsValid(tuple)) ! elog(ERROR, "Relation %s doesn't exist", RelationGetRelationName(rel)); ! natts = ((Form_pg_class) GETSTRUCT(tuple))->relnatts; ! ! /* Must free before calling dependDelete */ ! ReleaseSysCache(tuple); /* ! * Drop in decending order so the table is handled after all ! * of its columns. ! * ! * Oid first due to abilities like Primary Key on Oid. This is ! * done whether it has oids or not. */ ! myself.classId = RelOid_pg_class; ! myself.objectId = rid; /* ! * Delete depends on Oid regardless of whether ! * the relation has Oids or not. End with the ! * relation itself. */ ! myself.objectSubId = ObjectIdAttributeNumber; ! dependDelete(&myself, RESTRICT); ! ! for (i = natts; i >= 0; i--) ! { ! myself.objectSubId = i; ! dependDelete(&myself, RESTRICT); ! } + /* * delete attribute tuples */ *************** *** 1236,1247 **** RemoveStatistics(rel); - RemoveConstraints(rel); - /* ! * delete type tuple */ ! DeleteTypeTuple(rel); /* * delete relation tuple --- 1167,1178 ---- RemoveStatistics(rel); /* ! * Remove constraints if necessary ! * ! * Should be updated to use pg_depend methods */ ! RemoveConstraints(rel); /* * delete relation tuple Index: src/backend/catalog/index.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/index.c,v retrieving revision 1.176 diff -c -r1.176 index.c *** src/backend/catalog/index.c 2002/04/12 20:38:19 1.176 --- src/backend/catalog/index.c 2002/04/15 12:22:27 *************** *** 32,37 **** --- 32,39 ---- #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/indexing.h" + #include "catalog/pg_class.h" + #include "catalog/pg_depend.h" #include "catalog/pg_index.h" #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" *************** *** 41,46 **** --- 43,49 ---- #include "miscadmin.h" #include "optimizer/clauses.h" #include "optimizer/prep.h" + #include "parser/parse.h" /* For keyword RESTRICT */ #include "parser/parse_func.h" #include "storage/sinval.h" #include "storage/smgr.h" *************** *** 563,568 **** --- 566,573 ---- TupleDesc indexTupDesc; Oid namespaceId; Oid indexoid; + ObjectAddress myself; + int i; SetReindexProcessing(false); *************** *** 598,604 **** else indexTupDesc = ConstructTupleDescriptor(heapRelation, indexInfo->ii_NumKeyAttrs, ! indexInfo->ii_KeyAttrNumbers, classObjectId); /* --- 603,609 ---- else indexTupDesc = ConstructTupleDescriptor(heapRelation, indexInfo->ii_NumKeyAttrs, ! indexInfo->ii_KeyAttrNumbers, classObjectId); /* *************** *** 632,637 **** --- 637,670 ---- */ UpdateRelationRelation(indexRelation); + myself.classId = RelOid_pg_class; + myself.objectId = indexoid; + myself.objectSubId = 0; + + /* Store dependencies on the attributes */ + for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) + { + ObjectAddress dependee; + + dependee.classId = RelOid_pg_class; + dependee.objectId = heapRelationId; + dependee.objectSubId = indexInfo->ii_KeyAttrNumbers[i]; + + /* We always cascade index drops with attribute drops */ + dependCreate(&myself, &dependee, true); + } + + /* Store the dependency on the function (if appropriate) */ + if (OidIsValid(indexInfo->ii_FuncOid)) { + ObjectAddress dependee; + + dependee.classId = RelOid_pg_proc; + dependee.objectId = indexInfo->ii_FuncOid; + dependee.objectSubId = 0; + + dependCreate(&myself, &dependee, false); + } + /* * We create the disk file for this relation here */ *************** *** 711,716 **** --- 744,751 ---- HeapTuple tuple; int16 attnum; int i; + + ObjectAddress myself; Assert(OidIsValid(indexId)); *************** *** 820,825 **** --- 855,865 ---- heap_close(userHeapRelation, NoLock); RelationForgetRelation(indexId); + + myself.classId = RelOid_pg_class; + myself.objectId = indexId; + myself.objectSubId = 0; + dependDelete(&myself, RESTRICT); } /* ---------------------------------------------------------------- Index: src/backend/catalog/namespace.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/namespace.c,v retrieving revision 1.8 diff -c -r1.8 namespace.c *** src/backend/catalog/namespace.c 2002/04/12 20:38:19 1.8 --- src/backend/catalog/namespace.c 2002/04/15 12:22:28 *************** *** 567,572 **** --- 567,598 ---- } /* + * namespaceIdGetNspname + * Fetch the namespace name by the namespace OID + */ + char * + namespaceIdGetNspname(Oid namespaceId) + { + char *schemaname; + HeapTuple tup; + + tup = SearchSysCache(NAMESPACEOID, + namespaceId, + 0, 0, 0); + + if (!HeapTupleIsValid(tup)) { + elog(ERROR, "namespaceIdGetName(): NamespaceId %d does not exist.", + namespaceId); + } + + schemaname = NameStr(((Form_pg_namespace) GETSTRUCT(tup))->nspname); + + ReleaseSysCache(tup); + + return(schemaname); + } + + /* * NameListToString * Utility routine to convert a qualified-name list into a string. * Used primarily to form error messages. Index: src/backend/catalog/pg_aggregate.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v retrieving revision 1.44 diff -c -r1.44 pg_aggregate.c *** src/backend/catalog/pg_aggregate.c 2002/04/11 19:59:57 1.44 --- src/backend/catalog/pg_aggregate.c 2002/04/15 12:22:28 *************** *** 19,24 **** --- 19,26 ---- #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_aggregate.h" + #include "catalog/pg_depend.h" + #include "catalog/pg_namespace.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" #include "optimizer/cost.h" *************** *** 54,59 **** --- 56,63 ---- Oid procOid; TupleDesc tupDesc; int i; + ObjectAddress myself, + dependee; /* sanity checks */ if (!aggName) *************** *** 186,190 **** --- 190,221 ---- CatalogCloseIndices(Num_pg_aggregate_indices, idescs); } + /* Define Dependencies */ + myself.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(AggregateRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + myself.objectId = tup->t_data->t_oid; + myself.objectSubId = 0; + + /* Depends on transition function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtransfn - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Depends on final function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggfinalfn - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Depends on final transition type */ + dependee.classId = RelOid_pg_type; + dependee.objectId = DatumGetObjectId(values[Anum_pg_aggregate_aggtranstype - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Cleanup */ heap_close(aggdesc, RowExclusiveLock); } Index: src/backend/catalog/pg_operator.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_operator.c,v retrieving revision 1.65 diff -c -r1.65 pg_operator.c *** src/backend/catalog/pg_operator.c 2002/04/09 20:35:47 1.65 --- src/backend/catalog/pg_operator.c 2002/04/15 12:22:29 *************** *** 20,25 **** --- 20,27 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" + #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" *************** *** 406,411 **** --- 408,416 ---- int i, j; + ObjectAddress myself, + dependee; + /* * validate operator name */ *************** *** 683,688 **** --- 688,789 ---- CatalogOpenIndices(Num_pg_operator_indices, Name_pg_operator_indices, idescs); CatalogIndexInsert(idescs, Num_pg_operator_indices, pg_operator_desc, tup); CatalogCloseIndices(Num_pg_operator_indices, idescs); + } + + /* Load our object address */ + myself.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(OperatorRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + myself.objectId = operatorObjectId; + myself.objectSubId = 0; + + /* Dependency on left type */ + if (DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_type; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprleft - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on right type */ + if (DatumGetObjectId(values[Anum_pg_operator_oprright - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_type; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprright - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on result type */ + dependee.classId = RelOid_pg_type; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprresult - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Dependency on commutator */ + if (DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]) != InvalidOid) { + dependee.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(OperatorRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcom - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on negator */ + if (DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]) != InvalidOid) { + dependee.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(OperatorRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprnegate - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on sort left hand operator */ + if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) { + dependee.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(OperatorRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprlsortop - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on sort right hand operator */ + if (DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]) != InvalidOid) { + dependee.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(OperatorRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrsortop - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on implementation function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprcode - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Dependency on restriction selectivity function */ + if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprrest - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + /* Dependency on join selectifity function */ + if (DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_operator_oprjoin - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); } heap_close(pg_operator_desc, RowExclusiveLock); Index: src/backend/catalog/pg_proc.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_proc.c,v retrieving revision 1.70 diff -c -r1.70 pg_proc.c *** src/backend/catalog/pg_proc.c 2002/04/11 19:59:57 1.70 --- src/backend/catalog/pg_proc.c 2002/04/15 12:22:31 *************** *** 17,23 **** --- 17,25 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" #include "catalog/pg_language.h" + #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "executor/executor.h" #include "miscadmin.h" *************** *** 73,78 **** --- 75,83 ---- TupleDesc tupDesc; Oid retval; + ObjectAddress myself, + dependee; + /* * sanity checks */ *************** *** 312,317 **** --- 317,358 ---- } retval = tup->t_data->t_oid; + + /* Record Dependencies */ + myself.classId = RelOid_pg_proc; + myself.objectId = retval; + myself.objectSubId = 0; + + /* Procedure on Language */ + dependee.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(LanguageRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + dependee.objectId = languageObjectId; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Return Type */ + if (returnType != InvalidOid) + { + dependee.classId = RelOid_pg_type; + dependee.objectId = returnType; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + + for (i = 0; i < parameterCount; i++) + { + /* Parameter Types */ + if (typev[i] != InvalidOid) + { + dependee.classId = RelOid_pg_type; + dependee.objectId = typev[i]; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + } + } + heap_freetuple(tup); heap_close(rel, RowExclusiveLock); Index: src/backend/catalog/pg_type.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_type.c,v retrieving revision 1.70 diff -c -r1.70 pg_type.c *** src/backend/catalog/pg_type.c 2002/03/29 19:06:02 1.70 --- src/backend/catalog/pg_type.c 2002/04/15 12:22:31 *************** *** 17,22 **** --- 17,23 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" #include "catalog/pg_type.h" #include "miscadmin.h" #include "utils/builtins.h" *************** *** 167,172 **** --- 168,175 ---- NameData name; TupleDesc tupDesc; int i; + ObjectAddress myself, + dependee; /* * validate size specifications: either positive (fixed-length) or -1 *************** *** 299,304 **** --- 302,363 ---- CatalogOpenIndices(Num_pg_type_indices, Name_pg_type_indices, idescs); CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup); CatalogCloseIndices(Num_pg_type_indices, idescs); + } + + /* + * Create dependencies + */ + + /* Load our object address */ + myself.classId = RelOid_pg_type; + myself.objectId = typeObjectId; + myself.objectSubId = 0; + + /* Dependency on the input function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typinput - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Dependency on the output function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typoutput - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Dependency on the receive function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typreceive - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* Dependency on the send function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typsend - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* + * Dependency on the relation for complex types. Assume it's for + * a relation of somekind and drop it when the relation is removed. + */ + if (DatumGetObjectId(values[Anum_pg_type_typrelid - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_class; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typrelid - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, true); + } + + /* + * Dependency on the element Id for arrays. We can assume that it's for + * an array and that we should always cascade into this type when the base + * type is being removed. + */ + if (DatumGetObjectId(values[Anum_pg_type_typelem - 1]) != InvalidOid) { + dependee.classId = RelOid_pg_type; + dependee.objectId = DatumGetObjectId(values[Anum_pg_type_typelem - 1]); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, true); } /* Index: src/backend/commands/aggregatecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v retrieving revision 1.1 diff -c -r1.1 aggregatecmds.c *** src/backend/commands/aggregatecmds.c 2002/04/15 05:22:03 1.1 --- src/backend/commands/aggregatecmds.c 2002/04/15 12:22:31 *************** *** 26,34 **** --- 26,36 ---- #include "catalog/catname.h" #include "catalog/namespace.h" #include "catalog/pg_aggregate.h" + #include "catalog/pg_depend.h" #include "commands/comment.h" #include "commands/defrem.h" #include "miscadmin.h" + #include "parser/parse.h" /* For RESTRICT */ #include "parser/parse_func.h" #include "parser/parse_type.h" #include "utils/acl.h" *************** *** 179,184 **** --- 181,189 ---- if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "RemoveAggregate: couldn't find pg_proc tuple for %s", NameListToString(aggName)); + + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, RESTRICT); /* Delete any comments associated with this function */ DeleteComments(procOid, RelationGetRelid(relation)); Index: src/backend/commands/functioncmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/functioncmds.c,v retrieving revision 1.1 diff -c -r1.1 functioncmds.c *** src/backend/commands/functioncmds.c 2002/04/15 05:22:03 1.1 --- src/backend/commands/functioncmds.c 2002/04/15 12:22:33 *************** *** 34,39 **** --- 34,40 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/namespace.h" + #include "catalog/pg_depend.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" *************** *** 41,46 **** --- 42,48 ---- #include "commands/defrem.h" #include "miscadmin.h" #include "optimizer/cost.h" + #include "parser/parse.h" /* For RESTRICT */ #include "parser/parse_func.h" #include "parser/parse_type.h" #include "utils/acl.h" *************** *** 419,424 **** --- 421,429 ---- elog(WARNING, "Removing built-in function \"%s\"", NameListToString(functionName)); } + + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, RESTRICT); /* Delete any comments associated with this function */ DeleteComments(funcOid, RelationGetRelid(relation)); Index: src/backend/commands/operatorcmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/operatorcmds.c,v retrieving revision 1.1 diff -c -r1.1 operatorcmds.c *** src/backend/commands/operatorcmds.c 2002/04/15 05:22:03 1.1 --- src/backend/commands/operatorcmds.c 2002/04/15 12:22:33 *************** *** 37,46 **** --- 37,48 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/namespace.h" + #include "catalog/pg_depend.h" #include "catalog/pg_operator.h" #include "commands/comment.h" #include "commands/defrem.h" #include "miscadmin.h" + #include "parser/parse.h" /* For RESTRICT */ #include "parser/parse_type.h" #include "utils/acl.h" #include "utils/syscache.h" *************** *** 214,219 **** --- 216,224 ---- if (!pg_oper_ownercheck(tup->t_data->t_oid, GetUserId())) elog(ERROR, "RemoveOperator: operator '%s': permission denied", operatorName); + + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, RESTRICT); /* Delete any comments associated with this operator */ DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation)); Index: src/backend/commands/proclang.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/proclang.c,v retrieving revision 1.31 diff -c -r1.31 proclang.c *** src/backend/commands/proclang.c 2002/04/15 05:22:03 1.31 --- src/backend/commands/proclang.c 2002/04/15 12:22:33 *************** *** 18,23 **** --- 18,24 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" #include "catalog/namespace.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" *************** *** 25,30 **** --- 26,32 ---- #include "commands/defrem.h" #include "fmgr.h" #include "miscadmin.h" + #include "parser/parse.h" /* For keyword RESTRICT */ #include "parser/parse_func.h" #include "utils/builtins.h" #include "utils/lsyscache.h" *************** *** 48,53 **** --- 50,58 ---- TupleDesc tupDesc; int i; + ObjectAddress myself, + dependee; + /* * Check permission */ *************** *** 79,84 **** --- 84,94 ---- elog(ERROR, "PL handler function %s() isn't of return type Opaque", NameListToString(stmt->plhandler)); + /* Address of the PL handler function */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = procOid; + dependee.objectSubId = 0; + /* * Insert the new language into pg_language */ *************** *** 113,118 **** --- 123,136 ---- CatalogCloseIndices(Num_pg_language_indices, idescs); } + /* Address of myself */ + myself.classId = RelationGetRelid(rel); + myself.objectId = tup->t_data->t_oid; + myself.objectSubId = 0; + + /* Create dependency on the language PL Handler function */ + dependCreate(&myself, &dependee, false); + heap_close(rel, RowExclusiveLock); } *************** *** 152,157 **** --- 170,178 ---- if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl) elog(ERROR, "Language %s isn't a created procedural language", languageName); + + /* Deal with Dependencies */ + dependDeleteTuple(langTup, rel, RESTRICT); simple_heap_delete(rel, &langTup->t_self); Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.1 diff -c -r1.1 tablecmds.c *** src/backend/commands/tablecmds.c 2002/04/15 05:22:03 1.1 --- src/backend/commands/tablecmds.c 2002/04/15 12:22:35 *************** *** 23,28 **** --- 23,29 ---- #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_attrdef.h" + #include "catalog/pg_depend.h" #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" *************** *** 126,132 **** HeapTuple typeTuple; Form_pg_type tform; int attndims; ! /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. --- 127,134 ---- HeapTuple typeTuple; Form_pg_type tform; int attndims; ! ObjectAddress myself, ! dependee; /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. *************** *** 262,267 **** --- 264,279 ---- ReleaseSysCache(typeTuple); heap_insert(attrdesc, attributeTuple); + + /* Register Dependencies */ + myself.classId = RelOid_pg_class; + myself.objectId = attribute->attrelid; + myself.objectSubId = attribute->attnum; + + dependee.classId = RelOid_pg_type; + dependee.objectId = attribute->atttypid; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); /* Update indexes on pg_attribute */ if (RelationGetForm(attrdesc)->relhasindex) Index: src/backend/commands/trigger.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/trigger.c,v retrieving revision 1.113 diff -c -r1.113 trigger.c *** src/backend/commands/trigger.c 2002/04/12 20:38:24 1.113 --- src/backend/commands/trigger.c 2002/04/15 12:22:39 *************** *** 18,23 **** --- 18,24 ---- #include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" #include "catalog/namespace.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" *************** *** 26,31 **** --- 27,33 ---- #include "commands/trigger.h" #include "executor/executor.h" #include "miscadmin.h" + #include "parser/parse.h" /* For keyword RESTRICT */ #include "parser/parse_func.h" #include "utils/acl.h" #include "utils/builtins.h" *************** *** 73,78 **** --- 75,83 ---- char constrtrigname[NAMEDATALEN]; char *constrname = ""; Oid constrrelid = InvalidOid; + Oid insertOid, insertTupOid; + ObjectAddress myself, + dependee; rel = heap_openrv(stmt->relation, AccessExclusiveLock); *************** *** 260,265 **** --- 265,272 ---- tuple = heap_formtuple(tgrel->rd_att, values, nulls); + insertOid = tgrel->rd_id; + /* * Insert tuple into pg_trigger. */ *************** *** 267,272 **** --- 274,283 ---- CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, idescs); CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple); CatalogCloseIndices(Num_pg_trigger_indices, idescs); + + /* Need the Inserted Tup Oid below for the address of 'myself' */ + insertTupOid = tuple->t_data->t_oid; + heap_freetuple(tuple); heap_close(tgrel, RowExclusiveLock); *************** *** 295,300 **** --- 306,339 ---- heap_close(pgrel, RowExclusiveLock); /* + * Insert dependencies + */ + myself.classId = insertOid; + myself.objectId = insertTupOid; + myself.objectSubId = 0; + + /* tgrelid */ + dependee.classId = RelOid_pg_class; + dependee.objectId = RelationGetRelid(rel); + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, true); + + /* tgfoid */ + dependee.classId = RelOid_pg_proc; + dependee.objectId = funcoid; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, false); + + /* tgconstrrelid */ + if (constrrelid != InvalidOid) + { + dependee.classId = RelOid_pg_class; + dependee.objectId = constrrelid; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, true); + } + + /* * We used to try to update the rel's relcache entry here, but that's * fairly pointless since it will happen as a byproduct of the * upcoming CommandCounterIncrement... *************** *** 350,357 **** --- 389,400 ---- { Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple); + /* If trigOid is defined, it takes presedence over the name supplied */ if (namestrcmp(&(pg_trigger->tgname), trigname) == 0) { + /* Deal with dependencies */ + dependDeleteTuple(tuple, tgrel, RESTRICT); + /* Delete any comments associated with this trigger */ DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel)); *************** *** 396,494 **** heap_close(rel, NoLock); } /* ! * Remove all triggers for a relation that's being deleted. */ void ! RelationRemoveTriggers(Relation rel) { ! Relation tgrel; ! SysScanDesc tgscan; ! ScanKeyData key; ! HeapTuple tup; ! bool found = false; tgrel = heap_openr(TriggerRelationName, RowExclusiveLock); ! ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid, F_OIDEQ, ! ObjectIdGetDatum(RelationGetRelid(rel))); ! tgscan = systable_beginscan(tgrel, TriggerRelidIndex, true, ! SnapshotNow, 1, &key); ! while (HeapTupleIsValid(tup = systable_getnext(tgscan))) ! { ! /* Delete any comments associated with this trigger */ ! DeleteComments(tup->t_data->t_oid, RelationGetRelid(tgrel)); ! simple_heap_delete(tgrel, &tup->t_self); ! found = true; ! } ! systable_endscan(tgscan); ! /* ! * If we deleted any triggers, must update pg_class entry and advance ! * command counter to make the updated entry visible. This is fairly ! * annoying, since we'e just going to drop the durn thing later, but ! * it's necessary to have a consistent state in case we do ! * CommandCounterIncrement() below --- if RelationBuildTriggers() ! * runs, it will complain otherwise. Perhaps RelationBuildTriggers() ! * shouldn't be so picky... ! */ ! if (found) ! { ! Relation pgrel; ! Relation ridescs[Num_pg_class_indices]; ! pgrel = heap_openr(RelationRelationName, RowExclusiveLock); ! tup = SearchSysCacheCopy(RELOID, ! ObjectIdGetDatum(RelationGetRelid(rel)), ! 0, 0, 0); ! if (!HeapTupleIsValid(tup)) ! elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class", ! RelationGetRelid(rel)); ! ! ((Form_pg_class) GETSTRUCT(tup))->reltriggers = 0; ! simple_heap_update(pgrel, &tup->t_self, tup); ! CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); ! CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tup); ! CatalogCloseIndices(Num_pg_class_indices, ridescs); ! heap_freetuple(tup); ! heap_close(pgrel, RowExclusiveLock); ! CommandCounterIncrement(); ! } ! /* ! * Also drop all constraint triggers referencing this relation ! */ ! ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgconstrrelid, ! F_OIDEQ, ! ObjectIdGetDatum(RelationGetRelid(rel))); ! tgscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, true, ! SnapshotNow, 1, &key); ! while (HeapTupleIsValid(tup = systable_getnext(tgscan))) ! { ! Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup); ! elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", ! get_rel_name(pg_trigger->tgrelid)); ! DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname)); ! /* ! * Need to do a command counter increment here to show up new ! * pg_class.reltriggers in the next loop iteration (in case there ! * are multiple referential integrity action triggers for the same ! * FK table defined on the PK table). ! */ ! CommandCounterIncrement(); ! } ! systable_endscan(tgscan); ! heap_close(tgrel, RowExclusiveLock); } /* * Build trigger data to attach to the given relcache entry. --- 439,527 ---- heap_close(rel, NoLock); } + /* ! * DropTriggerById - Drop a trigger by it's OID */ void ! DropTriggerById(Oid trigId) { ! Relation rel; ! Relation tgrel; ! HeapScanDesc tgscan; ! ScanKeyData key[1]; ! Relation pgrel; ! HeapTuple tuple; ! Relation ridescs[Num_pg_class_indices]; ! Form_pg_trigger pg_trigger; ! int nkeys = 0; + /* + * Search pg_trigger, delete target trigger, count remaining triggers + * for relation. Note this is OK only because we have + * AccessExclusiveLock on the rel, so no one else is creating/deleting + * triggers on this rel at the same time. + */ tgrel = heap_openr(TriggerRelationName, RowExclusiveLock); ! ScanKeyEntryInitialize(&key[nkeys++], 0, ObjectIdAttributeNumber, F_OIDEQ, ! ObjectIdGetDatum(trigId)); ! tgscan = heap_beginscan(tgrel, 0, SnapshotNow, nkeys, key); ! tuple = heap_getnext(tgscan, 0); ! if (!HeapTupleIsValid(tuple)) ! elog(ERROR, "DropTriggerById: TriggerID %d not valid", trigId); ! /* Grab the info, and lock the triggers relation */ ! pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple); ! rel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock); ! /* Test Ownership */ ! if (!pg_class_ownercheck(pg_trigger->tgrelid, GetUserId())) ! elog(ERROR, "%s: %s", RelationGetRelationName(rel), ! aclcheck_error_strings[ACLCHECK_NOT_OWNER]); ! /* Deal with dependencies */ ! dependDeleteTuple(tuple, tgrel, RESTRICT); ! /* Delete any comments associated with this trigger */ ! DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel)); ! simple_heap_delete(tgrel, &tuple->t_self); ! heap_endscan(tgscan); ! heap_close(tgrel, RowExclusiveLock); ! /* ! * Update relation's pg_class entry. Crucial side-effect: other ! * backends (and this one too!) are sent SI message to make them ! * rebuild relcache entries. ! */ ! pgrel = heap_openr(RelationRelationName, RowExclusiveLock); ! tuple = SearchSysCacheCopy(RELOID, ! ObjectIdGetDatum(pg_trigger->tgrelid), ! 0, 0, 0); ! if (!HeapTupleIsValid(tuple)) ! elog(ERROR, "DropTriggerById: relation %s not found in pg_class", ! RelationGetRelationName(rel)); ! ! /* Guarenteed to take one and only one */ ! ((Form_pg_class) GETSTRUCT(tuple))->reltriggers--; ! simple_heap_update(pgrel, &tuple->t_self, tuple); ! CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); ! CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple); ! CatalogCloseIndices(Num_pg_class_indices, ridescs); ! heap_freetuple(tuple); ! heap_close(pgrel, RowExclusiveLock); ! ! /* Keep lock on target rel until end of xact */ ! heap_close(rel, NoLock); } + /* * Build trigger data to attach to the given relcache entry. Index: src/backend/commands/typecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.1 diff -c -r1.1 typecmds.c *** src/backend/commands/typecmds.c 2002/04/15 05:22:03 1.1 --- src/backend/commands/typecmds.c 2002/04/15 12:22:39 *************** *** 35,40 **** --- 35,41 ---- #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/namespace.h" + #include "catalog/pg_depend.h" #include "catalog/pg_type.h" #include "commands/comment.h" #include "commands/defrem.h" *************** *** 263,271 **** RemoveType(List *names) { TypeName *typename; - Relation relation; - Oid typeoid; - HeapTuple tup; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeNode(TypeName); --- 264,269 ---- *************** *** 273,278 **** --- 271,290 ---- typename->typmod = -1; typename->arrayBounds = NIL; + RemoveTypeByTypeName(typename); + } + + /* + * TypeRemove + * Removes a datatype by the typename struct + */ + void + RemoveTypeByTypeName(TypeName *typename) + { + Relation relation; + Oid typeoid; + HeapTuple tup; + relation = heap_openr(TypeRelationName, RowExclusiveLock); /* Use LookupTypeName here so that shell types can be removed. */ *************** *** 291,319 **** if (!pg_type_ownercheck(typeoid, GetUserId())) elog(ERROR, "RemoveType: type '%s': permission denied", TypeNameToString(typename)); - - /* Delete any comments associated with this type */ - DeleteComments(typeoid, RelationGetRelid(relation)); - - /* Remove the type tuple from pg_type */ - simple_heap_delete(relation, &tup->t_self); - - ReleaseSysCache(tup); - - /* Now, delete the "array of" that type */ - typename->arrayBounds = makeList1(makeInteger(1)); - - typeoid = LookupTypeName(typename); - if (!OidIsValid(typeoid)) - elog(ERROR, "Type \"%s\" does not exist", - TypeNameToString(typename)); ! tup = SearchSysCache(TYPEOID, ! ObjectIdGetDatum(typeoid), ! 0, 0, 0); ! if (!HeapTupleIsValid(tup)) ! elog(ERROR, "Type \"%s\" does not exist", ! TypeNameToString(typename)); DeleteComments(typeoid, RelationGetRelid(relation)); --- 303,311 ---- if (!pg_type_ownercheck(typeoid, GetUserId())) elog(ERROR, "RemoveType: type '%s': permission denied", TypeNameToString(typename)); ! /* Deal with dependencies */ ! dependDeleteTuple(tup, relation, RESTRICT); DeleteComments(typeoid, RelationGetRelid(relation)); *************** *** 596,601 **** --- 588,596 ---- if (typtype != 'd') elog(ERROR, "%s is not a domain", TypeNameToString(typename)); + + /* Deal with dependencies */ + dependDeleteTuple(tup, relation, RESTRICT); /* Delete any comments associated with this type */ DeleteComments(typeoid, RelationGetRelid(relation)); Index: src/backend/rewrite/rewriteDefine.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v retrieving revision 1.66 diff -c -r1.66 rewriteDefine.c *** src/backend/rewrite/rewriteDefine.c 2002/03/26 19:16:02 1.66 --- src/backend/rewrite/rewriteDefine.c 2002/04/15 12:22:40 *************** *** 17,22 **** --- 17,24 ---- #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/indexing.h" + #include "catalog/pg_depend.h" + #include "catalog/pg_namespace.h" #include "catalog/pg_rewrite.h" #include "commands/view.h" #include "miscadmin.h" *************** *** 49,62 **** char *evqual, char *actiontree) { ! int i; ! Datum values[Natts_pg_rewrite]; ! char nulls[Natts_pg_rewrite]; ! NameData rname; ! Relation pg_rewrite_desc; ! TupleDesc tupDesc; ! HeapTuple tup; ! Oid rewriteObjectId; if (IsDefinedRewriteRule(rulname)) elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists", --- 51,66 ---- char *evqual, char *actiontree) { ! int i; ! Datum values[Natts_pg_rewrite]; ! char nulls[Natts_pg_rewrite]; ! NameData rname; ! Relation pg_rewrite_desc; ! TupleDesc tupDesc; ! HeapTuple tup; ! Oid rewriteObjectId; ! ObjectAddress myself, ! dependee; if (IsDefinedRewriteRule(rulname)) elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists", *************** *** 102,107 **** --- 106,127 ---- tup); CatalogCloseIndices(Num_pg_rewrite_indices, idescs); } + + /* + * Create Dependencies + * - Class of relation + */ + myself.classId = GetSysCacheOid(RELNAMENSP, + CStringGetDatum(RewriteRelationName), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + myself.objectId = tup->t_data->t_oid; + myself.objectSubId = 0; + + dependee.classId = RelOid_pg_class; + dependee.objectId = eventrel_oid; + dependee.objectSubId = 0; + dependCreate(&myself, &dependee, true); heap_freetuple(tup); Index: src/backend/rewrite/rewriteRemove.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v retrieving revision 1.47 diff -c -r1.47 rewriteRemove.c *** src/backend/rewrite/rewriteRemove.c 2002/03/29 19:06:13 1.47 --- src/backend/rewrite/rewriteRemove.c 2002/04/15 12:22:40 *************** *** 14,31 **** */ #include "postgres.h" - #include "utils/builtins.h" #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/pg_rewrite.h" #include "commands/comment.h" #include "miscadmin.h" #include "rewrite/rewriteRemove.h" #include "rewrite/rewriteSupport.h" #include "utils/acl.h" #include "utils/fmgroids.h" #include "utils/syscache.h" /* * RemoveRewriteRule --- 14,35 ---- */ #include "postgres.h" #include "access/heapam.h" #include "catalog/catname.h" + #include "catalog/pg_depend.h" #include "catalog/pg_rewrite.h" #include "commands/comment.h" + #include "nodes/parsenodes.h" /* Required by parser/parse.h */ + #include "parser/parse.h" /* For keyword RESTRICT */ #include "miscadmin.h" #include "rewrite/rewriteRemove.h" #include "rewrite/rewriteSupport.h" + #include "utils/builtins.h" #include "utils/acl.h" #include "utils/fmgroids.h" #include "utils/syscache.h" + void RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force); /* * RemoveRewriteRule *************** *** 37,48 **** { char *ruleName; Relation RewriteRelation; - Relation event_relation; HeapTuple tuple; - Oid ruleId; - Oid eventRelationOid; - bool hasMoreRules; - int32 aclcheck_result; /* * XXX temporary until rules become schema-tized --- 41,47 ---- *************** *** 64,74 **** 0, 0, 0); /* ! * complain if no rule with such name existed */ if (!HeapTupleIsValid(tuple)) elog(ERROR, "Rule \"%s\" not found", ruleName); /* * Save the OID of the rule (i.e. the tuple's OID) and the event * relation's OID --- 63,133 ---- 0, 0, 0); /* ! * complain if no rule with such nam*e existed */ if (!HeapTupleIsValid(tuple)) elog(ERROR, "Rule \"%s\" not found", ruleName); + RemoveRewriteRuleByTuple(RewriteRelation, tuple, false); + + heap_freetuple(tuple); + + heap_close(RewriteRelation, RowExclusiveLock); + } + + + void + RemoveRewriteRuleById(Oid ruleId) + { + Relation RewriteRelation; + HeapScanDesc scanDesc = NULL; + ScanKeyData scanKeyData; + HeapTuple tuple; + + /* + * Open the pg_rewrite relation. + */ + RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock); + + /* + * Find the tuple for the target rule. + */ + ScanKeyEntryInitialize(&scanKeyData, + 0, + ObjectIdAttributeNumber, + F_OIDEQ, + ObjectIdGetDatum(ruleId)); + + scanDesc = heap_beginscan(RewriteRelation, + 0, SnapshotNow, 1, &scanKeyData); + + /* Assume only 1 will be found */ + while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) + { + RemoveRewriteRuleByTuple(RewriteRelation, tuple, true); + } + + heap_endscan(scanDesc); + + heap_close(RewriteRelation, RowExclusiveLock); + } + + /* + * RemoveRewriteRuleByTuple + * + * If force is true then the fact that the rule is owned by a view is ignored + * by the system. It will remove it anyway. + */ + void + RemoveRewriteRuleByTuple(Relation rewriteRelation, HeapTuple tuple, bool force) + { + + Relation event_relation; + Oid ruleId; + Oid eventRelationOid; + bool hasMoreRules; + int32 aclcheck_result; + /* * Save the OID of the rule (i.e. the tuple's OID) and the event * relation's OID *************** *** 95,121 **** aclcheck_error_strings[aclcheck_result]); /* do not allow the removal of a view's SELECT rule */ ! if (event_relation->rd_rel->relkind == RELKIND_VIEW && ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1') ! elog(ERROR, "Cannot remove a view's SELECT rule"); hasMoreRules = event_relation->rd_rules != NULL && event_relation->rd_rules->numLocks > 1; /* * Delete any comments associated with this rule */ ! DeleteComments(ruleId, RelationGetRelid(RewriteRelation)); ! /* * Now delete the pg_rewrite tuple for the rule */ ! simple_heap_delete(RewriteRelation, &tuple->t_self); - heap_freetuple(tuple); - - heap_close(RewriteRelation, RowExclusiveLock); - /* * Set pg_class 'relhasrules' field correctly for event relation. * --- 154,178 ---- aclcheck_error_strings[aclcheck_result]); /* do not allow the removal of a view's SELECT rule */ ! if (force == false && event_relation->rd_rel->relkind == RELKIND_VIEW && ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1') ! elog(ERROR, "RemoveRewriteRuleByTuple: Cannot remove a view's SELECT rule"); hasMoreRules = event_relation->rd_rules != NULL && event_relation->rd_rules->numLocks > 1; + /* Deal with dependencies */ + dependDeleteTuple(tuple, rewriteRelation, RESTRICT); + /* * Delete any comments associated with this rule */ ! DeleteComments(ruleId, RelationGetRelid(rewriteRelation)); /* * Now delete the pg_rewrite tuple for the rule */ ! simple_heap_delete(rewriteRelation, &tuple->t_self); /* * Set pg_class 'relhasrules' field correctly for event relation. * *************** *** 127,172 **** /* Close rel, but keep lock till commit... */ heap_close(event_relation, NoLock); - } - - /* - * RelationRemoveRules - - * removes all rules associated with the relation when the relation is - * being removed. - */ - void - RelationRemoveRules(Oid relid) - { - Relation RewriteRelation = NULL; - HeapScanDesc scanDesc = NULL; - ScanKeyData scanKeyData; - HeapTuple tuple = NULL; - - /* - * Open the pg_rewrite relation. - */ - RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock); - - /* - * Scan the RuleRelation ('pg_rewrite') for all the tuples that has - * the same ev_class as relid (the relation to be removed). - */ - ScanKeyEntryInitialize(&scanKeyData, - 0, - Anum_pg_rewrite_ev_class, - F_OIDEQ, - ObjectIdGetDatum(relid)); - scanDesc = heap_beginscan(RewriteRelation, - 0, SnapshotNow, 1, &scanKeyData); - - while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) - { - /* Delete any comments associated with this rule */ - DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation)); - - simple_heap_delete(RewriteRelation, &tuple->t_self); - } - - heap_endscan(scanDesc); - heap_close(RewriteRelation, RowExclusiveLock); } --- 184,187 ---- Index: src/bin/initdb/initdb.sh =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.sh,v retrieving revision 1.147 diff -c -r1.147 initdb.sh *** src/bin/initdb/initdb.sh 2002/04/04 04:25:50 1.147 --- src/bin/initdb/initdb.sh 2002/04/15 12:22:44 *************** *** 599,604 **** --- 599,1218 ---- PGSQL_OPT="$PGSQL_OPT -O" + $ECHO_N "initializing pg_depend... "$ECHO_C + + "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null < 0 \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- Toast tables depend on the relations + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , toast.oid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , pg_class.oid \ + , 0 \ + , TRUE \ + FROM pg_class \ + JOIN pg_class as toast ON (pg_class.reltoastrelid = toast.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , TRUE \ + FROM pg_depend; + + -- Indexes depend on the relation + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , idx.oid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , pg_class.oid \ + , 0 \ + , TRUE \ + FROM pg_class \ + JOIN pg_class as idx ON (pg_class.reltoastidxid = idx.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , TRUE \ + FROM pg_depend; + + -- Procedures depend on their control language + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_language') \ + , pg_language.oid \ + , 0 \ + , FALSE \ + FROM pg_proc \ + JOIN pg_language ON (prolang = pg_language.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- Procedures depend on their control language (*= for oid and oidvector needed) + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_proc \ + JOIN pg_type ON (pg_type.oid IN ( proargtypes[0] \ + , proargtypes[1] \ + , proargtypes[2] \ + , proargtypes[3] \ + , prorettype \ + )) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_trigger.tgfoid -> pg_function + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \ + , tgfoid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_trigger \ + JOIN pg_proc ON (pg_trigger.tgfoid = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_trigger.tgrelid -> pg_class + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \ + , tgrelid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , pg_class.oid \ + , 0 \ + , FALSE \ + FROM pg_trigger \ + JOIN pg_class ON (pg_trigger.tgrelid = pg_class.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_trigger.tgconstrrelid -> pg_class (always cascade) + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_trigger') \ + , tgconstrrelid \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , pg_class.oid \ + , 0 \ + , TRUE \ + FROM pg_trigger \ + JOIN pg_class ON (pg_trigger.tgconstrrelid = pg_class.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , TRUE \ + FROM pg_depend; + + -- pg_rewrite.ev_class -> pg_class + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') \ + , ev_class \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_class') \ + , pg_class.oid \ + , 0 \ + , TRUE \ + FROM pg_rewrite \ + JOIN pg_class ON (pg_rewrite.ev_class = pg_class.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , TRUE \ + FROM pg_depend; + + -- pg_operator.oprleft -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprleft \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_type ON (pg_operator.oprleft = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprright -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprright \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_type ON (pg_operator.oprright = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprresult -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprresult \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_type ON (pg_operator.oprresult = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprcom -> pg_operator + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , pg_operator.oprcom \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , dep.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_operator as dep ON (pg_operator.oprresult = dep.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprnegate -> pg_operator + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , pg_operator.oprnegate \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , dep.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_operator as dep ON (pg_operator.oprnegate = dep.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprlsortop -> pg_operator + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , pg_operator.oprlsortop \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , dep.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_operator as dep ON (pg_operator.oprlsortop = dep.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprrsortop -> pg_operator + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , pg_operator.oprrsortop \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , dep.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_operator as dep ON (pg_operator.oprrsortop = dep.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprcode -> pg_proc + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprcode \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_proc ON (pg_operator.oprcode = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprrest -> pg_proc + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprrest \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_proc ON (pg_operator.oprrest = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_operator.oprjoin -> pg_proc + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_operator') \ + , oprjoin \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_operator \ + JOIN pg_proc ON (pg_operator.oprjoin = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_aggregate.aggtransfn -> pg_proc + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \ + , aggtransfn \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_aggregate \ + JOIN pg_proc ON (pg_aggregate.aggtransfn = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_aggregate.aggfinalfn -> pg_proc + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \ + , aggfinalfn \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_proc') \ + , pg_proc.oid \ + , 0 \ + , FALSE \ + FROM pg_aggregate \ + JOIN pg_proc ON (pg_aggregate.aggfinalfn = pg_proc.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_aggregate.aggbasetype -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \ + , aggbasetype \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_aggregate \ + JOIN pg_type ON (pg_aggregate.aggbasetype = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_aggregate.aggtranstype -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \ + , aggtranstype \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_aggregate \ + JOIN pg_type ON (pg_aggregate.aggtranstype = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + + -- pg_aggregate.aggfinaltype -> pg_type + INSERT INTO pg_depend \ + SELECT \ + DISTINCT (SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') \ + , aggfinaltype \ + , 0 \ + , (SELECT oid FROM pg_class WHERE relname = 'pg_type') \ + , pg_type.oid \ + , 0 \ + , FALSE \ + FROM pg_aggregate \ + JOIN pg_type ON (pg_aggregate.aggfinaltype = pg_type.oid) \ + EXCEPT \ + SELECT classid \ + , objid \ + , objsubid \ + , depclassid \ + , depobjid \ + , depobjsubid \ + , FALSE \ + FROM pg_depend; + EOF + $ECHO_N "initializing pg_shadow... "$ECHO_C "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <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 ----