Track dependencies on shared objects (which is to say, roles; we already

have adequate mechanisms for tracking the contents of databases and
tablespaces).  This solves the longstanding problem that you can drop a
user who still owns objects and/or has access permissions.
Alvaro Herrera, with some kibitzing from Tom Lane.
This commit is contained in:
Tom Lane 2005-07-07 20:40:02 +00:00
parent 442b59dd8b
commit 59d1b3d99e
38 changed files with 1842 additions and 85 deletions

View File

@ -1,6 +1,6 @@
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.106 2005/06/28 05:08:50 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.107 2005/07/07 20:39:56 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
@ -173,6 +173,11 @@
<entry>query rewrite rules</entry> <entry>query rewrite rules</entry>
</row> </row>
<row>
<entry><link linkend="catalog-pg-shdepend"><structname>pg_shdepend</structname></link></entry>
<entry>dependencies on shared objects</entry>
</row>
<row> <row>
<entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry> <entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
<entry>planner statistics</entry> <entry>planner statistics</entry>
@ -1890,6 +1895,12 @@
RESTRICT</> case. RESTRICT</> case.
</para> </para>
<para>
See also <link linkend="catalog-pg-shdepend"><structname>pg_shdepend</structname></link>,
which performs a similar function for dependencies involving objects
that are shared across a database cluster.
</para>
<table> <table>
<title><structname>pg_depend</> Columns</title> <title><structname>pg_depend</> Columns</title>
@ -3024,7 +3035,7 @@
<row> <row>
<entry><structfield>proargmodes</structfield></entry> <entry><structfield>proargmodes</structfield></entry>
<entry><type>"char"[]</type></entry> <entry><type>char[]</type></entry>
<entry></entry> <entry></entry>
<entry> <entry>
An array with the modes of the function arguments, encoded as An array with the modes of the function arguments, encoded as
@ -3198,6 +3209,149 @@
</sect1> </sect1>
<sect1 id="catalog-pg-shdepend">
<title><structname>pg_shdepend</structname></title>
<indexterm zone="catalog-pg-shdepend">
<primary>pg_shdepend</primary>
</indexterm>
<para>
The catalog <structname>pg_shdepend</structname> records the
dependency relationships between database objects and shared objects,
such as roles. This information allows
<productname>PostgreSQL</productname> to ensure that those objects are
unreferenced before attempting to delete them.
</para>
<para>
See also <link linkend="catalog-pg-depend"><structname>pg_depend</structname></link>,
which performs a similar function for dependencies involving objects
within a single database.
</para>
<para>
Unlike most system catalogs, <structname>pg_shdepend</structname>
is shared across all databases of a cluster: there is only one
copy of <structname>pg_shdepend</structname> per cluster, not
one per database.
</para>
<table>
<title><structname>pg_shdepend</> Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>dbid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.oid</literal></entry>
<entry>The OID of the database the dependent object is in,
or zero for a shared object</entry>
</row>
<row>
<entry><structfield>classid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
<entry>The OID of the system catalog the dependent object is in</entry>
</row>
<row>
<entry><structfield>objid</structfield></entry>
<entry><type>oid</type></entry>
<entry>any OID column</entry>
<entry>The OID of the specific dependent object</entry>
</row>
<row>
<entry><structfield>refclassid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
<entry>The OID of the system catalog the referenced object is in
(must be a shared catalog)</entry>
</row>
<row>
<entry><structfield>refobjid</structfield></entry>
<entry><type>oid</type></entry>
<entry>any OID column</entry>
<entry>The OID of the specific referenced object</entry>
</row>
<row>
<entry><structfield>deptype</structfield></entry>
<entry><type>char</type></entry>
<entry></entry>
<entry>
A code defining the specific semantics of this dependency relationship; see text.
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
In all cases, a <structname>pg_shdepend</structname> entry indicates that
the referenced object may not be dropped without also dropping the dependent
object. However, there are several subflavors identified by
<structfield>deptype</>:
<variablelist>
<varlistentry>
<term><symbol>SHARED_DEPENDENCY_OWNER</> (<literal>o</>)</term>
<listitem>
<para>
The referenced object (which must be a role) is the owner of the
dependent object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><symbol>SHARED_DEPENDENCY_ACL</> (<literal>a</>)</term>
<listitem>
<para>
The referenced object (which must be a role) is mentioned in the
ACL (access control list, i.e., privileges list) of the
dependent object. (A <symbol>SHARED_DEPENDENCY_ACL</> entry is
not made for the owner of the object, since the owner will have
a <symbol>SHARED_DEPENDENCY_OWNER</> entry anyway.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><symbol>SHARED_DEPENDENCY_PIN</> (<literal>p</>)</term>
<listitem>
<para>
There is no dependent object; this type of entry is a signal
that the system itself depends on the referenced object, and so
that object must never be deleted. Entries of this type are
created only by <command>initdb</command>. The columns for the
dependent object contain zeroes.
</para>
</listitem>
</varlistentry>
</variablelist>
Other dependency flavors may be needed in future. Note in particular
that the current definition only supports roles as referenced objects.
</para>
</sect1>
<sect1 id="catalog-pg-statistic"> <sect1 id="catalog-pg-statistic">
<title><structname>pg_statistic</structname></title> <title><structname>pg_statistic</structname></title>
@ -4196,7 +4350,7 @@
<entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.oid</literal></entry> <entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.oid</literal></entry>
<entry> <entry>
OID of the database in which the object exists, or OID of the database in which the object exists, or
zero if the object is a globally-shared object, or zero if the object is a shared object, or
NULL if the object is a transaction ID NULL if the object is a transaction ID
</entry> </entry>
</row> </row>

View File

@ -2,7 +2,7 @@
# #
# Makefile for backend/catalog # Makefile for backend/catalog
# #
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.54 2005/06/28 05:08:52 tgl Exp $ # $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.55 2005/07/07 20:39:57 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -12,7 +12,8 @@ include $(top_builddir)/src/Makefile.global
OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \ 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_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 pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
pg_type.o
BKIFILES = postgres.bki postgres.description BKIFILES = postgres.bki postgres.description
@ -31,7 +32,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.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 \ 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_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_namespace.h pg_conversion.h pg_database.h \ pg_namespace.h pg_conversion.h pg_database.h pg_shdepend.h \
pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \ pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \
indexing.h \ indexing.h \
) )

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.114 2005/06/28 19:51:21 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.115 2005/07/07 20:39:57 tgl Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
@ -19,6 +19,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_auth_members.h" #include "catalog/pg_auth_members.h"
@ -252,6 +253,10 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
Datum values[Natts_pg_class]; Datum values[Natts_pg_class];
char nulls[Natts_pg_class]; char nulls[Natts_pg_class];
char replaces[Natts_pg_class]; char replaces[Natts_pg_class];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
/* open pg_class */ /* open pg_class */
relation = heap_open(RelationRelationId, RowExclusiveLock); relation = heap_open(RelationRelationId, RowExclusiveLock);
@ -344,11 +349,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -359,13 +372,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces); newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple); simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(RelationRelationId, relOid,
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl); pfree(new_acl);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -422,6 +441,10 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
Datum values[Natts_pg_database]; Datum values[Natts_pg_database];
char nulls[Natts_pg_database]; char nulls[Natts_pg_database];
char replaces[Natts_pg_database]; char replaces[Natts_pg_database];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(DatabaseRelationId, RowExclusiveLock); relation = heap_open(DatabaseRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0], ScanKeyInit(&entry[0],
@ -503,11 +526,19 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -523,6 +554,12 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
pfree(new_acl); pfree(new_acl);
heap_endscan(scan); heap_endscan(scan);
@ -580,6 +617,10 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
Datum values[Natts_pg_proc]; Datum values[Natts_pg_proc];
char nulls[Natts_pg_proc]; char nulls[Natts_pg_proc];
char replaces[Natts_pg_proc]; char replaces[Natts_pg_proc];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
oid = LookupFuncNameTypeNames(func->funcname, func->funcargs, false); oid = LookupFuncNameTypeNames(func->funcname, func->funcargs, false);
@ -658,11 +699,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -673,13 +722,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces); newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple); simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(ProcedureRelationId, oid,
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl); pfree(new_acl);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -734,6 +789,10 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
Datum values[Natts_pg_language]; Datum values[Natts_pg_language];
char nulls[Natts_pg_language]; char nulls[Natts_pg_language];
char replaces[Natts_pg_language]; char replaces[Natts_pg_language];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(LanguageRelationId, RowExclusiveLock); relation = heap_open(LanguageRelationId, RowExclusiveLock);
tuple = SearchSysCache(LANGNAME, tuple = SearchSysCache(LANGNAME,
@ -822,11 +881,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -837,13 +904,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces); newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple); simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl); pfree(new_acl);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -898,6 +971,10 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
Datum values[Natts_pg_namespace]; Datum values[Natts_pg_namespace];
char nulls[Natts_pg_namespace]; char nulls[Natts_pg_namespace];
char replaces[Natts_pg_namespace]; char replaces[Natts_pg_namespace];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(NamespaceRelationId, RowExclusiveLock); relation = heap_open(NamespaceRelationId, RowExclusiveLock);
tuple = SearchSysCache(NAMESPACENAME, tuple = SearchSysCache(NAMESPACENAME,
@ -977,11 +1054,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -992,13 +1077,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces); newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple); simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl); pfree(new_acl);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
@ -1055,6 +1146,10 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
Datum values[Natts_pg_tablespace]; Datum values[Natts_pg_tablespace];
char nulls[Natts_pg_tablespace]; char nulls[Natts_pg_tablespace];
char replaces[Natts_pg_tablespace]; char replaces[Natts_pg_tablespace];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(TableSpaceRelationId, RowExclusiveLock); relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0], ScanKeyInit(&entry[0],
@ -1136,11 +1231,19 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum); old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant, new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior, stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges, stmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */ /* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values)); MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls)); MemSet(nulls, ' ', sizeof(nulls));
@ -1156,6 +1259,12 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
/* keep the catalog indexes up to date */ /* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple); CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(TableSpaceRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
pfree(new_acl); pfree(new_acl);
heap_endscan(scan); heap_endscan(scan);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.44 2005/04/14 20:03:23 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.45 2005/07/07 20:39:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -22,9 +22,11 @@
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_attrdef.h" #include "catalog/pg_attrdef.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h" #include "catalog/pg_cast.h"
#include "catalog/pg_constraint.h" #include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_depend.h" #include "catalog/pg_depend.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
@ -32,12 +34,15 @@
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h" #include "catalog/pg_rewrite.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_trigger.h" #include "catalog/pg_trigger.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/comment.h" #include "commands/comment.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "commands/proclang.h" #include "commands/proclang.h"
#include "commands/schemacmds.h" #include "commands/schemacmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "commands/typecmds.h" #include "commands/typecmds.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
@ -509,6 +514,7 @@ recursiveDeletion(const ObjectAddress *object,
break; break;
} }
/* delete the pg_depend tuple */
simple_heap_delete(depRel, &tup->t_self); simple_heap_delete(depRel, &tup->t_self);
} }
@ -584,6 +590,14 @@ recursiveDeletion(const ObjectAddress *object,
*/ */
DeleteComments(object->objectId, object->classId, object->objectSubId); 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 * CommandCounterIncrement here to ensure that preceding changes are
* all visible. * all visible.
@ -1365,6 +1379,18 @@ getObjectClass(const ObjectAddress *object)
case NamespaceRelationId: case NamespaceRelationId:
Assert(object->objectSubId == 0); Assert(object->objectSubId == 0);
return OCLASS_SCHEMA; return OCLASS_SCHEMA;
case AuthIdRelationId:
Assert(object->objectSubId == 0);
return OCLASS_ROLE;
case DatabaseRelationId:
Assert(object->objectSubId == 0);
return OCLASS_DATABASE;
case TableSpaceRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TBLSPACE;
} }
/* shouldn't get here */ /* shouldn't get here */
@ -1680,6 +1706,37 @@ getObjectDescription(const ObjectAddress *object)
break; break;
} }
case OCLASS_ROLE:
{
appendStringInfo(&buffer, _("role %s"),
GetUserNameFromId(object->objectId));
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, _("database %s"), datname);
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, _("tablespace %s"), tblspace);
break;
}
default: default:
appendStringInfo(&buffer, "unrecognized object %u %u %d", appendStringInfo(&buffer, "unrecognized object %u %u %d",
object->classId, object->classId,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.285 2005/06/05 00:38:07 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.286 2005/07/07 20:39:57 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -755,6 +755,8 @@ heap_create_with_catalog(const char *relname,
* make a dependency link to force the relation to be deleted if its * 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 * namespace is. Skip this in bootstrap mode, since we don't make
* dependencies while bootstrapping. * dependencies while bootstrapping.
*
* Also make a dependency link to its owner.
*/ */
if (!IsBootstrapProcessingMode()) if (!IsBootstrapProcessingMode())
{ {
@ -768,6 +770,8 @@ heap_create_with_catalog(const char *relname,
referenced.objectId = relnamespace; referenced.objectId = relnamespace;
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(RelationRelationId, new_rel_oid, GetUserId());
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.24 2005/06/28 05:08:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.25 2005/07/07 20:39:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -120,6 +120,10 @@ ConversionCreate(const char *conname, Oid connamespace,
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* create dependency on owner */
recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup),
conowner);
heap_freetuple(tup); heap_freetuple(tup);
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);

View File

@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.14 2005/06/28 05:08:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.15 2005/07/07 20:39:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "utils/builtins.h" #include "utils/builtins.h"
@ -72,5 +73,8 @@ NamespaceCreate(const char *nspName, Oid ownerId)
heap_close(nspdesc, RowExclusiveLock); heap_close(nspdesc, RowExclusiveLock);
/* Record dependency on owner */
recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
return nspoid; return nspoid;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.92 2005/06/28 05:08:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.93 2005/07/07 20:39:57 tgl Exp $
* *
* NOTES * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
@ -889,6 +889,7 @@ makeOperatorDependencies(HeapTuple tuple)
/* In case we are updating a shell, delete any existing entries */ /* In case we are updating a shell, delete any existing entries */
deleteDependencyRecordsFor(myself.classId, myself.objectId); deleteDependencyRecordsFor(myself.classId, myself.objectId);
deleteSharedDependencyRecordsFor(myself.classId, myself.objectId);
/* Dependency on namespace */ /* Dependency on namespace */
if (OidIsValid(oper->oprnamespace)) if (OidIsValid(oper->oprnamespace))
@ -962,4 +963,8 @@ makeOperatorDependencies(HeapTuple tuple)
referenced.objectSubId = 0; referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
/* Dependency on owner */
recordDependencyOnOwner(OperatorRelationId, HeapTupleGetOid(tuple),
oper->oprowner);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.131 2005/06/28 19:51:21 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.132 2005/07/07 20:39:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -349,7 +349,10 @@ ProcedureCreate(const char *procedureName,
* existing function, first delete any existing pg_depend entries. * existing function, first delete any existing pg_depend entries.
*/ */
if (is_update) if (is_update)
{
deleteDependencyRecordsFor(ProcedureRelationId, retval); deleteDependencyRecordsFor(ProcedureRelationId, retval);
deleteSharedDependencyRecordsFor(ProcedureRelationId, retval);
}
myself.classId = ProcedureRelationId; myself.classId = ProcedureRelationId;
myself.objectId = retval; myself.objectId = retval;
@ -382,6 +385,9 @@ ProcedureCreate(const char *procedureName,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
/* dependency on owner */
recordDependencyOnOwner(ProcedureRelationId, retval, GetUserId());
heap_freetuple(tup); heap_freetuple(tup);
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.101 2005/06/28 05:08:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.102 2005/07/07 20:39:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -75,7 +75,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
namestrcpy(&name, typeName); namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* typname */ values[i++] = NameGetDatum(&name); /* typname */
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */ values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */ values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
values[i++] = Int16GetDatum(0); /* typlen */ values[i++] = Int16GetDatum(0); /* typlen */
values[i++] = BoolGetDatum(false); /* typbyval */ values[i++] = BoolGetDatum(false); /* typbyval */
values[i++] = CharGetDatum(0); /* typtype */ values[i++] = CharGetDatum(0); /* typtype */
@ -117,6 +117,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
typoid, typoid,
InvalidOid, InvalidOid,
0, 0,
GetUserId(),
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
InvalidOid, InvalidOid,
@ -330,6 +331,7 @@ TypeCreate(const char *typeName,
typeObjectId, typeObjectId,
relationOid, relationOid,
relationKind, relationKind,
GetUserId(),
inputProcedure, inputProcedure,
outputProcedure, outputProcedure,
receiveProcedure, receiveProcedure,
@ -365,6 +367,7 @@ GenerateTypeDependencies(Oid typeNamespace,
Oid relationOid, /* only for 'c'atalog Oid relationOid, /* only for 'c'atalog
* types */ * types */
char relationKind, /* ditto */ char relationKind, /* ditto */
Oid owner,
Oid inputProcedure, Oid inputProcedure,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,
@ -379,7 +382,10 @@ GenerateTypeDependencies(Oid typeNamespace,
referenced; referenced;
if (rebuild) if (rebuild)
{
deleteDependencyRecordsFor(TypeRelationId, typeObjectId); deleteDependencyRecordsFor(TypeRelationId, typeObjectId);
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId);
}
myself.classId = TypeRelationId; myself.classId = TypeRelationId;
myself.objectId = typeObjectId; myself.objectId = typeObjectId;
@ -485,6 +491,9 @@ GenerateTypeDependencies(Oid typeNamespace,
/* Normal dependency on the default expression. */ /* Normal dependency on the default expression. */
if (defaultExpr) if (defaultExpr)
recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL); recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
/* Shared dependency on owner. */
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.19 2005/06/28 05:08:53 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.20 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -17,6 +17,7 @@
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
@ -220,6 +221,10 @@ AlterConversionOwner(List *name, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(ConversionRelationId, conversionOid,
newOwnerId);
} }
heap_close(rel, NoLock); heap_close(rel, NoLock);

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.164 2005/06/30 00:00:50 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.165 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,6 +28,7 @@
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_authid.h" #include "catalog/pg_authid.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
@ -511,6 +512,12 @@ createdb(const CreatedbStmt *stmt)
/* Update indexes */ /* Update indexes */
CatalogUpdateIndexes(pg_database_rel, tuple); CatalogUpdateIndexes(pg_database_rel, tuple);
/* Register owner dependency */
recordDependencyOnOwner(DatabaseRelationId, dboid, datdba);
/* Create pg_shdepend entries for objects within database */
copyTemplateDependencies(src_dboid, dboid);
/* Close pg_database, but keep exclusive lock till commit */ /* Close pg_database, but keep exclusive lock till commit */
heap_close(pg_database_rel, NoLock); heap_close(pg_database_rel, NoLock);
@ -679,6 +686,11 @@ dropdb(const char *dbname)
/* Close pg_database, but keep exclusive lock till commit */ /* Close pg_database, but keep exclusive lock till commit */
heap_close(pgdbrel, NoLock); heap_close(pgdbrel, NoLock);
/*
* Remove shared dependency references for the database.
*/
dropDatabaseDependencies(db_id);
/* /*
* Set flag to update flat database file at commit. * Set flag to update flat database file at commit.
*/ */
@ -951,6 +963,10 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple); CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple); heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(DatabaseRelationId, HeapTupleGetOid(tuple),
newOwnerId);
} }
systable_endscan(scan); systable_endscan(scan);

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:53 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.63 2005/07/07 20:39:58 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
@ -925,6 +925,9 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple); CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple); heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(ProcedureRelationId, procOid, newOwnerId);
} }
ReleaseSysCache(tup); ReleaseSysCache(tup);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:53 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.34 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -392,6 +392,9 @@ DefineOpClass(CreateOpClassStmt *stmt)
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
} }
/* dependency on owner */
recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId());
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);
} }
@ -962,6 +965,9 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(OperatorClassRelationId, amOid, newOwnerId);
} }
heap_close(rel, NoLock); heap_close(rel, NoLock);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.23 2005/07/07 20:39:58 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -310,6 +310,9 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(OperatorRelationId, operOid, newOwnerId);
} }
heap_close(rel, NoLock); heap_close(rel, NoLock);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.31 2005/06/28 05:08:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.32 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -342,6 +342,10 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple); CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple); heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(NamespaceRelationId, HeapTupleGetOid(tup),
newOwnerId);
} }
ReleaseSysCache(tup); ReleaseSysCache(tup);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.162 2005/06/28 05:08:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.163 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -5321,6 +5321,9 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId)
heap_freetuple(newtuple); heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(RelationRelationId, relationOid, newOwnerId);
/* /*
* If we are operating on a table, also change the ownership of * If we are operating on a table, also change the ownership of
* any indexes and sequences that belong to the table, as well as * any indexes and sequences that belong to the table, as well as

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.24 2005/07/04 04:51:46 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.25 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -50,6 +50,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
@ -307,6 +308,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
heap_freetuple(tuple); heap_freetuple(tuple);
/* Record dependency on owner */
recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId);
/* /*
* Attempt to coerce target directory to safe permissions. If this * Attempt to coerce target directory to safe permissions. If this
* fails, it doesn't exist or has the wrong owner. * fails, it doesn't exist or has the wrong owner.
@ -818,6 +822,10 @@ AlterTableSpaceOwner(const char *name, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple); CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple); heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup),
newOwnerId);
} }
heap_endscan(scandesc); heap_endscan(scandesc);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.73 2005/06/28 05:08:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.74 2005/07/07 20:39:58 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -1208,6 +1208,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
domainoid, domainoid,
typTup->typrelid, typTup->typrelid,
0, /* relation kind is n/a */ 0, /* relation kind is n/a */
typTup->typowner,
typTup->typinput, typTup->typinput,
typTup->typoutput, typTup->typoutput,
typTup->typreceive, typTup->typreceive,
@ -2080,6 +2081,9 @@ AlterTypeOwner(List *names, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
} }
/* Clean up */ /* Clean up */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.155 2005/06/29 20:34:13 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.156 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -14,10 +14,10 @@
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_auth_members.h" #include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h" #include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
#include "commands/user.h" #include "commands/user.h"
#include "libpq/crypt.h" #include "libpq/crypt.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -742,10 +742,8 @@ DropRole(DropRoleStmt *stmt)
const char *role = strVal(lfirst(item)); const char *role = strVal(lfirst(item));
HeapTuple tuple, HeapTuple tuple,
tmp_tuple; tmp_tuple;
Relation pg_rel; ScanKeyData scankey;
TupleDesc pg_dsc; char *detail;
ScanKeyData scankey;
HeapScanDesc scan;
SysScanDesc sscan; SysScanDesc sscan;
Oid roleid; Oid roleid;
@ -780,42 +778,18 @@ DropRole(DropRoleStmt *stmt)
errmsg("must be superuser to drop superusers"))); errmsg("must be superuser to drop superusers")));
/* /*
* Check if role still owns a database. If so, error out. * Lock the role, so nobody can add dependencies to her while we drop
* * her. We keep the lock until the end of transaction.
* (It used to be that this function would drop the database */
* automatically. This is not only very dangerous for people that LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);
* don't read the manual, it doesn't seem to be the behaviour one
* would expect either.) -- petere 2000/01/14)
*/
pg_rel = heap_open(DatabaseRelationId, AccessShareLock);
pg_dsc = RelationGetDescr(pg_rel);
ScanKeyInit(&scankey, /* Check for pg_shdepend entries depending on this role */
Anum_pg_database_datdba, if ((detail = checkSharedDependencies(AuthIdRelationId, roleid)) != NULL)
BTEqualStrategyNumber, F_OIDEQ,
roleid);
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, ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE), (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
errmsg("role \"%s\" cannot be dropped", role), errmsg("role \"%s\" cannot be dropped because some objects depend on it",
errdetail("The role owns database \"%s\".", dbname))); role),
} errdetail("%s", detail)));
heap_endscan(scan);
heap_close(pg_rel, AccessShareLock);
/*
* Somehow we'd have to check for tables, views, etc. owned by the
* role as well, but those could be spread out over all sorts of
* databases which we don't have access to (easily).
*/
/* /*
* Remove the role from the pg_authid table * Remove the role from the pg_authid table

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.117 2005/06/29 20:34:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.118 2005/07/07 20:39:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -59,6 +59,7 @@ static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
Oid ownerId); Oid ownerId);
static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
Oid ownerId, DropBehavior behavior); Oid ownerId, DropBehavior behavior);
static int oidComparator(const void *arg1, const void *arg2);
static AclMode convert_priv_string(text *priv_type_text); static AclMode convert_priv_string(text *priv_type_text);
@ -1052,6 +1053,86 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
} }
/*
* aclmembers
* Find out all the roleids mentioned in an Acl.
* Note that we do not distinguish grantors from grantees.
*
* *roleids is set to point to a palloc'd array containing distinct OIDs
* in sorted order. The length of the array is the function result.
*/
int
aclmembers(const Acl *acl, Oid **roleids)
{
Oid *list;
const AclItem *acldat;
int i,
j,
k;
if (acl == NULL || ACL_NUM(acl) == 0)
{
*roleids = NULL;
return 0;
}
/* Allocate the worst-case space requirement */
list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
acldat = ACL_DAT(acl);
/*
* Walk the ACL collecting mentioned RoleIds.
*/
j = 0;
for (i = 0; i < ACL_NUM(acl); i++)
{
const AclItem *ai = &acldat[i];
if (ai->ai_grantee != ACL_ID_PUBLIC)
list[j++] = ai->ai_grantee;
/* grantor is currently never PUBLIC, but let's check anyway */
if (ai->ai_grantor != ACL_ID_PUBLIC)
list[j++] = ai->ai_grantor;
}
/* Sort the array */
qsort(list, j, sizeof(Oid), oidComparator);
/* Remove duplicates from the array */
k = 0;
for (i = 1; i < j; i++)
{
if (list[k] != list[i])
list[++k] = list[i];
}
/*
* We could repalloc the array down to minimum size, but it's hardly
* worth it since it's only transient memory.
*/
*roleids = list;
return k + 1;
}
/*
* oidComparator
* qsort comparison function for Oids
*/
static int
oidComparator(const void *arg1, const void *arg2)
{
Oid oid1 = * (const Oid *) arg1;
Oid oid2 = * (const Oid *) arg2;
if (oid1 > oid2)
return 1;
if (oid1 < oid2)
return -1;
return 0;
}
/* /*
* aclinsert (exported function) * aclinsert (exported function)
*/ */

