Support GRANT/REVOKE ON ALL TABLES/SEQUENCES/FUNCTIONS IN SCHEMA.

Petr Jelinek
This commit is contained in:
Tom Lane 2009-10-12 20:39:42 +00:00
parent faa1afc6c1
commit 11ca04b4b7
10 changed files with 300 additions and 20 deletions

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.78 2009/10/05 19:24:34 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.79 2009/10/12 20:39:39 tgl Exp $
PostgreSQL documentation
-->
@ -23,7 +23,8 @@ PostgreSQL documentation
<synopsis>
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
ON { [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="PARAMETER">column</replaceable> [, ...] )
@ -33,7 +34,8 @@ GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="PARAMETE
GRANT { { USAGE | SELECT | UPDATE }
[,...] | ALL [ PRIVILEGES ] }
ON SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...]
ON { SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...]
| ALL SEQUENCES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
@ -49,7 +51,8 @@ GRANT { USAGE | ALL [ PRIVILEGES ] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...]
ON { FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...]
| ALL FUNCTIONS IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
@ -90,6 +93,13 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
to those already granted, if any.
</para>
<para>
There is also an option to grant privileges on all objects of the same
type within one or more schemas. This functionality is currently supported
only for tables, sequences, and functions (but note that <literal>ALL
TABLES</> is considered to include views).
</para>
<para>
The key word <literal>PUBLIC</literal> indicates that the
privileges are to be granted to all roles, including those that might

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.52 2009/09/19 10:23:27 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.53 2009/10/12 20:39:39 tgl Exp $
PostgreSQL documentation
-->
@ -24,7 +24,8 @@ PostgreSQL documentation
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
ON { [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
@ -38,7 +39,8 @@ REVOKE [ GRANT OPTION FOR ]
REVOKE [ GRANT OPTION FOR ]
{ { USAGE | SELECT | UPDATE }
[,...] | ALL [ PRIVILEGES ] }
ON SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...]
ON { SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...]
| ALL SEQUENCES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
@ -62,7 +64,8 @@ REVOKE [ GRANT OPTION FOR ]
REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...]
ON { FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...]
| ALL FUNCTIONS IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.155 2009/10/05 19:24:35 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.156 2009/10/12 20:39:39 tgl Exp $
*
* NOTES
* See acl.h.
@ -110,6 +110,8 @@ static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames);
static void SetDefaultACL(InternalDefaultACL *iacls);
static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
static List *objectsInSchemaToOids(GrantObjectType objtype, List *nspnames);
static List *getRelationsInNamespace(Oid namespaceId, char relkind);
static void expand_col_privileges(List *colnames, Oid table_oid,
AclMode this_privileges,
AclMode *col_privileges,
@ -335,7 +337,22 @@ ExecuteGrantStmt(GrantStmt *stmt)
*/
istmt.is_grant = stmt->is_grant;
istmt.objtype = stmt->objtype;
istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
/* Collect the OIDs of the target objects */
switch (stmt->targtype)
{
case ACL_TARGET_OBJECT:
istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
break;
case ACL_TARGET_ALL_IN_SCHEMA:
istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
break;
/* ACL_TARGET_DEFAULTS should not be seen here */
default:
elog(ERROR, "unrecognized GrantStmt.targtype: %d",
(int) stmt->targtype);
}
/* all_privs to be filled below */
/* privileges to be filled below */
istmt.col_privs = NIL; /* may get filled below */
@ -656,6 +673,112 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
return objects;
}
/*
* objectsInSchemaToOids
*
* Find all objects of a given type in specified schemas, and make a list
* of their Oids. We check USAGE privilege on the schemas, but there is
* no privilege checking on the individual objects here.
*/
static List *
objectsInSchemaToOids(GrantObjectType objtype, List *nspnames)
{
List *objects = NIL;
ListCell *cell;
foreach(cell, nspnames)
{
char *nspname = strVal(lfirst(cell));
Oid namespaceId;
List *objs;
namespaceId = LookupExplicitNamespace(nspname);
switch (objtype)
{
case ACL_OBJECT_RELATION:
/* Process both regular tables and views */
objs = getRelationsInNamespace(namespaceId, RELKIND_RELATION);
objects = list_concat(objects, objs);
objs = getRelationsInNamespace(namespaceId, RELKIND_VIEW);
objects = list_concat(objects, objs);
break;
case ACL_OBJECT_SEQUENCE:
objs = getRelationsInNamespace(namespaceId, RELKIND_SEQUENCE);
objects = list_concat(objects, objs);
break;
case ACL_OBJECT_FUNCTION:
{
ScanKeyData key[1];
Relation rel;
HeapScanDesc scan;
HeapTuple tuple;
ScanKeyInit(&key[0],
Anum_pg_proc_pronamespace,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(namespaceId));
rel = heap_open(ProcedureRelationId, AccessShareLock);
scan = heap_beginscan(rel, SnapshotNow, 1, key);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
objects = lappend_oid(objects, HeapTupleGetOid(tuple));
}
heap_endscan(scan);
heap_close(rel, AccessShareLock);
}
break;
default:
/* should not happen */
elog(ERROR, "unrecognized GrantStmt.objtype: %d",
(int) objtype);
}
}
return objects;
}
/*
* getRelationsInNamespace
*
* Return Oid list of relations in given namespace filtered by relation kind
*/
static List *
getRelationsInNamespace(Oid namespaceId, char relkind)
{
List *relations = NIL;
ScanKeyData key[2];
Relation rel;
HeapScanDesc scan;
HeapTuple tuple;
ScanKeyInit(&key[0],
Anum_pg_class_relnamespace,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(namespaceId));
ScanKeyInit(&key[1],
Anum_pg_class_relkind,
BTEqualStrategyNumber, F_CHAREQ,
CharGetDatum(relkind));
rel = heap_open(RelationRelationId, AccessShareLock);
scan = heap_beginscan(rel, SnapshotNow, 2, key);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
relations = lappend_oid(relations, HeapTupleGetOid(tuple));
}
heap_endscan(scan);
heap_close(rel, AccessShareLock);
return relations;
}
/*
* ALTER DEFAULT PRIVILEGES statement
*/

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.445 2009/10/12 19:49:24 adunstan Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.446 2009/10/12 20:39:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -2350,6 +2350,7 @@ _copyGrantStmt(GrantStmt *from)
GrantStmt *newnode = makeNode(GrantStmt);
COPY_SCALAR_FIELD(is_grant);
COPY_SCALAR_FIELD(targtype);
COPY_SCALAR_FIELD(objtype);
COPY_NODE_FIELD(objects);
COPY_NODE_FIELD(privileges);

