Index: doc/src/sgml/catalogs.sgml
===================================================================
RCS file: /home/alvherre/cvs/pgsql/doc/src/sgml/catalogs.sgml,v
retrieving revision 2.94
diff -c -r2.94 catalogs.sgml
*** doc/src/sgml/catalogs.sgml 13 Dec 2004 18:05:07 -0000 2.94
--- doc/src/sgml/catalogs.sgml 13 Dec 2004 20:15:32 -0000
***************
*** 174,179 ****
--- 174,183 ----
+ pg_shdepend
+ cross-database dependencies between objects
+
+ pg_statisticplanner statistics
***************
*** 3095,3100 ****
--- 3099,3174 ----
+
+ pg_shdepend
+
+
+ pg_shdepend
+
+
+
+ The shared catalog pg_shdepend records the
+ dependency relationships between database objects and global objects,
+ such as users and tablespaces. This information allows DROP
+ USER and DROP TABLESPACE to ensure that
+ those objects are unreferenced before attempting to delete them.
+
+
+
+ pg_depend> Columns
+
+
+
+
+ Name
+ Type
+ References
+ Description
+
+
+
+
+
+ dbid
+ oid
+ pg_database.oid
+ The OID of the database the dependent object is in
+
+
+
+ classid
+ oid
+ pg_class.oid
+ The OID of the system catalog the dependent object is in
+
+
+
+ objid
+ oid
+ any OID column
+ The OID of the specific dependent object
+
+
+
+ refclassid
+ oid
+ pg_class.oid
+ The OID of the system catalog the referenced object is in
+
+
+
+ refobjid
+ oid
+ any OID column
+ The OID of the specific referenced object
+
+
+
+
+
+
+
+
pg_statistic
Index: src/backend/catalog/Makefile
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/Makefile,v
retrieving revision 1.53
diff -c -r1.53 Makefile
*** src/backend/catalog/Makefile 21 Jul 2004 20:34:45 -0000 1.53
--- src/backend/catalog/Makefile 10 Dec 2004 14:21:47 -0000
***************
*** 12,18 ****
OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
! pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_type.o
BKIFILES = postgres.bki postgres.description
--- 12,19 ----
OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
! pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
! pg_type.o
BKIFILES = postgres.bki postgres.description
***************
*** 32,38 ****
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
! pg_tablespace.h pg_depend.h indexing.h \
)
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
--- 33,39 ----
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
! pg_tablespace.h pg_depend.h pg_shdepend.h indexing.h \
)
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
Index: src/backend/catalog/catalog.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/catalog.c,v
retrieving revision 1.56
diff -c -r1.56 catalog.c
*** src/backend/catalog/catalog.c 29 Aug 2004 04:12:26 -0000 1.56
--- src/backend/catalog/catalog.c 10 Dec 2004 20:48:52 -0000
***************
*** 9,15 ****
*
*
* IDENTIFICATION
! * $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.56 2004/08/29 04:12:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
--- 9,15 ----
*
*
* IDENTIFICATION
! * $PostgreSQL: pgsql-server/src/backend/catalog/catalog.c,v 1.55 2004/08/04 21:33:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Index: src/backend/catalog/dependency.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/dependency.c,v
retrieving revision 1.40
diff -c -r1.40 dependency.c
*** src/backend/catalog/dependency.c 12 Oct 2004 21:54:36 -0000 1.40
--- src/backend/catalog/dependency.c 10 Dec 2004 14:32:52 -0000
***************
*** 32,40 ****
--- 32,42 ----
#include "catalog/pg_rewrite.h"
#include "catalog/pg_trigger.h"
#include "commands/comment.h"
+ #include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/proclang.h"
#include "commands/schemacmds.h"
+ #include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "lib/stringinfo.h"
***************
*** 496,501 ****
--- 498,504 ----
break;
}
+ /* delete the pg_depend tuple */
simple_heap_delete(depRel, &tup->t_self);
}
***************
*** 572,577 ****
--- 575,588 ----
DeleteComments(object->objectId, object->classId, object->objectSubId);
/*
+ * Delete shared dependency references related to this object.
+ * Sub-objects (columns) don't have dependencies on global objects,
+ * so skip them.
+ */
+ if (object->objectSubId == 0)
+ deleteSharedDependencyRecordsFor(object->classId, object->objectId);
+
+ /*
* CommandCounterIncrement here to ensure that preceding changes are
* all visible.
*/
***************
*** 1305,1313 ****
--- 1316,1327 ----
static void
init_object_classes(void)
{
+ object_classes[OCLASS_AM] = get_system_catalog_relid(AccessMethodRelationName);
object_classes[OCLASS_CLASS] = RelOid_pg_class;
object_classes[OCLASS_PROC] = RelOid_pg_proc;
object_classes[OCLASS_TYPE] = RelOid_pg_type;
+ object_classes[OCLASS_DATABASE] = RelOid_pg_database;
+ object_classes[OCLASS_SHADOW] = RelOid_pg_shadow;
object_classes[OCLASS_CAST] = get_system_catalog_relid(CastRelationName);
object_classes[OCLASS_CONSTRAINT] = get_system_catalog_relid(ConstraintRelationName);
object_classes[OCLASS_CONVERSION] = get_system_catalog_relid(ConversionRelationName);
***************
*** 1318,1323 ****
--- 1332,1338 ----
object_classes[OCLASS_REWRITE] = get_system_catalog_relid(RewriteRelationName);
object_classes[OCLASS_TRIGGER] = get_system_catalog_relid(TriggerRelationName);
object_classes[OCLASS_SCHEMA] = get_system_catalog_relid(NamespaceRelationName);
+ object_classes[OCLASS_TBLSPACE] = RelOid_pg_tablespace;
object_classes_initialized = true;
}
***************
*** 1344,1349 ****
--- 1359,1376 ----
case RelOid_pg_type:
Assert(object->objectSubId == 0);
return OCLASS_TYPE;
+
+ case RelOid_pg_database:
+ Assert(object->objectSubId == 0);
+ return OCLASS_DATABASE;
+
+ case RelOid_pg_tablespace:
+ Assert(object->objectSubId == 0);
+ return OCLASS_TBLSPACE;
+
+ case RelOid_pg_shadow:
+ Assert(object->objectSubId == 0);
+ return OCLASS_SHADOW;
}
/*
***************
*** 1352,1357 ****
--- 1379,1389 ----
if (!object_classes_initialized)
init_object_classes();
+ if (object->classId == object_classes[OCLASS_AM])
+ {
+ Assert(object->objectSubId == 0);
+ return OCLASS_AM;
+ }
if (object->classId == object_classes[OCLASS_CAST])
{
Assert(object->objectSubId == 0);
***************
*** 1439,1444 ****
--- 1471,1510 ----
format_type_be(object->objectId));
break;
+ case OCLASS_AM:
+ {
+ Relation amDesc;
+ ScanKeyData skey[1];
+ SysScanDesc rcscan;
+ HeapTuple tup;
+ Form_pg_am amForm;
+
+ amDesc = heap_openr(AccessMethodRelationName, AccessShareLock);
+
+ ScanKeyInit(&skey[0],
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(object->objectId));
+
+ rcscan = systable_beginscan(amDesc, AmOidIndex, true,
+ SnapshotNow, 1, skey);
+
+ tup = systable_getnext(rcscan);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "could not find tuple for access method %u",
+ object->objectId);
+
+ amForm = (Form_pg_am) GETSTRUCT(tup);
+
+ appendStringInfo(&buffer, gettext("access method %s"),
+ amForm->amname.data);
+
+ systable_endscan(rcscan);
+ heap_close(amDesc, AccessShareLock);
+ break;
+ }
+
case OCLASS_CAST:
{
Relation castDesc;
***************
*** 1715,1720 ****
--- 1781,1817 ----
break;
}
+ case OCLASS_TBLSPACE:
+ {
+ char *tblspace;
+
+ tblspace = get_tablespace_name(object->objectId);
+ if (!tblspace)
+ elog(ERROR, "cache lookup failed for tablespace %u",
+ object->objectId);
+ appendStringInfo(&buffer, gettext("tablespace %s"), tblspace);
+ break;
+ }
+
+ case OCLASS_DATABASE:
+ {
+ char *datname;
+
+ datname = get_database_name(object->objectId);
+ if (!datname)
+ elog(ERROR, "cache lookup failed for database %u",
+ object->objectId);
+ appendStringInfo(&buffer, gettext("database %s"), datname);
+ break;
+ }
+
+ case OCLASS_SHADOW:
+ {
+ appendStringInfo(&buffer, gettext("user %s"),
+ GetUserNameFromId((AclId)object->objectId));
+ break;
+ }
+
default:
appendStringInfo(&buffer, "unrecognized object %u %u %d",
object->classId,
Index: src/backend/catalog/heap.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/heap.c,v
retrieving revision 1.277
diff -c -r1.277 heap.c
*** src/backend/catalog/heap.c 1 Dec 2004 19:00:39 -0000 1.277
--- src/backend/catalog/heap.c 10 Dec 2004 14:33:13 -0000
***************
*** 332,338 ****
/* ----------------------------------------------------------------
* heap_create_with_catalog - Create a cataloged relation
*
! * this is done in 6 steps:
*
* 1) CheckAttributeNamesTypes() is used to make certain the tuple
* descriptor contains a valid set of attribute names and types
--- 332,338 ----
/* ----------------------------------------------------------------
* heap_create_with_catalog - Create a cataloged relation
*
! * this is done in 8 steps:
*
* 1) CheckAttributeNamesTypes() is used to make certain the tuple
* descriptor contains a valid set of attribute names and types
***************
*** 789,794 ****
--- 789,796 ----
* make a dependency link to force the relation to be deleted if its
* namespace is. Skip this in bootstrap mode, since we don't make
* dependencies while bootstrapping.
+ *
+ * Also make dependency links to its owner and tablespace, as needed.
*/
if (!IsBootstrapProcessingMode())
{
***************
*** 798,807 ****
--- 800,826 ----
myself.classId = RelOid_pg_class;
myself.objectId = new_rel_oid;
myself.objectSubId = 0;
+
+ /* the relation depends on its namespace */
referenced.classId = get_system_catalog_relid(NamespaceRelationName);
referenced.objectId = relnamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ /* the relation depends on its tablespace, if specified */
+ if (reltablespace != 0)
+ {
+ referenced.classId = get_system_catalog_relid(TableSpaceRelationName);
+ referenced.objectId = reltablespace;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
+ }
+
+ /* the relation depends on its owner */
+ referenced.classId = get_system_catalog_relid(ShadowRelationName);
+ referenced.objectId = GetUserId();
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
}
/*
Index: src/backend/catalog/pg_conversion.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/pg_conversion.c,v
retrieving revision 1.19
diff -c -r1.19 pg_conversion.c
*** src/backend/catalog/pg_conversion.c 29 Aug 2004 04:12:28 -0000 1.19
--- src/backend/catalog/pg_conversion.c 30 Oct 2004 15:18:49 -0000
***************
*** 121,126 ****
--- 121,132 ----
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ /* record shared dependency on owner */
+ referenced.classId = get_system_catalog_relid(ShadowRelationName);
+ referenced.objectId = conowner;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
+
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
Index: src/backend/catalog/pg_operator.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/pg_operator.c,v
retrieving revision 1.86
diff -c -r1.86 pg_operator.c
*** src/backend/catalog/pg_operator.c 29 Aug 2004 04:12:29 -0000 1.86
--- src/backend/catalog/pg_operator.c 30 Oct 2004 15:19:29 -0000
***************
*** 891,896 ****
--- 891,897 ----
/* In case we are updating a shell, delete any existing entries */
deleteDependencyRecordsFor(myself.classId, myself.objectId);
+ deleteSharedDependencyRecordsFor(myself.classId, myself.objectId);
/* Dependency on namespace */
if (OidIsValid(oper->oprnamespace))
***************
*** 964,967 ****
--- 965,974 ----
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
+
+ /* Dependency on owner */
+ referenced.classId = get_system_catalog_relid(ShadowRelationName);
+ referenced.objectId = oper->oprowner;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
}
Index: src/backend/catalog/pg_proc.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/pg_proc.c,v
retrieving revision 1.121
diff -c -r1.121 pg_proc.c
*** src/backend/catalog/pg_proc.c 18 Oct 2004 01:45:38 -0000 1.121
--- src/backend/catalog/pg_proc.c 30 Oct 2004 04:01:36 -0000
***************
*** 295,300 ****
--- 295,303 ----
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
+ /* dependency on owner */
+ recordDependencyOnCurrentUser(&myself);
+
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
Index: src/backend/catalog/pg_type.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/catalog/pg_type.c,v
retrieving revision 1.96
diff -c -r1.96 pg_type.c
*** src/backend/catalog/pg_type.c 29 Aug 2004 05:06:41 -0000 1.96
--- src/backend/catalog/pg_type.c 8 Dec 2004 05:44:26 -0000
***************
*** 488,493 ****
--- 488,496 ----
/* Normal dependency on the default expression. */
if (defaultExpr)
recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
+
+ /* Shared dependency on owner. */
+ recordDependencyOnCurrentUser(&myself);
}
/*
Index: src/backend/commands/conversioncmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/conversioncmds.c,v
retrieving revision 1.15
diff -c -r1.15 conversioncmds.c
*** src/backend/commands/conversioncmds.c 29 Aug 2004 05:06:41 -0000 1.15
--- src/backend/commands/conversioncmds.c 30 Oct 2004 15:21:47 -0000
***************
*** 18,23 ****
--- 18,24 ----
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
+ #include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
***************
*** 221,226 ****
--- 222,231 ----
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+ /* Update shared dependency reference */
+ shdependChangeOwner(get_system_catalog_relid(ConversionRelationName),
+ conversionOid,
+ newOwnerSysId);
}
heap_close(rel, NoLock);
Index: src/backend/commands/dbcommands.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.147
diff -c -r1.147 dbcommands.c
*** src/backend/commands/dbcommands.c 18 Nov 2004 01:14:26 -0000 1.147
--- src/backend/commands/dbcommands.c 10 Dec 2004 03:58:29 -0000
***************
*** 23,28 ****
--- 23,29 ----
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/catalog.h"
+ #include "catalog/dependency.h"
#include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
***************
*** 343,348 ****
--- 344,350 ----
/*
* Iterate through all tablespaces of the template database, and copy
* each one to the new database.
+ * XXX maybe it could be done better using pg_shdepend info.
*/
rel = heap_openr(TableSpaceRelationName, AccessShareLock);
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
***************
*** 497,502 ****
--- 499,526 ----
/* Update indexes */
CatalogUpdateIndexes(pg_database_rel, tuple);
+ /* Create pg_shdepend entries */
+ copyTemplateDependencies(src_dboid, dboid);
+ /* Register tablespace and owner dependencies */
+ {
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = RelOid_pg_database;
+ myself.objectId = dboid;
+ myself.objectSubId = 0;
+
+ referenced.classId = RelOid_pg_shadow;
+ referenced.objectId = datdba;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
+
+ referenced.classId = RelOid_pg_tablespace;
+ referenced.objectId = dst_deftablespace;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced);
+ }
+
/*
* Force dirty buffers out to disk, so that newly-connecting backends
* will see the new database in pg_database right away. (They'll see
***************
*** 633,638 ****
--- 657,667 ----
remove_dbtablespaces(db_id);
/*
+ * Remove shared dependency references in the database.
+ */
+ dropDatabaseDependencies(db_id);
+
+ /*
* Force dirty buffers out to disk, so that newly-connecting backends
* will see the database tuple marked dead in pg_database right away.
* (They'll see an uncommitted deletion, but they don't care; see
***************
*** 917,922 ****
--- 946,958 ----
heap_freetuple(newtuple);
+ /*
+ * Update shared dependency references
+ */
+ shdependChangeOwner(RelOid_pg_database,
+ HeapTupleGetOid(tuple),
+ newOwnerSysId);
+
/* must release buffer pins before FlushRelationBuffers */
systable_endscan(scan);
Index: src/backend/commands/functioncmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/functioncmds.c,v
retrieving revision 1.52
diff -c -r1.52 functioncmds.c
*** src/backend/commands/functioncmds.c 29 Aug 2004 05:06:41 -0000 1.52
--- src/backend/commands/functioncmds.c 30 Oct 2004 14:32:21 -0000
***************
*** 798,803 ****
--- 798,808 ----
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);
+ /* update shared dependency reference */
+ shdependChangeOwner(get_system_catalog_relid(ProcedureRelationName),
+ procOid,
+ newOwnerSysId);
+
heap_freetuple(newtuple);
}
Index: src/backend/commands/opclasscmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/opclasscmds.c,v
retrieving revision 1.28
diff -c -r1.28 opclasscmds.c
*** src/backend/commands/opclasscmds.c 29 Aug 2004 05:06:41 -0000 1.28
--- src/backend/commands/opclasscmds.c 30 Oct 2004 15:22:27 -0000
***************
*** 392,397 ****
--- 392,400 ----
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
+ /* dependency on owner */
+ recordDependencyOnCurrentUser(&myself);
+
heap_close(rel, RowExclusiveLock);
}
***************
*** 964,969 ****
--- 967,977 ----
CatalogUpdateIndexes(rel, tup);
}
+ /* Update shared dependency reference */
+ shdependChangeOwner(get_system_catalog_relid(OperatorClassRelationName),
+ amOid,
+ newOwnerSysId);
+
heap_close(rel, NoLock);
heap_freetuple(tup);
}
Index: src/backend/commands/operatorcmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/operatorcmds.c,v
retrieving revision 1.19
diff -c -r1.19 operatorcmds.c
*** src/backend/commands/operatorcmds.c 29 Aug 2004 05:06:41 -0000 1.19
--- src/backend/commands/operatorcmds.c 30 Oct 2004 14:33:34 -0000
***************
*** 311,316 ****
--- 311,323 ----
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ /*
+ * Update shared dependency references.
+ */
+ shdependChangeOwner(get_system_catalog_relid(OperatorRelationName),
+ operOid,
+ newOwnerSysId);
}
heap_close(rel, NoLock);
Index: src/backend/commands/schemacmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/schemacmds.c,v
retrieving revision 1.26
diff -c -r1.26 schemacmds.c
*** src/backend/commands/schemacmds.c 5 Nov 2004 19:15:57 -0000 1.26
--- src/backend/commands/schemacmds.c 6 Nov 2004 18:08:35 -0000
***************
*** 47,52 ****
--- 47,53 ----
AclId owner_userid;
AclId saved_userid;
AclResult aclresult;
+ ObjectAddress myself;
saved_userid = GetUserId();
***************
*** 147,152 ****
--- 148,160 ----
}
}
+ /* Record dependency on owner*/
+ myself.classId = get_system_catalog_relid(NamespaceRelationName);
+ myself.objectId = namespaceId;
+ myself.objectSubId = 0;
+
+ recordDependencyOnCurrentUser(&myself);
+
/* Reset search path to normal state */
PopSpecialNamespace(namespaceId);
***************
*** 345,350 ****
--- 353,365 ----
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
+
+ /*
+ * Update shared dependency references.
+ */
+ shdependChangeOwner(get_system_catalog_relid(NamespaceRelationName),
+ HeapTupleGetOid(tup),
+ newOwnerSysId);
}
ReleaseSysCache(tup);
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.140
diff -c -r1.140 tablecmds.c
*** src/backend/commands/tablecmds.c 16 Nov 2004 23:34:22 -0000 1.140
--- src/backend/commands/tablecmds.c 2 Dec 2004 22:17:19 -0000
***************
*** 5256,5261 ****
--- 5256,5266 ----
heap_freetuple(newtuple);
/*
+ * Update shared dependency reference.
+ */
+ shdependChangeOwner(RelOid_pg_class, relationOid, newOwnerSysId);
+
+ /*
* If we are operating on a table, also change the ownership of
* any indexes and sequences that belong to the table, as well as
* the table's toast table (if it has one)
***************
*** 5439,5444 ****
--- 5444,5452 ----
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_TABLESPACE, tablespacename);
+ /* Update shared dependency reference */
+ shdependChangeTablespace(RelOid_pg_class, tab->relid, tablespaceId);
+
/* Save info for Phase 3 to do the real work */
if (OidIsValid(tab->newTableSpace))
ereport(ERROR,
Index: src/backend/commands/tablespace.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/tablespace.c,v
retrieving revision 1.14
diff -c -r1.14 tablespace.c
*** src/backend/commands/tablespace.c 5 Nov 2004 19:15:57 -0000 1.14
--- src/backend/commands/tablespace.c 9 Dec 2004 05:23:38 -0000
***************
*** 51,56 ****
--- 51,57 ----
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
+ #include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
***************
*** 340,345 ****
--- 341,360 ----
set_short_version(location);
/*
+ * Record dependency link from tablespace to owner.
+ * XXX maybe this should be done after the symlink is created?
+ */
+ {
+ ObjectAddress myself;
+
+ myself.classId = RelOid_pg_tablespace;
+ myself.objectId = tablespaceoid;
+ myself.objectSubId = 0;
+
+ recordDependencyOnCurrentUser(&myself);
+ }
+
+ /*
* All seems well, create the symlink
*/
linkloc = (char *) palloc(strlen(DataDir) + 11 + 10 + 1);
***************
*** 439,444 ****
--- 454,472 ----
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE,
tablespacename);
+ /* Verify pg_shdepend entries mentioning this tablespace. */
+ if (checkSharedDependencies(RelOid_pg_tablespace, tablespaceoid) > 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_IN_USE),
+ errmsg("cannot drop tablespace \"%s\"", tablespacename),
+ errdetail("Some objects depend on this tablespace.")));
+
+ /* Remove shared dependency references to this tablespace */
+ deleteGlobalDependencyRecordsFor(RelOid_pg_tablespace, tablespaceoid);
+
+ /* Remove shared references from this tablespace to its owner */
+ deleteSharedDependencyRecordsFor(RelOid_pg_tablespace, tablespaceoid);
+
/*
* Remove the pg_tablespace tuple (this will roll back if we fail
* below)
***************
*** 865,870 ****
--- 893,903 ----
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);
+ /* Update shared dependency reference. */
+ shdependChangeOwner(RelOid_pg_tablespace,
+ HeapTupleGetOid(tup),
+ newOwnerSysId);
+
heap_freetuple(newtuple);
}
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.64
diff -c -r1.64 typecmds.c
*** src/backend/commands/typecmds.c 7 Oct 2004 15:21:52 -0000 1.64
--- src/backend/commands/typecmds.c 30 Oct 2004 03:24:21 -0000
***************
*** 2111,2116 ****
--- 2111,2120 ----
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ shdependChangeOwner(get_system_catalog_relid(TypeRelationName),
+ typeOid,
+ newOwnerSysId);
}
/* Clean up */
Index: src/backend/commands/user.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/backend/commands/user.c,v
retrieving revision 1.146
diff -c -r1.146 user.c
*** src/backend/commands/user.c 27 Sep 2004 04:01:23 -0000 1.146
--- src/backend/commands/user.c 8 Dec 2004 04:23:56 -0000
***************
*** 19,24 ****
--- 19,25 ----
#include "access/heapam.h"
#include "catalog/catname.h"
+ #include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_database.h"
#include "catalog/pg_group.h"
***************
*** 1091,1097 ****
tmp_tuple;
Relation pg_rel;
TupleDesc pg_dsc;
- ScanKeyData scankey;
HeapScanDesc scan;
AclId usesysid;
--- 1092,1097 ----
***************
*** 1114,1156 ****
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("session user cannot be dropped")));
! /*
! * Check if user still owns a database. If so, error out.
! *
! * (It used to be that this function would drop the database
! * automatically. This is not only very dangerous for people that
! * don't read the manual, it doesn't seem to be the behaviour one
! * would expect either.) -- petere 2000/01/14)
! */
! pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
! pg_dsc = RelationGetDescr(pg_rel);
!
! ScanKeyInit(&scankey,
! Anum_pg_database_datdba,
! BTEqualStrategyNumber, F_INT4EQ,
! Int32GetDatum(usesysid));
!
! scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
!
! if ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
! {
! char *dbname;
!
! dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("user \"%s\" cannot be dropped", user),
! errdetail("The user owns database \"%s\".", dbname)));
! }
! heap_endscan(scan);
! heap_close(pg_rel, AccessShareLock);
!
! /*
! * Somehow we'd have to check for tables, views, etc. owned by the
! * user as well, but those could be spread out over all sorts of
! * databases which we don't have access to (easily).
! */
/*
* Remove the user from the pg_shadow table
--- 1114,1128 ----
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("session user cannot be dropped")));
! /* Verify pg_shdepend entries mentioning this user. */
! if (checkSharedDependencies(RelOid_pg_shadow, usesysid) > 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("user \"%s\" cannot be dropped", user),
! errdetail("Some objects depend on this user.")));
! /* Remove shared dependency references to this user */
! deleteGlobalDependencyRecordsFor(RelOid_pg_shadow, usesysid);
/*
* Remove the user from the pg_shadow table
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.70
diff -c -r1.70 initdb.c
*** src/bin/initdb/initdb.c 29 Nov 2004 03:05:03 -0000 1.70
--- src/bin/initdb/initdb.c 9 Dec 2004 07:53:10 -0000
***************
*** 173,178 ****
--- 173,179 ----
static void get_set_pwd(void);
static void unlimit_systables(void);
static void setup_depend(void);
+ static void setup_shared_depend(void);
static void setup_sysviews(void);
static void setup_description(void);
static void setup_conversion(void);
***************
*** 1559,1564 ****
--- 1560,1659 ----
check_ok();
}
+ static void
+ setup_shared_depend(void)
+ {
+ PG_CMD_DECL;
+ char **line;
+ static char *pg_shdepend_setup[] = {
+ /*
+ * Fill pg_shdepend with info about all existant objects.
+ * We need to take the ownership and tablespace into consideration.
+ *
+ * Note that we first clear the table to rid of dependencies recorded
+ * by normal operation, because it's incomplete.
+ */
+ "DELETE FROM pg_shdepend\n",
+
+ /* Entries for owners of database-local objects */
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_type'::regclass, oid, 'pg_shadow'::regclass, typowner"
+ " FROM pg_type t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_proc'::regclass, oid, 'pg_shadow'::regclass, proowner"
+ " FROM pg_proc t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_class'::regclass, oid, 'pg_shadow'::regclass, relowner"
+ " FROM pg_class t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_operator'::regclass, oid, 'pg_shadow'::regclass, oprowner"
+ " FROM pg_operator t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_opclass'::regclass, oid, 'pg_shadow'::regclass, opcowner"
+ " FROM pg_opclass t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_am'::regclass, oid, 'pg_shadow'::regclass, amowner"
+ " FROM pg_am t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_namespace'::regclass, oid, 'pg_shadow'::regclass, nspowner"
+ " FROM pg_namespace t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_conversion'::regclass, oid, 'pg_shadow'::regclass, conowner"
+ " FROM pg_conversion t\n",
+
+ /* Entries for tablespaces of database-local objects */
+ "INSERT INTO pg_shdepend SELECT"
+ " (SELECT oid FROM pg_database WHERE datname=current_database()),"
+ " 'pg_class'::regclass, oid, 'pg_tablespace'::regclass, reltablespace"
+ " FROM pg_class t"
+ " WHERE reltablespace <> 0\n",
+
+ /* Entries for owners of shared objects */
+ "INSERT INTO pg_shdepend SELECT"
+ " 0,"
+ " 'pg_tablespace'::regclass, oid, 'pg_shadow'::regclass, spcowner"
+ " FROM pg_tablespace t\n",
+ "INSERT INTO pg_shdepend SELECT"
+ " 0,"
+ " 'pg_database'::regclass, oid, 'pg_shadow'::regclass, datdba"
+ " FROM pg_database t\n",
+ /* Entries for tablespaces of shared objects */
+ "INSERT INTO pg_shdepend SELECT"
+ " 0,"
+ " 'pg_database'::regclass, oid, 'pg_tablespace'::regclass, dattablespace"
+ " FROM pg_database t"
+ " WHERE dattablespace <> 0\n",
+ NULL
+ };
+
+
+ fputs(_("initializing pg_shdepend ... "), stdout);
+ fflush(stdout);
+
+ snprintf(cmd, sizeof(cmd),
+ "\"%s\" %s template1 >%s",
+ backend_exec, backend_options,
+ DEVNULL);
+
+ PG_CMD_OPEN;
+
+ for (line = pg_shdepend_setup; *line != NULL; line++)
+ PG_CMD_PUTS(*line);
+
+ PG_CMD_CLOSE;
+
+ check_ok();
+ }
+
+
/*
* set up system views
*/
***************
*** 2595,2600 ****
--- 2690,2697 ----
setup_depend();
+ setup_shared_depend();
+
setup_sysviews();
setup_description();
Index: src/bin/psql/po/es.po
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/bin/psql/po/es.po,v
retrieving revision 1.5
diff -c -r1.5 es.po
*** src/bin/psql/po/es.po 11 Dec 2004 19:03:47 -0000 1.5
--- src/bin/psql/po/es.po 13 Dec 2004 20:17:40 -0000
***************
*** 809,815 ****
#, c-format
msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n"
msgstr ""
! "\\dp [PATRÓN] listar privilegios de acceso a tablas, vistas y secuencias\n"
#: help.c:228
#, c-format
--- 809,815 ----
#, c-format
msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n"
msgstr ""
! " \\dp [PATRÓN] listar privilegios de acceso a tablas, vistas y secuencias\n"
#: help.c:228
#, c-format
***************
*** 835,841 ****
msgstr ""
" \\z [PATRÓN] listar privilegios de acceso a tablas, vistas y "
"secuencias\n"
! " (lo mismo que \\dp)\n"
#: help.c:234
#, c-format
--- 835,841 ----
msgstr ""
" \\z [PATRÓN] listar privilegios de acceso a tablas, vistas y "
"secuencias\n"
! " (lo mismo que \\dp)\n"
#: help.c:234
#, c-format
Index: src/include/catalog/catname.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/include/catalog/catname.h,v
retrieving revision 1.33
diff -c -r1.33 catname.h
*** src/include/catalog/catname.h 29 Aug 2004 04:13:04 -0000 1.33
--- src/include/catalog/catname.h 29 Oct 2004 19:48:50 -0000
***************
*** 25,30 ****
--- 25,31 ----
#define ConversionRelationName "pg_conversion"
#define DatabaseRelationName "pg_database"
#define DependRelationName "pg_depend"
+ #define SharedDependRelationName "pg_shdepend"
#define DescriptionRelationName "pg_description"
#define GroupRelationName "pg_group"
#define IndexRelationName "pg_index"
Index: src/include/catalog/dependency.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/include/catalog/dependency.h,v
retrieving revision 1.13
diff -c -r1.13 dependency.h
*** src/include/catalog/dependency.h 29 Aug 2004 04:13:04 -0000 1.13
--- src/include/catalog/dependency.h 10 Dec 2004 03:58:25 -0000
***************
*** 81,90 ****
/*
! * This enum covers all system catalogs whose OIDs can appear in classId.
*/
typedef enum ObjectClass
{
OCLASS_CLASS, /* pg_class */
OCLASS_PROC, /* pg_proc */
OCLASS_TYPE, /* pg_type */
--- 81,92 ----
/*
! * This enum covers all system catalogs whose OIDs can appear in
! * pg_depend.classId or pg_shdepend.classId.
*/
typedef enum ObjectClass
{
+ OCLASS_AM, /* pg_am */
OCLASS_CLASS, /* pg_class */
OCLASS_PROC, /* pg_proc */
OCLASS_TYPE, /* pg_type */
***************
*** 98,103 ****
--- 100,109 ----
OCLASS_REWRITE, /* pg_rewrite */
OCLASS_TRIGGER, /* pg_trigger */
OCLASS_SCHEMA, /* pg_namespace */
+ /* shared system catalogs: */
+ OCLASS_TBLSPACE, /* pg_tablespace */
+ OCLASS_DATABASE, /* pg_database */
+ OCLASS_SHADOW, /* pg_shadow */
MAX_OCLASS /* MUST BE LAST */
} ObjectClass;
***************
*** 136,139 ****
--- 142,168 ----
extern long deleteDependencyRecordsFor(Oid classId, Oid objectId);
+ /* in pg_shdepend.c */
+
+ extern void recordSharedDependencyOn(const ObjectAddress *depender,
+ const ObjectAddress *referenced);
+
+ extern void recordDependencyOnCurrentUser(const ObjectAddress *depender);
+
+ extern void shdependChangeOwner(Oid classId, Oid objectId,
+ int newOwnerSysId);
+
+ extern void shdependChangeTablespace(Oid classId, Oid objectId,
+ Oid newTblspc);
+
+ extern int checkSharedDependencies(Oid classId, Oid objectId);
+
+ extern void copyTemplateDependencies(Oid templateDbId, Oid newDbId);
+
+ extern void dropDatabaseDependencies(Oid databaseId);
+
+ extern void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId);
+
+ extern void deleteGlobalDependencyRecordsFor(Oid classId, Oid objectId);
+
#endif /* DEPENDENCY_H */
Index: src/include/catalog/indexing.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/include/catalog/indexing.h,v
retrieving revision 1.83
diff -c -r1.83 indexing.h
*** src/include/catalog/indexing.h 29 Aug 2004 04:13:05 -0000 1.83
--- src/include/catalog/indexing.h 29 Oct 2004 19:49:05 -0000
***************
*** 67,72 ****
--- 67,74 ----
#define ProcedureOidIndex "pg_proc_oid_index"
#define RewriteOidIndex "pg_rewrite_oid_index"
#define RewriteRelRulenameIndex "pg_rewrite_rel_rulename_index"
+ #define SharedDependDependerIndex "pg_shdepend_depender_index"
+ #define SharedDependReferenceIndex "pg_shdepend_reference_index"
#define ShadowNameIndex "pg_shadow_usename_index"
#define ShadowSysidIndex "pg_shadow_usesysid_index"
#define StatisticRelidAttnumIndex "pg_statistic_relid_att_index"
***************
*** 165,170 ****
--- 167,176 ----
/* This following index is not used for a cache and is not unique */
DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
+ /* This following index is not used for a cache and is not unique */
+ DECLARE_INDEX(pg_shdepend_depender_index on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops));
+ /* This following index is not used for a cache and is not unique */
+ DECLARE_INDEX(pg_shdepend_reference_index on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops));
DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops));
DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index on pg_shadow using btree(usesysid int4_ops));
DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
Index: src/include/catalog/pg_tablespace.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/include/catalog/pg_tablespace.h,v
retrieving revision 1.4
diff -c -r1.4 pg_tablespace.h
*** src/include/catalog/pg_tablespace.h 29 Aug 2004 05:06:55 -0000 1.4
--- src/include/catalog/pg_tablespace.h 10 Dec 2004 20:46:27 -0000
***************
*** 8,14 ****
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
! * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.4 2004/08/29 05:06:55 momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
--- 8,14 ----
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
! * $PostgreSQL: pgsql-server/src/include/catalog/pg_tablespace.h,v 1.3 2004/08/29 04:13:05 momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
Index: src/test/regress/expected/sanity_check.out
===================================================================
RCS file: /home/alvherre/cvs/pgsql/src/test/regress/expected/sanity_check.out,v
retrieving revision 1.24
diff -c -r1.24 sanity_check.out
*** src/test/regress/expected/sanity_check.out 18 Jun 2004 06:14:27 -0000 1.24
--- src/test/regress/expected/sanity_check.out 10 Dec 2004 18:48:36 -0000
***************
*** 55,60 ****
--- 55,61 ----
pg_proc | t
pg_rewrite | t
pg_shadow | t
+ pg_shdepend | t
pg_statistic | t
pg_tablespace | t
pg_trigger | t
***************
*** 63,69 ****
shighway | t
tenk1 | t
tenk2 | t
! (53 rows)
--
-- another sanity check: every system catalog that has OIDs should have
--- 64,70 ----
shighway | t
tenk1 | t
tenk2 | t
! (54 rows)
--
-- another sanity check: every system catalog that has OIDs should have