View File

@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD. * Portions taken from FreeBSD.
* *
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.90 2005/07/02 17:01:50 momjian Exp $ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.91 2005/07/07 20:39:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1512,6 +1512,10 @@ setup_depend(void)
* must be the only entries for their objects. * must be the only entries for their objects.
*/ */
"DELETE FROM pg_depend;\n", "DELETE FROM pg_depend;\n",
"VACUUM pg_depend;\n",
"DELETE FROM pg_shdepend;\n",
"VACUUM pg_shdepend;\n",
"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
" FROM pg_class;\n", " FROM pg_class;\n",
"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
@ -1541,10 +1545,13 @@ setup_depend(void)
"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
" FROM pg_namespace " " FROM pg_namespace "
" WHERE nspname LIKE 'pg%';\n", " WHERE nspname LIKE 'pg%';\n",
"INSERT INTO pg_shdepend SELECT 0, 0, 0, tableoid, oid, 'p' "
" FROM pg_authid;\n",
NULL NULL
}; };
fputs(_("initializing pg_depend ... "), stdout); fputs(_("initializing dependencies ... "), stdout);
fflush(stdout); fflush(stdout);
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.284 2005/07/01 19:19:02 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.285 2005/07/07 20:39:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200507011 #define CATALOG_VERSION_NO 200507071
#endif #endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.14 2004/12/31 22:03:24 pgsql Exp $ * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.15 2005/07/07 20:39:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -67,6 +67,40 @@ typedef enum DependencyType
DEPENDENCY_PIN = 'p' DEPENDENCY_PIN = 'p'
} DependencyType; } DependencyType;
/*
* There is also a SharedDependencyType enum type that determines the exact
* semantics of an entry in pg_shdepend. Just like regular dependency entries,
* any pg_shdepend entry means that the referenced object cannot be dropped
* unless the dependent object is dropped at the same time. There are some
* additional rules however:
*
* (a) For a SHARED_DEPENDENCY_PIN entry, there is no dependent object --
* rather, the referenced object is an essential part of the system. This
* applies to the initdb-created superuser. Entries of this type are only
* created by initdb; objects in this category don't need further pg_shdepend
* entries if more objects come to depend on them.
*
* (b) a SHARED_DEPENDENCY_OWNER entry means that the referenced object is
* the role owning the dependent object. The referenced object must be
* a pg_authid entry.
*
* (c) a SHARED_DEPENDENCY_ACL entry means that the referenced object is
* a role mentioned in the ACL field of the dependent object. The referenced
* object must be a pg_authid entry. (SHARED_DEPENDENCY_ACL entries are not
* created for the owner of an object; hence two objects may be linked by
* one or the other, but not both, of these dependency types.)
*
* SHARED_DEPENDENCY_INVALID is a value used as a parameter in internal
* routines, and is not valid in the catalog itself.
*/
typedef enum SharedDependencyType
{
SHARED_DEPENDENCY_PIN = 'p',
SHARED_DEPENDENCY_OWNER = 'o',
SHARED_DEPENDENCY_ACL = 'a',
SHARED_DEPENDENCY_INVALID = 0
} SharedDependencyType;
/* /*
* The two objects related by a dependency are identified by ObjectAddresses. * The two objects related by a dependency are identified by ObjectAddresses.
@ -81,7 +115,8 @@ typedef struct ObjectAddress
/* /*
* This enum covers all system catalogs whose OIDs can appear in classId. * This enum covers all system catalogs whose OIDs can appear in
* pg_depend.classId or pg_shdepend.classId.
*/ */
typedef enum ObjectClass typedef enum ObjectClass
{ {
@ -98,6 +133,9 @@ typedef enum ObjectClass
OCLASS_REWRITE, /* pg_rewrite */ OCLASS_REWRITE, /* pg_rewrite */
OCLASS_TRIGGER, /* pg_trigger */ OCLASS_TRIGGER, /* pg_trigger */
OCLASS_SCHEMA, /* pg_namespace */ OCLASS_SCHEMA, /* pg_namespace */
OCLASS_ROLE, /* pg_authid */
OCLASS_DATABASE, /* pg_database */
OCLASS_TBLSPACE, /* pg_tablespace */
MAX_OCLASS /* MUST BE LAST */ MAX_OCLASS /* MUST BE LAST */
} ObjectClass; } ObjectClass;
@ -136,4 +174,28 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
extern long deleteDependencyRecordsFor(Oid classId, Oid objectId); extern long deleteDependencyRecordsFor(Oid classId, Oid objectId);
/* in pg_shdepend.c */
extern void recordSharedDependencyOn(ObjectAddress *depender,
ObjectAddress *referenced,
SharedDependencyType deptype);
extern void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId);
extern void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner);
extern void changeDependencyOnOwner(Oid classId, Oid objectId,
Oid newOwnerId);
extern void updateAclDependencies(Oid classId, Oid objectId,
Oid ownerId, bool isGrant,
int noldmembers, Oid *oldmembers,
int nnewmembers, Oid *newmembers);
extern char *checkSharedDependencies(Oid classId, Oid objectId);
extern void copyTemplateDependencies(Oid templateDbId, Oid newDbId);
extern void dropDatabaseDependencies(Oid databaseId);
#endif /* DEPENDENCY_H */ #endif /* DEPENDENCY_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.88 2005/06/28 05:09:04 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.89 2005/07/07 20:39:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -179,6 +179,13 @@ DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index,2692, on pg_rewrite using btree(oid oi
DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index,2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops)); DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index,2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
#define RewriteRelRulenameIndexId 2693 #define RewriteRelRulenameIndexId 2693
/* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_shdepend_depender_index,1232, on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops));
#define SharedDependDependerIndexId 1232
/* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_shdepend_reference_index,1233, on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops));
#define SharedDependReferenceIndexId 1233
DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index,2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index,2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
#define StatisticRelidAttnumIndexId 2696 #define StatisticRelidAttnumIndexId 2696

View File

@ -0,0 +1,91 @@
/*-------------------------------------------------------------------------
*
* pg_shdepend.h
* definition of the system "shared dependency" relation (pg_shdepend)
* along with the relation's initial contents.
*
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_shdepend.h,v 1.1 2005/07/07 20:39:59 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
* information from the DATA() statements.
*
*-------------------------------------------------------------------------
*/
#ifndef PG_SHDEPEND_H
#define PG_SHDEPEND_H
/* ----------------
* postgres.h contains the system type definitions and the
* CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
* can be read by both genbki.sh and the C compiler.
* ----------------
*/
/* ----------------
* pg_shdepend definition. cpp turns this into
* typedef struct FormData_pg_shdepend
* ----------------
*/
#define SharedDependRelationId 1214
CATALOG(pg_shdepend,1214) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
{
/*
* Identification of the dependent (referencing) object.
*
* These fields are all zeroes for a DEPENDENCY_PIN entry. Also,
* dbid can be zero to denote a shared object.
*/
Oid dbid; /* OID of database containing object */
Oid classid; /* OID of table containing object */
Oid objid; /* OID of object itself */
/*
* Identification of the independent (referenced) object. This is
* always a shared object, so we need no database ID field.
*/
Oid refclassid; /* OID of table containing object */
Oid refobjid; /* OID of object itself */
/*
* Precise semantics of the relationship are specified by the deptype
* field. See SharedDependencyType in catalog/dependency.h.
*/
char deptype; /* see codes in dependency.h */
} FormData_pg_shdepend;
/* ----------------
* Form_pg_shdepend corresponds to a pointer to a row with
* the format of pg_shdepend relation.
* ----------------
*/
typedef FormData_pg_shdepend *Form_pg_shdepend;
/* ----------------
* compiler constants for pg_shdepend
* ----------------
*/
#define Natts_pg_shdepend 6
#define Anum_pg_shdepend_dbid 1
#define Anum_pg_shdepend_classid 2
#define Anum_pg_shdepend_objid 3
#define Anum_pg_shdepend_refclassid 4
#define Anum_pg_shdepend_refobjid 5
#define Anum_pg_shdepend_deptype 6
/*
* pg_shdepend has no preloaded contents; system-defined dependencies are
* loaded into it during a late stage of the initdb process.
*
* NOTE: we do not represent all possible dependency pairs in pg_shdepend;
* for example, there's not much value in creating an explicit dependency
* from a relation to its database. Currently, only dependencies on roles
* are explicitly stored in pg_shdepend.
*/
#endif /* PG_SHDEPEND_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.162 2005/06/28 05:09:12 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.163 2005/07/07 20:39:59 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -582,6 +582,7 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId, Oid typeObjectId,
Oid relationOid, Oid relationOid,
char relationKind, char relationKind,
Oid owner,
Oid inputProcedure, Oid inputProcedure,
Oid outputProcedure, Oid outputProcedure,
Oid receiveProcedure, Oid receiveProcedure,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.80 2005/06/29 20:34:15 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.81 2005/07/07 20:40:00 tgl Exp $
* *
* NOTES * NOTES
* An ACL array is simply an array of AclItems, representing the union * An ACL array is simply an array of AclItems, representing the union
@ -208,6 +208,7 @@ extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
extern int aclmembers(const Acl *acl, Oid **roleids);
extern bool is_member_of_role(Oid member, Oid role); extern bool is_member_of_role(Oid member, Oid role);
extern bool is_admin_of_role(Oid member, Oid role); extern bool is_admin_of_role(Oid member, Oid role);

