mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
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:
parent
442b59dd8b
commit
59d1b3d99e
@ -1,6 +1,6 @@
|
||||
<!--
|
||||
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">
|
||||
@ -173,6 +173,11 @@
|
||||
<entry>query rewrite rules</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-shdepend"><structname>pg_shdepend</structname></link></entry>
|
||||
<entry>dependencies on shared objects</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
|
||||
<entry>planner statistics</entry>
|
||||
@ -1890,6 +1895,12 @@
|
||||
RESTRICT</> case.
|
||||
</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>
|
||||
<title><structname>pg_depend</> Columns</title>
|
||||
|
||||
@ -3024,7 +3035,7 @@
|
||||
|
||||
<row>
|
||||
<entry><structfield>proargmodes</structfield></entry>
|
||||
<entry><type>"char"[]</type></entry>
|
||||
<entry><type>char[]</type></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
An array with the modes of the function arguments, encoded as
|
||||
@ -3198,6 +3209,149 @@
|
||||
</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">
|
||||
<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>
|
||||
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
|
||||
</entry>
|
||||
</row>
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# 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 \
|
||||
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
|
||||
|
||||
@ -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_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_namespace.h pg_conversion.h pg_database.h pg_shdepend.h \
|
||||
pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \
|
||||
indexing.h \
|
||||
)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* See acl.h.
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_auth_members.h"
|
||||
@ -252,6 +253,10 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_class];
|
||||
char nulls[Natts_pg_class];
|
||||
char replaces[Natts_pg_class];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
/* open pg_class */
|
||||
relation = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
@ -344,11 +349,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -359,13 +372,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
|
||||
|
||||
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||
|
||||
/* keep the catalog indexes up to date */
|
||||
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);
|
||||
|
||||
heap_close(relation, RowExclusiveLock);
|
||||
@ -422,6 +441,10 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_database];
|
||||
char nulls[Natts_pg_database];
|
||||
char replaces[Natts_pg_database];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
relation = heap_open(DatabaseRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&entry[0],
|
||||
@ -503,11 +526,19 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -523,6 +554,12 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
||||
/* keep the catalog indexes up to date */
|
||||
CatalogUpdateIndexes(relation, newtuple);
|
||||
|
||||
/* Update the shared dependency ACL info */
|
||||
updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple),
|
||||
ownerId, stmt->is_grant,
|
||||
noldmembers, oldmembers,
|
||||
nnewmembers, newmembers);
|
||||
|
||||
pfree(new_acl);
|
||||
|
||||
heap_endscan(scan);
|
||||
@ -580,6 +617,10 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_proc];
|
||||
char nulls[Natts_pg_proc];
|
||||
char replaces[Natts_pg_proc];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
oid = LookupFuncNameTypeNames(func->funcname, func->funcargs, false);
|
||||
|
||||
@ -658,11 +699,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -673,13 +722,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||
|
||||
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||
|
||||
/* keep the catalog indexes up to date */
|
||||
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);
|
||||
|
||||
heap_close(relation, RowExclusiveLock);
|
||||
@ -734,6 +789,10 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_language];
|
||||
char nulls[Natts_pg_language];
|
||||
char replaces[Natts_pg_language];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
relation = heap_open(LanguageRelationId, RowExclusiveLock);
|
||||
tuple = SearchSysCache(LANGNAME,
|
||||
@ -822,11 +881,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -837,13 +904,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
|
||||
|
||||
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||
|
||||
/* keep the catalog indexes up to date */
|
||||
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);
|
||||
|
||||
heap_close(relation, RowExclusiveLock);
|
||||
@ -898,6 +971,10 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_namespace];
|
||||
char nulls[Natts_pg_namespace];
|
||||
char replaces[Natts_pg_namespace];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
relation = heap_open(NamespaceRelationId, RowExclusiveLock);
|
||||
tuple = SearchSysCache(NAMESPACENAME,
|
||||
@ -977,11 +1054,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -992,13 +1077,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
|
||||
|
||||
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
simple_heap_update(relation, &newtuple->t_self, newtuple);
|
||||
|
||||
/* keep the catalog indexes up to date */
|
||||
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);
|
||||
|
||||
heap_close(relation, RowExclusiveLock);
|
||||
@ -1055,6 +1146,10 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
|
||||
Datum values[Natts_pg_tablespace];
|
||||
char nulls[Natts_pg_tablespace];
|
||||
char replaces[Natts_pg_tablespace];
|
||||
int noldmembers;
|
||||
int nnewmembers;
|
||||
Oid *oldmembers;
|
||||
Oid *newmembers;
|
||||
|
||||
relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&entry[0],
|
||||
@ -1136,11 +1231,19 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
|
||||
/* get a detoasted copy of the ACL */
|
||||
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,
|
||||
stmt->grant_option, stmt->behavior,
|
||||
stmt->grantees, this_privileges,
|
||||
grantorId, ownerId);
|
||||
|
||||
nnewmembers = aclmembers(new_acl, &newmembers);
|
||||
|
||||
/* finished building new ACL value, now insert it */
|
||||
MemSet(values, 0, sizeof(values));
|
||||
MemSet(nulls, ' ', sizeof(nulls));
|
||||
@ -1156,6 +1259,12 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
|
||||
/* keep the catalog indexes up to date */
|
||||
CatalogUpdateIndexes(relation, newtuple);
|
||||
|
||||
/* Update the shared dependency ACL info */
|
||||
updateAclDependencies(TableSpaceRelationId, HeapTupleGetOid(tuple),
|
||||
ownerId, stmt->is_grant,
|
||||
noldmembers, oldmembers,
|
||||
nnewmembers, newmembers);
|
||||
|
||||
pfree(new_acl);
|
||||
|
||||
heap_endscan(scan);
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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/namespace.h"
|
||||
#include "catalog/pg_attrdef.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_cast.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_depend.h"
|
||||
#include "catalog/pg_language.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
@ -32,12 +34,15 @@
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_rewrite.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "catalog/pg_trigger.h"
|
||||
#include "catalog/pg_type.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"
|
||||
@ -509,6 +514,7 @@ recursiveDeletion(const ObjectAddress *object,
|
||||
break;
|
||||
}
|
||||
|
||||
/* delete the pg_depend tuple */
|
||||
simple_heap_delete(depRel, &tup->t_self);
|
||||
}
|
||||
|
||||
@ -584,6 +590,14 @@ recursiveDeletion(const ObjectAddress *object,
|
||||
*/
|
||||
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.
|
||||
@ -1365,6 +1379,18 @@ getObjectClass(const ObjectAddress *object)
|
||||
case NamespaceRelationId:
|
||||
Assert(object->objectSubId == 0);
|
||||
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 */
|
||||
@ -1680,6 +1706,37 @@ getObjectDescription(const ObjectAddress *object)
|
||||
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:
|
||||
appendStringInfo(&buffer, "unrecognized object %u %u %d",
|
||||
object->classId,
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -755,6 +755,8 @@ heap_create_with_catalog(const char *relname,
|
||||
* 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 a dependency link to its owner.
|
||||
*/
|
||||
if (!IsBootstrapProcessingMode())
|
||||
{
|
||||
@ -768,6 +770,8 @@ heap_create_with_catalog(const char *relname,
|
||||
referenced.objectId = relnamespace;
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
|
||||
recordDependencyOnOwner(RelationRelationId, new_rel_oid, GetUserId());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
|
||||
/* create dependency on owner */
|
||||
recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup),
|
||||
conowner);
|
||||
|
||||
heap_freetuple(tup);
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
|
||||
|
@ -8,13 +8,14 @@
|
||||
*
|
||||
*
|
||||
* 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 "access/heapam.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "utils/builtins.h"
|
||||
@ -72,5 +73,8 @@ NamespaceCreate(const char *nspName, Oid ownerId)
|
||||
|
||||
heap_close(nspdesc, RowExclusiveLock);
|
||||
|
||||
/* Record dependency on owner */
|
||||
recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
|
||||
|
||||
return nspoid;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* 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 */
|
||||
deleteDependencyRecordsFor(myself.classId, myself.objectId);
|
||||
deleteSharedDependencyRecordsFor(myself.classId, myself.objectId);
|
||||
|
||||
/* Dependency on namespace */
|
||||
if (OidIsValid(oper->oprnamespace))
|
||||
@ -962,4 +963,8 @@ makeOperatorDependencies(HeapTuple tuple)
|
||||
referenced.objectSubId = 0;
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
/* Dependency on owner */
|
||||
recordDependencyOnOwner(OperatorRelationId, HeapTupleGetOid(tuple),
|
||||
oper->oprowner);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
if (is_update)
|
||||
{
|
||||
deleteDependencyRecordsFor(ProcedureRelationId, retval);
|
||||
deleteSharedDependencyRecordsFor(ProcedureRelationId, retval);
|
||||
}
|
||||
|
||||
myself.classId = ProcedureRelationId;
|
||||
myself.objectId = retval;
|
||||
@ -382,6 +385,9 @@ ProcedureCreate(const char *procedureName,
|
||||
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||
}
|
||||
|
||||
/* dependency on owner */
|
||||
recordDependencyOnOwner(ProcedureRelationId, retval, GetUserId());
|
||||
|
||||
heap_freetuple(tup);
|
||||
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
|
1042
src/backend/catalog/pg_shdepend.c
Normal file
1042
src/backend/catalog/pg_shdepend.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
values[i++] = NameGetDatum(&name); /* typname */
|
||||
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
|
||||
values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */
|
||||
values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
|
||||
values[i++] = Int16GetDatum(0); /* typlen */
|
||||
values[i++] = BoolGetDatum(false); /* typbyval */
|
||||
values[i++] = CharGetDatum(0); /* typtype */
|
||||
@ -117,6 +117,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
|
||||
typoid,
|
||||
InvalidOid,
|
||||
0,
|
||||
GetUserId(),
|
||||
InvalidOid,
|
||||
InvalidOid,
|
||||
InvalidOid,
|
||||
@ -330,6 +331,7 @@ TypeCreate(const char *typeName,
|
||||
typeObjectId,
|
||||
relationOid,
|
||||
relationKind,
|
||||
GetUserId(),
|
||||
inputProcedure,
|
||||
outputProcedure,
|
||||
receiveProcedure,
|
||||
@ -365,6 +367,7 @@ GenerateTypeDependencies(Oid typeNamespace,
|
||||
Oid relationOid, /* only for 'c'atalog
|
||||
* types */
|
||||
char relationKind, /* ditto */
|
||||
Oid owner,
|
||||
Oid inputProcedure,
|
||||
Oid outputProcedure,
|
||||
Oid receiveProcedure,
|
||||
@ -379,7 +382,10 @@ GenerateTypeDependencies(Oid typeNamespace,
|
||||
referenced;
|
||||
|
||||
if (rebuild)
|
||||
{
|
||||
deleteDependencyRecordsFor(TypeRelationId, typeObjectId);
|
||||
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId);
|
||||
}
|
||||
|
||||
myself.classId = TypeRelationId;
|
||||
myself.objectId = typeObjectId;
|
||||
@ -485,6 +491,9 @@ GenerateTypeDependencies(Oid typeNamespace,
|
||||
/* Normal dependency on the default expression. */
|
||||
if (defaultExpr)
|
||||
recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
|
||||
|
||||
/* Shared dependency on owner. */
|
||||
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 "access/heapam.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_type.h"
|
||||
@ -220,6 +221,10 @@ AlterConversionOwner(List *name, Oid newOwnerId)
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(ConversionRelationId, conversionOid,
|
||||
newOwnerId);
|
||||
}
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* 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/heapam.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_database.h"
|
||||
@ -511,6 +512,12 @@ createdb(const CreatedbStmt *stmt)
|
||||
/* Update indexes */
|
||||
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 */
|
||||
heap_close(pg_database_rel, NoLock);
|
||||
|
||||
@ -679,6 +686,11 @@ dropdb(const char *dbname)
|
||||
/* Close pg_database, but keep exclusive lock till commit */
|
||||
heap_close(pgdbrel, NoLock);
|
||||
|
||||
/*
|
||||
* Remove shared dependency references for the database.
|
||||
*/
|
||||
dropDatabaseDependencies(db_id);
|
||||
|
||||
/*
|
||||
* Set flag to update flat database file at commit.
|
||||
*/
|
||||
@ -951,6 +963,10 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
|
||||
CatalogUpdateIndexes(rel, newtuple);
|
||||
|
||||
heap_freetuple(newtuple);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(DatabaseRelationId, HeapTupleGetOid(tuple),
|
||||
newOwnerId);
|
||||
}
|
||||
|
||||
systable_endscan(scan);
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* These routines take the parse tree and pick out the
|
||||
@ -925,6 +925,9 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
|
||||
CatalogUpdateIndexes(rel, newtuple);
|
||||
|
||||
heap_freetuple(newtuple);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(ProcedureRelationId, procOid, newOwnerId);
|
||||
}
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* dependency on owner */
|
||||
recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId());
|
||||
|
||||
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);
|
||||
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(OperatorClassRelationId, amOid, newOwnerId);
|
||||
}
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* 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);
|
||||
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(OperatorRelationId, operOid, newOwnerId);
|
||||
}
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
|
||||
heap_freetuple(newtuple);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(NamespaceRelationId, HeapTupleGetOid(tup),
|
||||
newOwnerId);
|
||||
}
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(RelationRelationId, relationOid, newOwnerId);
|
||||
|
||||
/*
|
||||
* If we are operating on a table, also change the ownership of
|
||||
* any indexes and sequences that belong to the table, as well as
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* 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 "catalog/catalog.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
@ -307,6 +308,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
|
||||
|
||||
heap_freetuple(tuple);
|
||||
|
||||
/* Record dependency on owner */
|
||||
recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId);
|
||||
|
||||
/*
|
||||
* Attempt to coerce target directory to safe permissions. If this
|
||||
* fails, it doesn't exist or has the wrong owner.
|
||||
@ -818,6 +822,10 @@ AlterTableSpaceOwner(const char *name, Oid newOwnerId)
|
||||
CatalogUpdateIndexes(rel, newtuple);
|
||||
|
||||
heap_freetuple(newtuple);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup),
|
||||
newOwnerId);
|
||||
}
|
||||
|
||||
heap_endscan(scandesc);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -1208,6 +1208,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
|
||||
domainoid,
|
||||
typTup->typrelid,
|
||||
0, /* relation kind is n/a */
|
||||
typTup->typowner,
|
||||
typTup->typinput,
|
||||
typTup->typoutput,
|
||||
typTup->typreceive,
|
||||
@ -2080,6 +2081,9 @@ AlterTypeOwner(List *names, Oid newOwnerId)
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
|
||||
/* Update owner dependency reference */
|
||||
changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* 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/heapam.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_auth_members.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "commands/user.h"
|
||||
#include "libpq/crypt.h"
|
||||
#include "miscadmin.h"
|
||||
@ -742,10 +742,8 @@ DropRole(DropRoleStmt *stmt)
|
||||
const char *role = strVal(lfirst(item));
|
||||
HeapTuple tuple,
|
||||
tmp_tuple;
|
||||
Relation pg_rel;
|
||||
TupleDesc pg_dsc;
|
||||
ScanKeyData scankey;
|
||||
HeapScanDesc scan;
|
||||
ScanKeyData scankey;
|
||||
char *detail;
|
||||
SysScanDesc sscan;
|
||||
Oid roleid;
|
||||
|
||||
@ -780,42 +778,18 @@ DropRole(DropRoleStmt *stmt)
|
||||
errmsg("must be superuser to drop superusers")));
|
||||
|
||||
/*
|
||||
* Check if role 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_open(DatabaseRelationId, AccessShareLock);
|
||||
pg_dsc = RelationGetDescr(pg_rel);
|
||||
* Lock the role, so nobody can add dependencies to her while we drop
|
||||
* her. We keep the lock until the end of transaction.
|
||||
*/
|
||||
LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);
|
||||
|
||||
ScanKeyInit(&scankey,
|
||||
Anum_pg_database_datdba,
|
||||
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);
|
||||
/* Check for pg_shdepend entries depending on this role */
|
||||
if ((detail = checkSharedDependencies(AuthIdRelationId, roleid)) != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_IN_USE),
|
||||
errmsg("role \"%s\" cannot be dropped", role),
|
||||
errdetail("The role 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
|
||||
* role as well, but those could be spread out over all sorts of
|
||||
* databases which we don't have access to (easily).
|
||||
*/
|
||||
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
|
||||
errmsg("role \"%s\" cannot be dropped because some objects depend on it",
|
||||
role),
|
||||
errdetail("%s", detail)));
|
||||
|
||||
/*
|
||||
* Remove the role from the pg_authid table
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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);
|
||||
static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
|
||||
Oid ownerId, DropBehavior behavior);
|
||||
static int oidComparator(const void *arg1, const void *arg2);
|
||||
|
||||
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)
|
||||
*/
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
* 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.
|
||||
*/
|
||||
"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' "
|
||||
" FROM pg_class;\n",
|
||||
"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' "
|
||||
" FROM pg_namespace "
|
||||
" WHERE nspname LIKE 'pg%';\n",
|
||||
|
||||
"INSERT INTO pg_shdepend SELECT 0, 0, 0, tableoid, oid, 'p' "
|
||||
" FROM pg_authid;\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
fputs(_("initializing pg_depend ... "), stdout);
|
||||
fputs(_("initializing dependencies ... "), stdout);
|
||||
fflush(stdout);
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* 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 */
|
||||
#define CATALOG_VERSION_NO 200507011
|
||||
#define CATALOG_VERSION_NO 200507071
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* 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'
|
||||
} 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.
|
||||
@ -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
|
||||
{
|
||||
@ -98,6 +133,9 @@ typedef enum ObjectClass
|
||||
OCLASS_REWRITE, /* pg_rewrite */
|
||||
OCLASS_TRIGGER, /* pg_trigger */
|
||||
OCLASS_SCHEMA, /* pg_namespace */
|
||||
OCLASS_ROLE, /* pg_authid */
|
||||
OCLASS_DATABASE, /* pg_database */
|
||||
OCLASS_TBLSPACE, /* pg_tablespace */
|
||||
MAX_OCLASS /* MUST BE LAST */
|
||||
} ObjectClass;
|
||||
|
||||
@ -136,4 +174,28 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
|
||||
|
||||
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 */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* 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));
|
||||
#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));
|
||||
#define StatisticRelidAttnumIndexId 2696
|
||||
|
||||
|
91
src/include/catalog/pg_shdepend.h
Normal file
91
src/include/catalog/pg_shdepend.h
Normal 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 */
|
@ -8,7 +8,7 @@
|
||||
* 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_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
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
@ -582,6 +582,7 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
|
||||
Oid typeObjectId,
|
||||
Oid relationOid,
|
||||
char relationKind,
|
||||
Oid owner,
|
||||
Oid inputProcedure,
|
||||
Oid outputProcedure,
|
||||
Oid receiveProcedure,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* 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
|
||||
* 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,
|
||||
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_admin_of_role(Oid member, Oid role);
|
||||
|
@ -385,5 +385,6 @@ SELECT * FROM clstr_1;
|
||||
-- clean up
|
||||
\c -
|
||||
DROP TABLE clstr_1;
|
||||
DROP TABLE clstr_2;
|
||||
DROP TABLE clstr_3;
|
||||
DROP USER clstr_user;
|
||||
|
39
src/test/regress/expected/dependency.out
Normal file
39
src/test/regress/expected/dependency.out
Normal 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;
|
@ -601,6 +601,7 @@ DROP TABLE atest3;
|
||||
DROP TABLE atest4;
|
||||
DROP GROUP regressgroup1;
|
||||
DROP GROUP regressgroup2;
|
||||
REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
|
||||
DROP USER regressuser1;
|
||||
DROP USER regressuser2;
|
||||
DROP USER regressuser3;
|
||||
|
@ -56,6 +56,7 @@ SELECT relname, relhasindex
|
||||
pg_operator | t
|
||||
pg_proc | t
|
||||
pg_rewrite | t
|
||||
pg_shdepend | t
|
||||
pg_statistic | t
|
||||
pg_tablespace | t
|
||||
pg_trigger | t
|
||||
@ -65,7 +66,7 @@ SELECT relname, relhasindex
|
||||
shighway | t
|
||||
tenk1 | t
|
||||
tenk2 | t
|
||||
(55 rows)
|
||||
(56 rows)
|
||||
|
||||
--
|
||||
-- another sanity check: every system catalog that has OIDs should have
|
||||
|
@ -68,7 +68,7 @@ test: misc
|
||||
# ----------
|
||||
# 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
|
||||
|
@ -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.
|
||||
test: boolean
|
||||
test: char
|
||||
@ -98,3 +98,4 @@ test: polymorphism
|
||||
test: rowtypes
|
||||
test: stats
|
||||
test: tablespace
|
||||
test: dependency
|
||||
|
@ -156,5 +156,6 @@ SELECT * FROM clstr_1;
|
||||
-- clean up
|
||||
\c -
|
||||
DROP TABLE clstr_1;
|
||||
DROP TABLE clstr_2;
|
||||
DROP TABLE clstr_3;
|
||||
DROP USER clstr_user;
|
||||
|
41
src/test/regress/sql/dependency.sql
Normal file
41
src/test/regress/sql/dependency.sql
Normal 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;
|
@ -339,6 +339,7 @@ DROP TABLE atest4;
|
||||
DROP GROUP regressgroup1;
|
||||
DROP GROUP regressgroup2;
|
||||
|
||||
REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
|
||||
DROP USER regressuser1;
|
||||
DROP USER regressuser2;
|
||||
DROP USER regressuser3;
|
||||
|
Loading…
Reference in New Issue
Block a user