View File

@ -22,7 +22,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.367 2009/10/12 19:49:24 adunstan Exp $
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.368 2009/10/12 20:39:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -990,6 +990,7 @@ static bool
_equalGrantStmt(GrantStmt *a, GrantStmt *b)
{
COMPARE_SCALAR_FIELD(is_grant);
COMPARE_SCALAR_FIELD(targtype);
COMPARE_SCALAR_FIELD(objtype);
COMPARE_NODE_FIELD(objects);
COMPARE_NODE_FIELD(privileges);

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.683 2009/10/12 19:49:24 adunstan Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.684 2009/10/12 20:39:41 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -95,6 +95,7 @@
/* Private struct for the result of privilege_target production */
typedef struct PrivTarget
{
GrantTargetType targtype;
GrantObjectType objtype;
List *objs;
} PrivTarget;
@ -480,7 +481,7 @@ static TypeName *TableFuncTypeName(List *columns);
EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION
FREEZE FROM FULL FUNCTION FUNCTIONS
GLOBAL GRANT GRANTED GREATEST GROUP_P
@ -518,13 +519,13 @@ static TypeName *TableFuncTypeName(List *columns);
RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART
RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE
SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
SYMMETRIC SYSID SYSTEM_P
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
TRUNCATE TRUSTED TYPE_P
@ -4321,6 +4322,7 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list
GrantStmt *n = makeNode(GrantStmt);
n->is_grant = true;
n->privileges = $2;
n->targtype = ($4)->targtype;
n->objtype = ($4)->objtype;
n->objects = ($4)->objs;
n->grantees = $6;
@ -4337,6 +4339,7 @@ RevokeStmt:
n->is_grant = false;
n->grant_option = false;
n->privileges = $2;
n->targtype = ($4)->targtype;
n->objtype = ($4)->objtype;
n->objects = ($4)->objs;
n->grantees = $6;
@ -4350,6 +4353,7 @@ RevokeStmt:
n->is_grant = false;
n->grant_option = true;
n->privileges = $5;
n->targtype = ($7)->targtype;
n->objtype = ($7)->objtype;
n->objects = ($7)->objs;
n->grantees = $9;
@ -4432,6 +4436,7 @@ privilege_target:
qualified_name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_RELATION;
n->objs = $1;
$$ = n;
@ -4439,6 +4444,7 @@ privilege_target:
| TABLE qualified_name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_RELATION;
n->objs = $2;
$$ = n;
@ -4446,6 +4452,7 @@ privilege_target:
| SEQUENCE qualified_name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_SEQUENCE;
n->objs = $2;
$$ = n;
@ -4453,6 +4460,7 @@ privilege_target:
| FOREIGN DATA_P WRAPPER name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_FDW;
n->objs = $4;
$$ = n;
@ -4460,6 +4468,7 @@ privilege_target:
| FOREIGN SERVER name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_FOREIGN_SERVER;
n->objs = $3;
$$ = n;
@ -4467,6 +4476,7 @@ privilege_target:
| FUNCTION function_with_argtypes_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_FUNCTION;
n->objs = $2;
$$ = n;
@ -4474,6 +4484,7 @@ privilege_target:
| DATABASE name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_DATABASE;
n->objs = $2;
$$ = n;
@ -4481,6 +4492,7 @@ privilege_target:
| LANGUAGE name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_LANGUAGE;
n->objs = $2;
$$ = n;
@ -4488,6 +4500,7 @@ privilege_target:
| SCHEMA name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_NAMESPACE;
n->objs = $2;
$$ = n;
@ -4495,10 +4508,35 @@ privilege_target:
| TABLESPACE name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_OBJECT;
n->objtype = ACL_OBJECT_TABLESPACE;
n->objs = $2;
$$ = n;
}
| ALL TABLES IN_P SCHEMA name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
n->objtype = ACL_OBJECT_RELATION;
n->objs = $5;
$$ = n;
}
| ALL SEQUENCES IN_P SCHEMA name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
n->objtype = ACL_OBJECT_SEQUENCE;
n->objs = $5;
$$ = n;
}
| ALL FUNCTIONS IN_P SCHEMA name_list
{
PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
n->objtype = ACL_OBJECT_FUNCTION;
n->objs = $5;
$$ = n;
}
;
@ -4648,6 +4686,7 @@ DefACLAction:
GrantStmt *n = makeNode(GrantStmt);
n->is_grant = true;
n->privileges = $2;
n->targtype = ACL_TARGET_DEFAULTS;
n->objtype = $4;
n->objects = NIL;
n->grantees = $6;
@ -4661,6 +4700,7 @@ DefACLAction:
n->is_grant = false;
n->grant_option = false;
n->privileges = $2;
n->targtype = ACL_TARGET_DEFAULTS;
n->objtype = $4;
n->objects = NIL;
n->grantees = $6;
@ -4674,6 +4714,7 @@ DefACLAction:
n->is_grant = false;
n->grant_option = true;
n->privileges = $5;
n->targtype = ACL_TARGET_DEFAULTS;
n->objtype = $7;
n->objects = NIL;
n->grantees = $9;
@ -10535,6 +10576,7 @@ unreserved_keyword:
| FORCE
| FORWARD
| FUNCTION
| FUNCTIONS
| GLOBAL
| GRANTED
| HANDLER
@ -10644,6 +10686,7 @@ unreserved_keyword:
| SECOND_P
| SECURITY
| SEQUENCE
| SEQUENCES
| SERIALIZABLE
| SERVER
| SESSION
@ -10664,6 +10707,7 @@ unreserved_keyword:
| SUPERUSER_P
| SYSID
| SYSTEM_P
| TABLES
| TABLESPACE
| TEMP
| TEMPLATE

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.407 2009/10/12 19:49:24 adunstan Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.408 2009/10/12 20:39:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1182,6 +1182,13 @@ typedef struct AlterDomainStmt
* Grant|Revoke Statement
* ----------------------
*/
typedef enum GrantTargetType
{
ACL_TARGET_OBJECT, /* grant on specific named object(s) */
ACL_TARGET_ALL_IN_SCHEMA, /* grant on all objects in given schema(s) */
ACL_TARGET_DEFAULTS /* ALTER DEFAULT PRIVILEGES */
} GrantTargetType;
typedef enum GrantObjectType
{
ACL_OBJECT_COLUMN, /* column */
@ -1200,6 +1207,7 @@ typedef struct GrantStmt
{
NodeTag type;
bool is_grant; /* true = GRANT, false = REVOKE */
GrantTargetType targtype; /* type of the grant target */
GrantObjectType objtype; /* kind of object being operated on */
List *objects; /* list of RangeVar nodes, FuncWithArgs nodes,
* or plain names (as Value strings) */

View File

@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.4 2009/10/12 19:49:24 adunstan Exp $
* $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.5 2009/10/12 20:39:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -164,6 +164,7 @@ PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("from", FROM, RESERVED_KEYWORD)
PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD)
PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD)
PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD)
PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD)
PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD)
@ -329,6 +330,7 @@ PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD)
PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD)
PG_KEYWORD("select", SELECT, RESERVED_KEYWORD)
PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD)
PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD)
PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD)
PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD)
PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD)
@ -357,6 +359,7 @@ PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD)
PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD)
PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD)
PG_KEYWORD("table", TABLE, RESERVED_KEYWORD)
PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD)
PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD)
PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD)
PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD)