View File

@ -385,5 +385,6 @@ SELECT * FROM clstr_1;
-- clean up -- clean up
\c - \c -
DROP TABLE clstr_1; DROP TABLE clstr_1;
DROP TABLE clstr_2;
DROP TABLE clstr_3; DROP TABLE clstr_3;
DROP USER clstr_user; DROP USER clstr_user;

View File

@ -0,0 +1,39 @@
--
-- DEPENDENCIES
--
CREATE USER regression_user;
CREATE USER regression_user2;
CREATE USER regression_user3;
CREATE GROUP regression_group;
CREATE TABLE deptest ();
GRANT SELECT ON TABLE deptest TO GROUP regression_group;
GRANT ALL ON TABLE deptest TO regression_user, regression_user2;
-- can't drop neither because they have privileges somewhere
DROP USER regression_user;
ERROR: role "regression_user" cannot be dropped because some objects depend on it
DETAIL: access to table deptest
DROP GROUP regression_group;
ERROR: role "regression_group" cannot be dropped because some objects depend on it
DETAIL: access to table deptest
-- if we revoke the privileges we can drop the group
REVOKE SELECT ON deptest FROM GROUP regression_group;
DROP GROUP regression_group;
-- can't drop the user if we revoke the privileges partially
REVOKE SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES ON deptest FROM regression_user;
DROP USER regression_user;
ERROR: role "regression_user" cannot be dropped because some objects depend on it
DETAIL: access to table deptest
-- now we are OK to drop him
REVOKE TRIGGER ON deptest FROM regression_user;
DROP USER regression_user;
-- we are OK too if we drop the privileges all at once
REVOKE ALL ON deptest FROM regression_user2;
DROP USER regression_user2;
-- can't drop the owner of an object
ALTER TABLE deptest OWNER TO regression_user3;
DROP USER regression_user3;
ERROR: role "regression_user3" cannot be dropped because some objects depend on it
DETAIL: owner of table deptest
-- if we drop the object, we can drop the user too
DROP TABLE deptest;
DROP USER regression_user3;

