Clean up some loose ends from the column privileges patch: add
has_column_privilege and has_any_column_privilege SQL functions; fix the information_schema views that are supposed to pay attention to column privileges; adjust pg_stats to show stats for any column you have select privilege on; and fix COPY to allow copying a subset of columns if the user has suitable per-column privileges for all the columns. To improve efficiency of some of the information_schema views, extend the has_xxx_privilege functions to allow inquiring about the OR of a set of privileges in just one call. This is just exposing capability that already existed in the underlying aclcheck routines. In passing, make the information_schema views report the owner's own privileges as being grantable, since Postgres assumes this even when the grant option bit is not set in the ACL. This is a longstanding oversight. Also, make the new has_xxx_privilege functions for foreign data objects follow the same coding conventions used by the older ones. Stephen Frost and Tom Lane
This commit is contained in:
parent
0274e1b949
commit
7449427a1e
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.470 2009/01/15 18:19:58 heikki Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.471 2009/02/06 21:15:11 tgl Exp $ -->
|
||||
|
||||
<chapter id="functions">
|
||||
<title>Functions and Operators</title>
|
||||
@ -11599,6 +11599,38 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal><function>has_any_column_privilege</function>(<parameter>user</parameter>,
|
||||
<parameter>table</parameter>,
|
||||
<parameter>privilege</parameter>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>does user have privilege for any column of table</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>has_any_column_privilege</function>(<parameter>table</parameter>,
|
||||
<parameter>privilege</parameter>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>does current user have privilege for any column of table</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>has_column_privilege</function>(<parameter>user</parameter>,
|
||||
<parameter>table</parameter>,
|
||||
<parameter>column</parameter>,
|
||||
<parameter>privilege</parameter>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>does user have privilege for column</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>has_column_privilege</function>(<parameter>table</parameter>,
|
||||
<parameter>column</parameter>,
|
||||
<parameter>privilege</parameter>)</literal>
|
||||
</entry>
|
||||
<entry><type>boolean</type></entry>
|
||||
<entry>does current user have privilege for column</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal><function>has_database_privilege</function>(<parameter>user</parameter>,
|
||||
<parameter>database</parameter>,
|
||||
@ -11738,6 +11770,12 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<indexterm>
|
||||
<primary>has_any_column_privilege</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>has_column_privilege</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>has_database_privilege</primary>
|
||||
</indexterm>
|
||||
@ -11766,11 +11804,71 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
|
||||
<primary>pg_has_role</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
<function>has_table_privilege</function> checks whether a user
|
||||
can access a table in a particular way. The user can be
|
||||
specified by name or by OID
|
||||
(<literal>pg_authid.oid</literal>), or if the argument is
|
||||
omitted
|
||||
<function>current_user</function> is assumed. The table can be specified
|
||||
by name or by OID. (Thus, there are actually six variants of
|
||||
<function>has_table_privilege</function>, which can be distinguished by
|
||||
the number and types of their arguments.) When specifying by name,
|
||||
the name can be schema-qualified if necessary.
|
||||
The desired access privilege type
|
||||
is specified by a text string, which must evaluate to one of the
|
||||
values <literal>SELECT</literal>, <literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, <literal>DELETE</literal>, <literal>TRUNCATE</>,
|
||||
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>. Optionally,
|
||||
<literal>WITH GRANT OPTION</> can be added to a privilege type to test
|
||||
whether the privilege is held with grant option. Also, multiple privilege
|
||||
types can be listed separated by commas, in which case the result will
|
||||
be <literal>true</> if any of the listed privileges is held.
|
||||
(Case of the privilege string is not significant, and extra whitespace
|
||||
is allowed between but not within privilege names.)
|
||||
Some examples:
|
||||
<programlisting>
|
||||
SELECT has_table_privilege('myschema.mytable', 'select');
|
||||
SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>has_any_column_privilege</function> checks whether a user can
|
||||
access any column of a table in a particular way. The possibilities for
|
||||
its arguments are the same as for <function>has_table_privilege</>,
|
||||
except that the desired access privilege type must evaluate to some
|
||||
combination of
|
||||
<literal>SELECT</literal>,
|
||||
<literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, or
|
||||
<literal>REFERENCES</literal>. Note that having any of these privileges
|
||||
at the table level implicitly grants it for each column of the table,
|
||||
so <function>has_any_column_privilege</function> will always return
|
||||
<literal>true</> if <function>has_table_privilege</> does for the same
|
||||
arguments. But <function>has_any_column_privilege</> also succeeds if
|
||||
there is a column-level grant of the privilege for at least one column.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>has_column_privilege</function> checks whether a user
|
||||
can access a column in a particular way. The possibilities for its
|
||||
arguments are analogous to <function>has_table_privilege</function>,
|
||||
with the addition that the column can be specified either by name
|
||||
or attribute number.
|
||||
The desired access privilege type must evaluate to some combination of
|
||||
<literal>SELECT</literal>,
|
||||
<literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, or
|
||||
<literal>REFERENCES</literal>. Note that having any of these privileges
|
||||
at the table level implicitly grants it for each column of the table.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>has_database_privilege</function> checks whether a user
|
||||
can access a database in a particular way. The possibilities for its
|
||||
arguments are analogous to <function>has_table_privilege</function>.
|
||||
The desired access privilege type must evaluate to
|
||||
The desired access privilege type must evaluate to some combination of
|
||||
<literal>CREATE</literal>,
|
||||
<literal>CONNECT</literal>,
|
||||
<literal>TEMPORARY</literal>, or
|
||||
@ -11813,7 +11911,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
|
||||
<function>has_schema_privilege</function> checks whether a user
|
||||
can access a schema in a particular way. The possibilities for its
|
||||
arguments are analogous to <function>has_table_privilege</function>.
|
||||
The desired access privilege type must evaluate to
|
||||
The desired access privilege type must evaluate to some combination of
|
||||
<literal>CREATE</literal> or
|
||||
<literal>USAGE</literal>.
|
||||
</para>
|
||||
@ -11826,29 +11924,6 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
|
||||
<literal>USAGE</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>has_table_privilege</function> checks whether a user
|
||||
can access a table in a particular way. The user can be
|
||||
specified by name or by OID
|
||||
(<literal>pg_authid.oid</literal>), or if the argument is
|
||||
omitted
|
||||
<function>current_user</function> is assumed. The table can be specified
|
||||
by name or by OID. (Thus, there are actually six variants of
|
||||
<function>has_table_privilege</function>, which can be distinguished by
|
||||
the number and types of their arguments.) When specifying by name,
|
||||
the name can be schema-qualified if necessary.
|
||||
The desired access privilege type
|
||||
is specified by a text string, which must evaluate to one of the
|
||||
values <literal>SELECT</literal>, <literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, <literal>DELETE</literal>, <literal>TRUNCATE</>,
|
||||
<literal>REFERENCES</literal>, or <literal>TRIGGER</literal>.
|
||||
(Case of the string is not significant, however.)
|
||||
An example is:
|
||||
<programlisting>
|
||||
SELECT has_table_privilege('myschema.mytable', 'select');
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>has_tablespace_privilege</function> checks whether a user
|
||||
can access a tablespace in a particular way. The possibilities for its
|
||||
@ -11861,7 +11936,7 @@ SELECT has_table_privilege('myschema.mytable', 'select');
|
||||
<function>pg_has_role</function> checks whether a user
|
||||
can access a role in a particular way. The possibilities for its
|
||||
arguments are analogous to <function>has_table_privilege</function>.
|
||||
The desired access privilege type must evaluate to
|
||||
The desired access privilege type must evaluate to some combination of
|
||||
<literal>MEMBER</literal> or
|
||||
<literal>USAGE</literal>.
|
||||
<literal>MEMBER</literal> denotes direct or indirect membership in
|
||||
@ -11870,12 +11945,6 @@ SELECT has_table_privilege('myschema.mytable', 'select');
|
||||
are immediately available without doing <command>SET ROLE</>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To test whether a user holds a grant option on the privilege,
|
||||
append <literal>WITH GRANT OPTION</literal> to the privilege key
|
||||
word; for example <literal>'UPDATE WITH GRANT OPTION'</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<xref linkend="functions-info-schema-table"> shows functions that
|
||||
determine whether a certain object is <firstterm>visible</> in the
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.37 2009/01/20 09:10:20 petere Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/information_schema.sgml,v 1.38 2009/02/06 21:15:11 tgl Exp $ -->
|
||||
|
||||
<chapter id="information-schema">
|
||||
<title>The Information Schema</title>
|
||||
@ -686,18 +686,11 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In <productname>PostgreSQL</productname>, you can only grant
|
||||
privileges on entire tables, not individual columns. Therefore,
|
||||
this view contains the same information as
|
||||
<literal>table_privileges</literal>, just represented through one
|
||||
row for each column in each appropriate table, but it only covers
|
||||
If a privilege has been granted on an entire table, it will show up in
|
||||
this view as a grant for each column, but only for the
|
||||
privilege types where column granularity is possible:
|
||||
<literal>SELECT</literal>, <literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, <literal>REFERENCES</literal>. If you
|
||||
want to make your applications fit for possible future
|
||||
developments, it is generally the right choice to use this view
|
||||
instead of <literal>table_privileges</literal> if one of those
|
||||
privilege types is concerned.
|
||||
<literal>UPDATE</literal>, <literal>REFERENCES</literal>.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
@ -2727,8 +2720,10 @@ ORDER BY c.ordinal_position;
|
||||
|
||||
<para>
|
||||
The view <literal>referential_constraints</literal> contains all
|
||||
referential (foreign key) constraints in the current database that
|
||||
belong to a table owned by a currently enabled role.
|
||||
referential (foreign key) constraints in the current database.
|
||||
Only those constraints are shown for which the current user has
|
||||
write access to the referencing table (by way of being the
|
||||
owner or having some privilege other than SELECT).
|
||||
</para>
|
||||
|
||||
<table>
|
||||
@ -3157,8 +3152,8 @@ ORDER BY c.ordinal_position;
|
||||
|
||||
<para>
|
||||
The view <literal>routine_privileges</literal> identifies all
|
||||
privileges granted to a currently enabled role or by a currently
|
||||
enabled role. There is one row for each combination of function,
|
||||
privileges granted on functions to a currently enabled role or by a
|
||||
currently enabled role. There is one row for each combination of function,
|
||||
grantor, and grantee.
|
||||
</para>
|
||||
|
||||
@ -4500,7 +4495,7 @@ ORDER BY c.ordinal_position;
|
||||
<para>
|
||||
The view <literal>table_constraints</literal> contains all
|
||||
constraints belonging to tables that the current user owns or has
|
||||
some privilege on.
|
||||
some non-SELECT privilege on.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
@ -4777,7 +4772,7 @@ ORDER BY c.ordinal_position;
|
||||
<para>
|
||||
The view <literal>triggers</literal> contains all triggers defined
|
||||
in the current database on tables that the current user owns or has
|
||||
some privilege on.
|
||||
some non-SELECT privilege on.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.152 2009/01/22 20:16:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.153 2009/02/06 21:15:11 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* See acl.h.
|
||||
@ -2292,22 +2292,7 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
|
||||
Oid ownerId;
|
||||
|
||||
/*
|
||||
* Must get the relation's tuple from pg_class (only needed for ownerId)
|
||||
*/
|
||||
classTuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(table_oid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(classTuple))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||
errmsg("relation with OID %u does not exist",
|
||||
table_oid)));
|
||||
classForm = (Form_pg_class) GETSTRUCT(classTuple);
|
||||
|
||||
ownerId = classForm->relowner;
|
||||
|
||||
/*
|
||||
* Next, get the column's ACL from pg_attribute
|
||||
* First, get the column's ACL from its pg_attribute entry
|
||||
*/
|
||||
attTuple = SearchSysCache(ATTNUM,
|
||||
ObjectIdGetDatum(table_oid),
|
||||
@ -2330,17 +2315,41 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
|
||||
aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
|
||||
&isNull);
|
||||
|
||||
/*
|
||||
* Here we hard-wire knowledge that the default ACL for a column
|
||||
* grants no privileges, so that we can fall out quickly in the
|
||||
* very common case where attacl is null.
|
||||
*/
|
||||
if (isNull)
|
||||
{
|
||||
/* No ACL, so build default ACL */
|
||||
acl = acldefault(ACL_OBJECT_COLUMN, ownerId);
|
||||
aclDatum = (Datum) 0;
|
||||
ReleaseSysCache(attTuple);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
||||
/*
|
||||
* Must get the relation's ownerId from pg_class. Since we already found
|
||||
* a pg_attribute entry, the only likely reason for this to fail is that
|
||||
* a concurrent DROP of the relation committed since then (which could
|
||||
* only happen if we don't have lock on the relation). We prefer to
|
||||
* report "no privileges" rather than failing in such a case, so as to
|
||||
* avoid unwanted failures in has_column_privilege() tests.
|
||||
*/
|
||||
classTuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(table_oid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(classTuple))
|
||||
{
|
||||
/* detoast column's ACL if necessary */
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
ReleaseSysCache(attTuple);
|
||||
return 0;
|
||||
}
|
||||
classForm = (Form_pg_class) GETSTRUCT(classTuple);
|
||||
|
||||
ownerId = classForm->relowner;
|
||||
|
||||
ReleaseSysCache(classTuple);
|
||||
|
||||
/* detoast column's ACL if necessary */
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
@ -2349,7 +2358,6 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
|
||||
pfree(acl);
|
||||
|
||||
ReleaseSysCache(attTuple);
|
||||
ReleaseSysCache(classTuple);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2922,7 +2930,7 @@ pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
|
||||
* ACLCHECK_NO_PRIV).
|
||||
*
|
||||
* If 'how' is ACLMASK_ALL, then returns ACLCHECK_OK if user has any of the
|
||||
* privileges identified by 'mode' on all non-dropped columns in the relation
|
||||
* privileges identified by 'mode' on each non-dropped column in the relation
|
||||
* (and there must be at least one such column); otherwise returns a suitable
|
||||
* error code (in practice, always ACLCHECK_NO_PRIV).
|
||||
*
|
||||
@ -2942,15 +2950,16 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
|
||||
AttrNumber nattrs;
|
||||
AttrNumber curr_att;
|
||||
|
||||
/* Must fetch pg_class row to check number of attributes */
|
||||
/*
|
||||
* Must fetch pg_class row to check number of attributes. As in
|
||||
* pg_attribute_aclmask, we prefer to return "no privileges" instead
|
||||
* of throwing an error if we get any unexpected lookup errors.
|
||||
*/
|
||||
classTuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(table_oid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(classTuple))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||
errmsg("relation with OID %u does not exist",
|
||||
table_oid)));
|
||||
return ACLCHECK_NO_PRIV;
|
||||
classForm = (Form_pg_class) GETSTRUCT(classTuple);
|
||||
|
||||
nattrs = classForm->relnatts;
|
||||
@ -2966,26 +2975,36 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
|
||||
for (curr_att = 1; curr_att <= nattrs; curr_att++)
|
||||
{
|
||||
HeapTuple attTuple;
|
||||
bool isdropped;
|
||||
AclMode attmask;
|
||||
|
||||
attTuple = SearchSysCache(ATTNUM,
|
||||
ObjectIdGetDatum(table_oid),
|
||||
Int16GetDatum(curr_att),
|
||||
0, 0);
|
||||
if (!HeapTupleIsValid(attTuple))
|
||||
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
|
||||
curr_att, table_oid);
|
||||
continue;
|
||||
|
||||
isdropped = ((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped;
|
||||
/* ignore dropped columns */
|
||||
if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
|
||||
{
|
||||
ReleaseSysCache(attTuple);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we hard-wire knowledge that the default ACL for a column
|
||||
* grants no privileges, so that we can fall out quickly in the
|
||||
* very common case where attacl is null.
|
||||
*/
|
||||
if (heap_attisnull(attTuple, Anum_pg_attribute_attacl))
|
||||
attmask = 0;
|
||||
else
|
||||
attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
|
||||
mode, ACLMASK_ANY);
|
||||
|
||||
ReleaseSysCache(attTuple);
|
||||
|
||||
/* ignore dropped columns */
|
||||
if (isdropped)
|
||||
continue;
|
||||
|
||||
if (pg_attribute_aclmask(table_oid, curr_att, roleid,
|
||||
mode, ACLMASK_ANY) != 0)
|
||||
if (attmask != 0)
|
||||
{
|
||||
result = ACLCHECK_OK;
|
||||
if (how == ACLMASK_ANY)
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2003-2009, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.50 2009/01/20 09:10:20 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.51 2009/02/06 21:15:11 tgl Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -494,8 +494,13 @@ CREATE VIEW column_privileges AS
|
||||
CAST(a.attname AS sql_identifier) AS column_name,
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(grantee.oid, c.relowner, 'USAGE')
|
||||
OR aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
OR aclcontains(a.attacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_attribute a,
|
||||
@ -507,18 +512,20 @@ CREATE VIEW column_privileges AS
|
||||
UNION ALL
|
||||
SELECT 0::oid, 'PUBLIC'
|
||||
) AS grantee (oid, rolname),
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
SELECT 'UPDATE' UNION ALL
|
||||
SELECT 'REFERENCES') AS pr (type)
|
||||
(VALUES ('SELECT'),
|
||||
('INSERT'),
|
||||
('UPDATE'),
|
||||
('REFERENCES')) AS pr (type)
|
||||
|
||||
WHERE a.attrelid = c.oid
|
||||
AND c.relnamespace = nc.oid
|
||||
AND a.attnum > 0
|
||||
AND NOT a.attisdropped
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
|
||||
AND (aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
|
||||
OR aclcontains(a.attacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, false)))
|
||||
AND (pg_has_role(u_grantor.oid, 'USAGE')
|
||||
OR pg_has_role(grantee.oid, 'USAGE')
|
||||
OR grantee.rolname = 'PUBLIC');
|
||||
@ -674,10 +681,8 @@ CREATE VIEW columns AS
|
||||
AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind in ('r', 'v')
|
||||
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
OR has_table_privilege(c.oid, 'SELECT')
|
||||
OR has_table_privilege(c.oid, 'INSERT')
|
||||
OR has_table_privilege(c.oid, 'UPDATE')
|
||||
OR has_table_privilege(c.oid, 'REFERENCES') );
|
||||
OR has_column_privilege(c.oid, a.attnum,
|
||||
'SELECT, INSERT, UPDATE, REFERENCES'));
|
||||
|
||||
GRANT SELECT ON columns TO PUBLIC;
|
||||
|
||||
@ -954,8 +959,8 @@ CREATE VIEW key_column_usage AS
|
||||
END AS cardinal_number)
|
||||
AS position_in_unique_constraint
|
||||
FROM pg_attribute a,
|
||||
(SELECT r.oid AS roid, r.relname, nc.nspname AS nc_nspname,
|
||||
nr.nspname AS nr_nspname,
|
||||
(SELECT r.oid AS roid, r.relname, r.relowner,
|
||||
nc.nspname AS nc_nspname, nr.nspname AS nr_nspname,
|
||||
c.oid AS coid, c.conname, c.contype, c.confkey, c.confrelid,
|
||||
_pg_expandarray(c.conkey) AS x
|
||||
FROM pg_namespace nr, pg_class r, pg_namespace nc,
|
||||
@ -965,15 +970,13 @@ CREATE VIEW key_column_usage AS
|
||||
AND nc.oid = c.connamespace
|
||||
AND c.contype IN ('p', 'u', 'f')
|
||||
AND r.relkind = 'r'
|
||||
AND (NOT pg_is_other_temp_schema(nr.oid))
|
||||
AND (pg_has_role(r.relowner, 'USAGE')
|
||||
OR has_table_privilege(r.oid, 'SELECT')
|
||||
OR has_table_privilege(r.oid, 'INSERT')
|
||||
OR has_table_privilege(r.oid, 'UPDATE')
|
||||
OR has_table_privilege(r.oid, 'REFERENCES')) ) AS ss
|
||||
AND (NOT pg_is_other_temp_schema(nr.oid)) ) AS ss
|
||||
WHERE ss.roid = a.attrelid
|
||||
AND a.attnum = (ss.x).x
|
||||
AND NOT a.attisdropped;
|
||||
AND NOT a.attisdropped
|
||||
AND (pg_has_role(relowner, 'USAGE')
|
||||
OR has_column_privilege(roid, a.attnum,
|
||||
'SELECT, INSERT, UPDATE, REFERENCES'));
|
||||
|
||||
GRANT SELECT ON key_column_usage TO PUBLIC;
|
||||
|
||||
@ -1114,7 +1117,10 @@ CREATE VIEW referential_constraints AS
|
||||
WHERE c.relkind = 'r'
|
||||
AND con.contype = 'f'
|
||||
AND (pkc.contype IN ('p', 'u') OR pkc.contype IS NULL)
|
||||
AND pg_has_role(c.relowner, 'USAGE');
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
-- SELECT privilege omitted, per SQL standard
|
||||
OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
|
||||
|
||||
GRANT SELECT ON referential_constraints TO PUBLIC;
|
||||
|
||||
@ -1133,8 +1139,13 @@ CREATE VIEW role_column_grants AS
|
||||
CAST(a.attname AS sql_identifier) AS column_name,
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(g_grantee.oid, c.relowner, 'USAGE')
|
||||
OR aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
|
||||
OR aclcontains(a.attacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_attribute a,
|
||||
@ -1142,18 +1153,20 @@ CREATE VIEW role_column_grants AS
|
||||
pg_namespace nc,
|
||||
pg_authid u_grantor,
|
||||
pg_authid g_grantee,
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
SELECT 'UPDATE' UNION ALL
|
||||
SELECT 'REFERENCES') AS pr (type)
|
||||
(VALUES ('SELECT'),
|
||||
('INSERT'),
|
||||
('UPDATE'),
|
||||
('REFERENCES')) AS pr (type)
|
||||
|
||||
WHERE a.attrelid = c.oid
|
||||
AND c.relnamespace = nc.oid
|
||||
AND a.attnum > 0
|
||||
AND NOT a.attisdropped
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, false))
|
||||
AND (aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, false))
|
||||
OR aclcontains(a.attacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, false)))
|
||||
AND (u_grantor.rolname IN (SELECT role_name FROM enabled_roles)
|
||||
OR g_grantee.rolname IN (SELECT role_name FROM enabled_roles));
|
||||
|
||||
@ -1176,8 +1189,11 @@ CREATE VIEW role_routine_grants AS
|
||||
CAST(p.proname AS sql_identifier) AS routine_name,
|
||||
CAST('EXECUTE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(p.proacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'EXECUTE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(g_grantee.oid, p.proowner, 'USAGE')
|
||||
OR aclcontains(p.proacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'EXECUTE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_proc p,
|
||||
@ -1207,8 +1223,11 @@ CREATE VIEW role_table_grants AS
|
||||
CAST(c.relname AS sql_identifier) AS table_name,
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(g_grantee.oid, c.relowner, 'USAGE')
|
||||
OR aclcontains(c.relacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
|
||||
CAST('NO' AS character_data) AS with_hierarchy
|
||||
|
||||
@ -1216,13 +1235,13 @@ CREATE VIEW role_table_grants AS
|
||||
pg_namespace nc,
|
||||
pg_authid u_grantor,
|
||||
pg_authid g_grantee,
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
SELECT 'UPDATE' UNION ALL
|
||||
SELECT 'DELETE' UNION ALL
|
||||
SELECT 'TRUNCATE' UNION ALL
|
||||
SELECT 'REFERENCES' UNION ALL
|
||||
SELECT 'TRIGGER') AS pr (type)
|
||||
(VALUES ('SELECT'),
|
||||
('INSERT'),
|
||||
('UPDATE'),
|
||||
('DELETE'),
|
||||
('TRUNCATE'),
|
||||
('REFERENCES'),
|
||||
('TRIGGER')) AS pr (type)
|
||||
|
||||
WHERE c.relnamespace = nc.oid
|
||||
AND c.relkind IN ('r', 'v')
|
||||
@ -1258,8 +1277,11 @@ CREATE VIEW role_usage_grants AS
|
||||
CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type,
|
||||
CAST('USAGE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(fdw.fdwacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(g_grantee.oid, fdw.fdwowner, 'USAGE')
|
||||
OR aclcontains(fdw.fdwacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_foreign_data_wrapper fdw,
|
||||
@ -1282,8 +1304,11 @@ CREATE VIEW role_usage_grants AS
|
||||
CAST('FOREIGN SERVER' AS character_data) AS object_type,
|
||||
CAST('USAGE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(srv.srvacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(g_grantee.oid, srv.srvowner, 'USAGE')
|
||||
OR aclcontains(srv.srvacl,
|
||||
makeaclitem(g_grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_foreign_server srv,
|
||||
@ -1330,8 +1355,11 @@ CREATE VIEW routine_privileges AS
|
||||
CAST(p.proname AS sql_identifier) AS routine_name,
|
||||
CAST('EXECUTE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(p.proacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(grantee.oid, p.proowner, 'USAGE')
|
||||
OR aclcontains(p.proacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_proc p,
|
||||
@ -1531,8 +1559,7 @@ CREATE VIEW sequences AS
|
||||
AND c.relkind = 'S'
|
||||
AND (NOT pg_is_other_temp_schema(nc.oid))
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
OR has_table_privilege(c.oid, 'SELECT')
|
||||
OR has_table_privilege(c.oid, 'UPDATE') );
|
||||
OR has_table_privilege(c.oid, 'SELECT, UPDATE') );
|
||||
|
||||
GRANT SELECT ON sequences TO PUBLIC;
|
||||
|
||||
@ -1763,12 +1790,8 @@ CREATE VIEW table_constraints AS
|
||||
AND (NOT pg_is_other_temp_schema(nr.oid))
|
||||
AND (pg_has_role(r.relowner, 'USAGE')
|
||||
-- SELECT privilege omitted, per SQL standard
|
||||
OR has_table_privilege(r.oid, 'INSERT')
|
||||
OR has_table_privilege(r.oid, 'UPDATE')
|
||||
OR has_table_privilege(r.oid, 'DELETE')
|
||||
OR has_table_privilege(r.oid, 'TRUNCATE')
|
||||
OR has_table_privilege(r.oid, 'REFERENCES')
|
||||
OR has_table_privilege(r.oid, 'TRIGGER') )
|
||||
OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') )
|
||||
|
||||
UNION
|
||||
|
||||
@ -1796,13 +1819,9 @@ CREATE VIEW table_constraints AS
|
||||
AND r.relkind = 'r'
|
||||
AND (NOT pg_is_other_temp_schema(nr.oid))
|
||||
AND (pg_has_role(r.relowner, 'USAGE')
|
||||
OR has_table_privilege(r.oid, 'SELECT')
|
||||
OR has_table_privilege(r.oid, 'INSERT')
|
||||
OR has_table_privilege(r.oid, 'UPDATE')
|
||||
OR has_table_privilege(r.oid, 'DELETE')
|
||||
OR has_table_privilege(r.oid, 'TRUNCATE')
|
||||
OR has_table_privilege(r.oid, 'REFERENCES')
|
||||
OR has_table_privilege(r.oid, 'TRIGGER') );
|
||||
-- SELECT privilege omitted, per SQL standard
|
||||
OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') );
|
||||
|
||||
GRANT SELECT ON table_constraints TO PUBLIC;
|
||||
|
||||
@ -1828,8 +1847,11 @@ CREATE VIEW table_privileges AS
|
||||
CAST(c.relname AS sql_identifier) AS table_name,
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(grantee.oid, c.relowner, 'USAGE')
|
||||
OR aclcontains(c.relacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
|
||||
CAST('NO' AS character_data) AS with_hierarchy
|
||||
|
||||
@ -1841,13 +1863,13 @@ CREATE VIEW table_privileges AS
|
||||
UNION ALL
|
||||
SELECT 0::oid, 'PUBLIC'
|
||||
) AS grantee (oid, rolname),
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
SELECT 'UPDATE' UNION ALL
|
||||
SELECT 'DELETE' UNION ALL
|
||||
SELECT 'TRUNCATE' UNION ALL
|
||||
SELECT 'REFERENCES' UNION ALL
|
||||
SELECT 'TRIGGER') AS pr (type)
|
||||
(VALUES ('SELECT'),
|
||||
('INSERT'),
|
||||
('UPDATE'),
|
||||
('DELETE'),
|
||||
('TRUNCATE'),
|
||||
('REFERENCES'),
|
||||
('TRIGGER')) AS pr (type)
|
||||
|
||||
WHERE c.relnamespace = nc.oid
|
||||
AND c.relkind IN ('r', 'v')
|
||||
@ -1901,13 +1923,8 @@ CREATE VIEW tables AS
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND (NOT pg_is_other_temp_schema(nc.oid))
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
OR has_table_privilege(c.oid, 'SELECT')
|
||||
OR has_table_privilege(c.oid, 'INSERT')
|
||||
OR has_table_privilege(c.oid, 'UPDATE')
|
||||
OR has_table_privilege(c.oid, 'DELETE')
|
||||
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||
OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
|
||||
|
||||
GRANT SELECT ON tables TO PUBLIC;
|
||||
|
||||
@ -2013,9 +2030,9 @@ CREATE VIEW triggers AS
|
||||
CAST(null AS time_stamp) AS created
|
||||
|
||||
FROM pg_namespace n, pg_class c, pg_trigger t,
|
||||
(SELECT 4, 'INSERT' UNION ALL
|
||||
SELECT 8, 'DELETE' UNION ALL
|
||||
SELECT 16, 'UPDATE') AS em (num, text)
|
||||
(VALUES (4, 'INSERT'),
|
||||
(8, 'DELETE'),
|
||||
(16, 'UPDATE')) AS em (num, text)
|
||||
|
||||
WHERE n.oid = c.relnamespace
|
||||
AND c.oid = t.tgrelid
|
||||
@ -2024,12 +2041,8 @@ CREATE VIEW triggers AS
|
||||
AND (NOT pg_is_other_temp_schema(n.oid))
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
-- SELECT privilege omitted, per SQL standard
|
||||
OR has_table_privilege(c.oid, 'INSERT')
|
||||
OR has_table_privilege(c.oid, 'UPDATE')
|
||||
OR has_table_privilege(c.oid, 'DELETE')
|
||||
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||
OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
|
||||
|
||||
GRANT SELECT ON triggers TO PUBLIC;
|
||||
|
||||
@ -2079,8 +2092,11 @@ CREATE VIEW usage_privileges AS
|
||||
CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type,
|
||||
CAST('USAGE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(fdw.fdwacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(grantee.oid, fdw.fdwowner, 'USAGE')
|
||||
OR aclcontains(fdw.fdwacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_foreign_data_wrapper fdw,
|
||||
@ -2108,8 +2124,11 @@ CREATE VIEW usage_privileges AS
|
||||
CAST('FOREIGN SERVER' AS character_data) AS object_type,
|
||||
CAST('USAGE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(srv.srvacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
CASE WHEN
|
||||
-- object owner always has grant options
|
||||
pg_has_role(grantee.oid, srv.srvowner, 'USAGE')
|
||||
OR aclcontains(srv.srvacl,
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'USAGE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_foreign_server srv,
|
||||
@ -2279,13 +2298,8 @@ CREATE VIEW views AS
|
||||
AND c.relkind = 'v'
|
||||
AND (NOT pg_is_other_temp_schema(nc.oid))
|
||||
AND (pg_has_role(c.relowner, 'USAGE')
|
||||
OR has_table_privilege(c.oid, 'SELECT')
|
||||
OR has_table_privilege(c.oid, 'INSERT')
|
||||
OR has_table_privilege(c.oid, 'UPDATE')
|
||||
OR has_table_privilege(c.oid, 'DELETE')
|
||||
OR has_table_privilege(c.oid, 'TRUNCATE')
|
||||
OR has_table_privilege(c.oid, 'REFERENCES')
|
||||
OR has_table_privilege(c.oid, 'TRIGGER') );
|
||||
OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||
OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
|
||||
|
||||
GRANT SELECT ON views TO PUBLIC;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.58 2009/01/01 17:23:37 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.59 2009/02/06 21:15:11 tgl Exp $
|
||||
*/
|
||||
|
||||
CREATE VIEW pg_roles AS
|
||||
@ -137,7 +137,7 @@ CREATE VIEW pg_stats AS
|
||||
FROM pg_statistic s JOIN pg_class c ON (c.oid = s.starelid)
|
||||
JOIN pg_attribute a ON (c.oid = attrelid AND attnum = s.staattnum)
|
||||
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
||||
WHERE has_table_privilege(c.oid, 'select');
|
||||
WHERE NOT attisdropped AND has_column_privilege(c.oid, a.attnum, 'select');
|
||||
|
||||
REVOKE ALL on pg_statistic FROM public;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.304 2009/01/02 20:42:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.305 2009/02/06 21:15:11 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -711,7 +711,7 @@ CopyLoadRawBuf(CopyState cstate)
|
||||
* or write to a file.
|
||||
*
|
||||
* Do not allow the copy if user doesn't have proper permission to access
|
||||
* the table.
|
||||
* the table or the specifically requested columns.
|
||||
*/
|
||||
uint64
|
||||
DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
@ -723,7 +723,8 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
List *force_quote = NIL;
|
||||
List *force_notnull = NIL;
|
||||
AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT);
|
||||
AclResult aclresult;
|
||||
AclMode relPerms;
|
||||
AclMode remainingPerms;
|
||||
ListCell *option;
|
||||
TupleDesc tupDesc;
|
||||
int num_phys_attrs;
|
||||
@ -973,13 +974,31 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
cstate->rel = heap_openrv(stmt->relation,
|
||||
(is_from ? RowExclusiveLock : AccessShareLock));
|
||||
|
||||
tupDesc = RelationGetDescr(cstate->rel);
|
||||
|
||||
/* Check relation permissions. */
|
||||
aclresult = pg_class_aclcheck(RelationGetRelid(cstate->rel),
|
||||
GetUserId(),
|
||||
required_access);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(cstate->rel));
|
||||
relPerms = pg_class_aclmask(RelationGetRelid(cstate->rel), GetUserId(),
|
||||
required_access, ACLMASK_ALL);
|
||||
remainingPerms = required_access & ~relPerms;
|
||||
if (remainingPerms != 0)
|
||||
{
|
||||
/* We don't have table permissions, check per-column permissions */
|
||||
List *attnums;
|
||||
ListCell *cur;
|
||||
|
||||
attnums = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
|
||||
foreach(cur, attnums)
|
||||
{
|
||||
int attnum = lfirst_int(cur);
|
||||
|
||||
if (pg_attribute_aclcheck(RelationGetRelid(cstate->rel),
|
||||
attnum,
|
||||
GetUserId(),
|
||||
remainingPerms) != ACLCHECK_OK)
|
||||
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(cstate->rel));
|
||||
}
|
||||
}
|
||||
|
||||
/* check read-only transaction */
|
||||
if (XactReadOnly && is_from &&
|
||||
@ -994,8 +1013,6 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("table \"%s\" does not have OIDs",
|
||||
RelationGetRelationName(cstate->rel))));
|
||||
|
||||
tupDesc = RelationGetDescr(cstate->rel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.520 2009/01/27 12:40:15 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.521 2009/02/06 21:15:11 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200901271
|
||||
#define CATALOG_VERSION_NO 200902061
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.535 2009/01/01 17:23:57 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.536 2009/02/06 21:15:11 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -2913,6 +2913,43 @@ DESCR("current user privilege on relation by rel name");
|
||||
DATA(insert OID = 1927 ( has_table_privilege PGNSP PGUID 12 1 0 0 f f f t f s 2 0 16 "26 25" _null_ _null_ _null_ _null_ has_table_privilege_id _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on relation by rel oid");
|
||||
|
||||
DATA(insert OID = 3012 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "19 25 25 25" _null_ _null_ _null_ _null_ has_column_privilege_name_name_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by username, rel name, col name");
|
||||
DATA(insert OID = 3013 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "19 25 21 25" _null_ _null_ _null_ _null_ has_column_privilege_name_name_attnum _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by username, rel name, col attnum");
|
||||
DATA(insert OID = 3014 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "19 26 25 25" _null_ _null_ _null_ _null_ has_column_privilege_name_id_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by username, rel oid, col name");
|
||||
DATA(insert OID = 3015 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "19 26 21 25" _null_ _null_ _null_ _null_ has_column_privilege_name_id_attnum _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by username, rel oid, col attnum");
|
||||
DATA(insert OID = 3016 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "26 25 25 25" _null_ _null_ _null_ _null_ has_column_privilege_id_name_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by user oid, rel name, col name");
|
||||
DATA(insert OID = 3017 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "26 25 21 25" _null_ _null_ _null_ _null_ has_column_privilege_id_name_attnum _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by user oid, rel name, col attnum");
|
||||
DATA(insert OID = 3018 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "26 26 25 25" _null_ _null_ _null_ _null_ has_column_privilege_id_id_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by user oid, rel oid, col name");
|
||||
DATA(insert OID = 3019 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 4 0 16 "26 26 21 25" _null_ _null_ _null_ _null_ has_column_privilege_id_id_attnum _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on column by user oid, rel oid, col attnum");
|
||||
DATA(insert OID = 3020 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 3 0 16 "25 25 25" _null_ _null_ _null_ _null_ has_column_privilege_name_name _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on column by rel name, col name");
|
||||
DATA(insert OID = 3021 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 3 0 16 "25 21 25" _null_ _null_ _null_ _null_ has_column_privilege_name_attnum _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on column by rel name, col attnum");
|
||||
DATA(insert OID = 3022 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 3 0 16 "26 25 25" _null_ _null_ _null_ _null_ has_column_privilege_id_name _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on column by rel oid, col name");
|
||||
DATA(insert OID = 3023 ( has_column_privilege PGNSP PGUID 12 1 0 0 f f f t f s 3 0 16 "26 21 25" _null_ _null_ _null_ _null_ has_column_privilege_id_attnum _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on column by rel oid, col attnum");
|
||||
|
||||
DATA(insert OID = 3024 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 3 0 16 "19 25 25" _null_ _null_ _null_ _null_ has_any_column_privilege_name_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on any column by username, rel name");
|
||||
DATA(insert OID = 3025 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 3 0 16 "19 26 25" _null_ _null_ _null_ _null_ has_any_column_privilege_name_id _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on any column by username, rel oid");
|
||||
DATA(insert OID = 3026 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 3 0 16 "26 25 25" _null_ _null_ _null_ _null_ has_any_column_privilege_id_name _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on any column by user oid, rel name");
|
||||
DATA(insert OID = 3027 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 3 0 16 "26 26 25" _null_ _null_ _null_ _null_ has_any_column_privilege_id_id _null_ _null_ _null_ ));
|
||||
DESCR("user privilege on any column by user oid, rel oid");
|
||||
DATA(insert OID = 3028 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 2 0 16 "25 25" _null_ _null_ _null_ _null_ has_any_column_privilege_name _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on any column by rel name");
|
||||
DATA(insert OID = 3029 ( has_any_column_privilege PGNSP PGUID 12 10 0 0 f f f t f s 2 0 16 "26 25" _null_ _null_ _null_ _null_ has_any_column_privilege_id _null_ _null_ _null_ ));
|
||||
DESCR("current user privilege on any column by rel oid");
|
||||
|
||||
DATA(insert OID = 1928 ( pg_stat_get_numscans PGNSP PGUID 12 1 0 0 f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_numscans _null_ _null_ _null_ ));
|
||||
DESCR("statistics: number of scans done for table/index");
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.330 2009/01/01 17:24:02 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.331 2009/02/06 21:15:12 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -22,6 +22,24 @@
|
||||
*/
|
||||
|
||||
/* acl.c */
|
||||
extern Datum has_any_column_privilege_name_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_any_column_privilege_name_id(PG_FUNCTION_ARGS);
|
||||
extern Datum has_any_column_privilege_id_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_any_column_privilege_id_id(PG_FUNCTION_ARGS);
|
||||
extern Datum has_any_column_privilege_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_any_column_privilege_id(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_name_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_id_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_name_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_name_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_id_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_id_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_name_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_column_privilege_id_attnum(PG_FUNCTION_ARGS);
|
||||
extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS);
|
||||
extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS);
|
||||
extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS);
|
||||
|
@ -695,8 +695,8 @@ SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorizati
|
||||
SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5;
|
||||
grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable
|
||||
-------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+--------------
|
||||
foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO
|
||||
foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | NO
|
||||
foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES
|
||||
foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | YES
|
||||
foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO
|
||||
foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES
|
||||
(4 rows)
|
||||
@ -704,8 +704,8 @@ SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIG
|
||||
SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5;
|
||||
grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable
|
||||
-------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+--------------
|
||||
foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO
|
||||
foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | NO
|
||||
foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES
|
||||
foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | YES
|
||||
foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO
|
||||
foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES
|
||||
(4 rows)
|
||||
|
@ -258,10 +258,16 @@ SELECT one FROM atest5; -- ok
|
||||
1
|
||||
(1 row)
|
||||
|
||||
COPY atest5 (one) TO stdout; -- ok
|
||||
1
|
||||
SELECT two FROM atest5; -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
COPY atest5 (two) TO stdout; -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
SELECT atest5 FROM atest5; -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
COPY atest5 (one,two) TO stdout; -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
SELECT 1 FROM atest5; -- ok
|
||||
?column?
|
||||
----------
|
||||
@ -324,6 +330,9 @@ SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now
|
||||
|
||||
-- test column-level privileges for INSERT and UPDATE
|
||||
INSERT INTO atest5 (two) VALUES (3); -- ok
|
||||
COPY atest5 FROM stdin; -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
COPY atest5 (two) FROM stdin; -- ok
|
||||
INSERT INTO atest5 (three) VALUES (4); -- fail
|
||||
ERROR: permission denied for relation atest5
|
||||
INSERT INTO atest5 VALUES (5,5,5); -- fail
|
||||
@ -346,6 +355,7 @@ SELECT atest6 FROM atest6; -- ok
|
||||
--------
|
||||
(0 rows)
|
||||
|
||||
COPY atest6 TO stdout; -- ok
|
||||
-- test column-level privileges when involved with DELETE
|
||||
SET SESSION AUTHORIZATION regressuser1;
|
||||
ALTER TABLE atest6 ADD COLUMN three integer;
|
||||
|
@ -1276,8 +1276,8 @@ drop table cchild;
|
||||
-- Check that ruleutils are working
|
||||
--
|
||||
SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname;
|
||||
viewname | definition
|
||||
--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
viewname | definition
|
||||
--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
|
||||
pg_cursors | SELECT c.name, c.statement, c.is_holdable, c.is_binary, c.is_scrollable, c.creation_time FROM pg_cursor() c(name, statement, is_holdable, is_binary, is_scrollable, creation_time);
|
||||
pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
|
||||
@ -1308,7 +1308,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
|
||||
pg_statio_user_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_indexes.schemaname !~ '^pg_toast'::text));
|
||||
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_sequences.schemaname !~ '^pg_toast'::text));
|
||||
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_tables.schemaname !~ '^pg_toast'::text));
|
||||
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stavalues1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stavalues2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stavalues3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stanumbers1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stanumbers2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stanumbers3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (s.stakind1 = 2) THEN s.stavalues1 WHEN (s.stakind2 = 2) THEN s.stavalues2 WHEN (s.stakind3 = 2) THEN s.stavalues3 WHEN (s.stakind4 = 2) THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE WHEN (s.stakind1 = 3) THEN s.stanumbers1[1] WHEN (s.stakind2 = 3) THEN s.stanumbers2[1] WHEN (s.stakind3 = 3) THEN s.stanumbers3[1] WHEN (s.stakind4 = 3) THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
|
||||
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stavalues1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stavalues2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stavalues3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stanumbers1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stanumbers2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stanumbers3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (s.stakind1 = 2) THEN s.stavalues1 WHEN (s.stakind2 = 2) THEN s.stavalues2 WHEN (s.stakind3 = 2) THEN s.stavalues3 WHEN (s.stakind4 = 2) THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE WHEN (s.stakind1 = 3) THEN s.stanumbers1[1] WHEN (s.stakind2 = 3) THEN s.stanumbers2[1] WHEN (s.stakind3 = 3) THEN s.stanumbers3[1] WHEN (s.stakind4 = 3) THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text));
|
||||
pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS tablespace, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.relhastriggers AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
|
||||
pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
|
||||
pg_timezone_names | SELECT pg_timezone_names.name, pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);
|
||||
|
@ -184,8 +184,11 @@ INSERT INTO atest5 VALUES (1,2,3);
|
||||
SET SESSION AUTHORIZATION regressuser4;
|
||||
SELECT * FROM atest5; -- fail
|
||||
SELECT one FROM atest5; -- ok
|
||||
COPY atest5 (one) TO stdout; -- ok
|
||||
SELECT two FROM atest5; -- fail
|
||||
COPY atest5 (two) TO stdout; -- fail
|
||||
SELECT atest5 FROM atest5; -- fail
|
||||
COPY atest5 (one,two) TO stdout; -- fail
|
||||
SELECT 1 FROM atest5; -- ok
|
||||
SELECT 1 FROM atest5 a JOIN atest5 b USING (one); -- ok
|
||||
SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
|
||||
@ -213,6 +216,10 @@ SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now
|
||||
|
||||
-- test column-level privileges for INSERT and UPDATE
|
||||
INSERT INTO atest5 (two) VALUES (3); -- ok
|
||||
COPY atest5 FROM stdin; -- fail
|
||||
COPY atest5 (two) FROM stdin; -- ok
|
||||
1
|
||||
\.
|
||||
INSERT INTO atest5 (three) VALUES (4); -- fail
|
||||
INSERT INTO atest5 VALUES (5,5,5); -- fail
|
||||
UPDATE atest5 SET three = 10; -- ok
|
||||
@ -227,6 +234,7 @@ SET SESSION AUTHORIZATION regressuser4;
|
||||
SELECT one FROM atest5; -- fail
|
||||
UPDATE atest5 SET one = 1; -- fail
|
||||
SELECT atest6 FROM atest6; -- ok
|
||||
COPY atest6 TO stdout; -- ok
|
||||
|
||||
-- test column-level privileges when involved with DELETE
|
||||
SET SESSION AUTHORIZATION regressuser1;
|
||||
|
Loading…
Reference in New Issue
Block a user