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
|
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>
|
||||||
|
@ -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 \
|
||||||
)
|
)
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
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
|
* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
*/
|
*/
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
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) 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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
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 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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
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 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;
|
||||||
|
Loading…
Reference in New Issue
Block a user