View File

@ -601,6 +601,7 @@ DROP TABLE atest3;
DROP TABLE atest4; DROP TABLE atest4;
DROP GROUP regressgroup1; DROP GROUP regressgroup1;
DROP GROUP regressgroup2; DROP GROUP regressgroup2;
REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
DROP USER regressuser1; DROP USER regressuser1;
DROP USER regressuser2; DROP USER regressuser2;
DROP USER regressuser3; DROP USER regressuser3;

View File

@ -56,6 +56,7 @@ SELECT relname, relhasindex
pg_operator | t pg_operator | t
pg_proc | t pg_proc | t
pg_rewrite | t pg_rewrite | t
pg_shdepend | t
pg_statistic | t pg_statistic | t
pg_tablespace | t pg_tablespace | t
pg_trigger | t pg_trigger | t
@ -65,7 +66,7 @@ SELECT relname, relhasindex
shighway | t shighway | t
tenk1 | t tenk1 | t
tenk2 | t tenk2 | t
(55 rows) (56 rows)
-- --
-- another sanity check: every system catalog that has OIDs should have -- another sanity check: every system catalog that has OIDs should have

View File

@ -68,7 +68,7 @@ test: misc
# ---------- # ----------
# The fifth group of parallel test # The fifth group of parallel test
# ---------- # ----------
test: select_views portals_p2 rules foreign_key cluster test: select_views portals_p2 rules foreign_key cluster dependency
# ---------- # ----------
# The sixth group of parallel test # The sixth group of parallel test