View File

@ -3,7 +3,7 @@
--
-- Clean up in case a prior regression run failed
-- Suppress NOTICE messages when users/groups don't exist
SET client_min_messages TO 'error';
SET client_min_messages TO 'warning';
DROP ROLE IF EXISTS regressgroup1;
DROP ROLE IF EXISTS regressgroup2;
DROP ROLE IF EXISTS regressuser1;
@ -947,6 +947,60 @@ SELECT d.* -- check that entries went away
------------+-----------------+---------------+-----------
(0 rows)
-- Grant on all objects of given type in a schema
\c -
CREATE SCHEMA testns;
CREATE TABLE testns.t1 (f1 int);
CREATE TABLE testns.t2 (f1 int);
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
has_table_privilege
---------------------
f
(1 row)
GRANT ALL ON ALL TABLES IN SCHEMA testns TO regressuser1;
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- true
has_table_privilege
---------------------
t
(1 row)
SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- true
has_table_privilege
---------------------
t
(1 row)
REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regressuser1;
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
has_table_privilege
---------------------
f
(1 row)
SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- false
has_table_privilege
---------------------
f
(1 row)
CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
has_function_privilege
------------------------
t
(1 row)
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- false
has_function_privilege
------------------------
f
(1 row)
SET client_min_messages TO 'warning';
DROP SCHEMA testns CASCADE;
RESET client_min_messages;
-- clean up
\c
drop sequence x_seq;

View File

@ -5,7 +5,7 @@
-- Clean up in case a prior regression run failed
-- Suppress NOTICE messages when users/groups don't exist
SET client_min_messages TO 'error';
SET client_min_messages TO 'warning';
DROP ROLE IF EXISTS regressgroup1;
DROP ROLE IF EXISTS regressgroup2;
@ -551,6 +551,39 @@ SELECT d.* -- check that entries went away
FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
WHERE nspname IS NULL AND defaclnamespace != 0;
-- Grant on all objects of given type in a schema
\c -
CREATE SCHEMA testns;
CREATE TABLE testns.t1 (f1 int);
CREATE TABLE testns.t2 (f1 int);
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
GRANT ALL ON ALL TABLES IN SCHEMA testns TO regressuser1;
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- true
SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- true
REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regressuser1;
SELECT has_table_privilege('regressuser1', 'testns.t1', 'SELECT'); -- false
SELECT has_table_privilege('regressuser1', 'testns.t2', 'SELECT'); -- false
CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE'); -- false
SET client_min_messages TO 'warning';
DROP SCHEMA testns CASCADE;
RESET client_min_messages;
-- clean up
\c