View File

@ -1,4 +1,4 @@
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.27 2005/06/17 22:32:50 tgl Exp $ # $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.28 2005/07/07 20:40:01 tgl Exp $
# This should probably be in an order similar to parallel_schedule. # This should probably be in an order similar to parallel_schedule.
test: boolean test: boolean
test: char test: char
@ -98,3 +98,4 @@ test: polymorphism
test: rowtypes test: rowtypes
test: stats test: stats
test: tablespace test: tablespace
test: dependency

View File

@ -156,5 +156,6 @@ SELECT * FROM clstr_1;
-- clean up -- clean up
\c - \c -
DROP TABLE clstr_1; DROP TABLE clstr_1;
DROP TABLE clstr_2;
DROP TABLE clstr_3; DROP TABLE clstr_3;
DROP USER clstr_user; DROP USER clstr_user;

View File

@ -0,0 +1,41 @@
--
-- DEPENDENCIES
--
CREATE USER regression_user;
CREATE USER regression_user2;
CREATE USER regression_user3;
CREATE GROUP regression_group;
CREATE TABLE deptest ();
GRANT SELECT ON TABLE deptest TO GROUP regression_group;
GRANT ALL ON TABLE deptest TO regression_user, regression_user2;
-- can't drop neither because they have privileges somewhere
DROP USER regression_user;
DROP GROUP regression_group;
-- if we revoke the privileges we can drop the group
REVOKE SELECT ON deptest FROM GROUP regression_group;
DROP GROUP regression_group;
-- can't drop the user if we revoke the privileges partially
REVOKE SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES ON deptest FROM regression_user;
DROP USER regression_user;
-- now we are OK to drop him
REVOKE TRIGGER ON deptest FROM regression_user;
DROP USER regression_user;
-- we are OK too if we drop the privileges all at once
REVOKE ALL ON deptest FROM regression_user2;
DROP USER regression_user2;
-- can't drop the owner of an object
ALTER TABLE deptest OWNER TO regression_user3;
DROP USER regression_user3;
-- if we drop the object, we can drop the user too
DROP TABLE deptest;
DROP USER regression_user3;

View File

@ -339,6 +339,7 @@ DROP TABLE atest4;
DROP GROUP regressgroup1; DROP GROUP regressgroup1;
DROP GROUP regressgroup2; DROP GROUP regressgroup2;
REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
DROP USER regressuser1; DROP USER regressuser1;
DROP USER regressuser2; DROP USER regressuser2;
DROP USER regressuser3; DROP USER regressuser3;