One more typo fix in docs

--
Regards
Petr Jelinek (PJMODOS)
diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml
index bf963b8..6400f9e 100644
*** a/doc/src/sgml/ref/grant.sgml
--- b/doc/src/sgml/ref/grant.sgml
*************** PostgreSQL documentation
*** 23,39 ****
  <synopsis>
  GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER 
}
      [,...] | ALL [ PRIVILEGES ] }
!     ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, 
...]
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] )
      [,...] | ALL [ PRIVILEGES ] ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] ) }
!     ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, 
...]
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { USAGE | SELECT | UPDATE }
      [,...] | ALL [ PRIVILEGES ] }
!     ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, 
...]
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
--- 23,41 ----
  <synopsis>
  GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER 
}
      [,...] | ALL [ PRIVILEGES ] }
!     ON { { [ TABLE | VIEW ] <replaceable 
class="PARAMETER">tablename</replaceable> [, ...] } 
!     | ALL [ TABLES | VIEWS ] IN <replaceable 
class="PARAMETER">schemaname</replaceable> [, ...] }
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] )
      [,...] | ALL [ PRIVILEGES ] ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] ) }
!     ON [ TABLE | VIEW ] <replaceable 
class="PARAMETER">tablename</replaceable> [, ...]
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { USAGE | SELECT | UPDATE }
      [,...] | ALL [ PRIVILEGES ] }
!     ON { SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> 
[, ...]
!     | ALL SEQUENCES IN <replaceable 
class="PARAMETER">schemaname</replaceable> [, ...] }
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
*************** GRANT { USAGE | ALL [ PRIVILEGES ] }
*** 49,55 ****
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { EXECUTE | ALL [ PRIVILEGES ] }
!     ON FUNCTION <replaceable>funcname</replaceable> ( [ [ <replaceable 
class="parameter">argmode</replaceable> ] [ <replaceable 
class="parameter">argname</replaceable> ] <replaceable 
class="parameter">argtype</replaceable> [, ...] ] ) [, ...]
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { USAGE | ALL [ PRIVILEGES ] }
--- 51,58 ----
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { EXECUTE | ALL [ PRIVILEGES ] }
!     ON { FUNCTION <replaceable>funcname</replaceable> ( [ [ <replaceable 
class="parameter">argmode</replaceable> ] [ <replaceable 
class="parameter">argname</replaceable> ] <replaceable 
class="parameter">argtype</replaceable> [, ...] ] ) [, ...]
!     | ALL FUNCTIONS IN <replaceable 
class="PARAMETER">schemaname</replaceable> [, ...] }
      TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
  GRANT { USAGE | ALL [ PRIVILEGES ] }
*************** GRANT <replaceable class="PARAMETER">rol
*** 143,148 ****
--- 146,159 ----
    </para>
  
    <para>
+    There is also the possibility of granting permissions to all objects of
+    given type inside one or multiple schemas. This functionality is supported
+    for tables, views, sequences and functions and can done by using
+    ALL {TABLES|VIEWS|SEQUENCES|FUNCTIONS} IN schemaname syntax in place
+    of object name.
+   </para>
+ 
+   <para>
     The possible privileges are:
  
     <variablelist>
diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml
index 8d62580..ac0905f 100644
*** a/doc/src/sgml/ref/revoke.sgml
--- b/doc/src/sgml/ref/revoke.sgml
*************** PostgreSQL documentation
*** 24,44 ****
  REVOKE [ GRANT OPTION FOR ]
      { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
      [,...] | ALL [ PRIVILEGES ] }
!     ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, 
...]
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
  REVOKE [ GRANT OPTION FOR ]
      { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] )
      [,...] | ALL [ PRIVILEGES ] ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] ) }
!     ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, 
...]
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
  REVOKE [ GRANT OPTION FOR ]
      { { USAGE | SELECT | UPDATE }
      [,...] | ALL [ PRIVILEGES ] }
!     ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, 
...]
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
--- 24,46 ----
  REVOKE [ GRANT OPTION FOR ]
      { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
      [,...] | ALL [ PRIVILEGES ] }
!     ON { { [ TABLE | VIEW ] <replaceable 
class="PARAMETER">tablename</replaceable> [, ...] }
!     | ALL [ TABLES | VIEWS ] IN <replaceable>schemaname</replaceable> [, ...] 
}
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
  REVOKE [ GRANT OPTION FOR ]
      { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] )
      [,...] | ALL [ PRIVILEGES ] ( <replaceable 
class="PARAMETER">column</replaceable> [, ...] ) }
!     ON [ TABLE | VIEW ] <replaceable 
class="PARAMETER">tablename</replaceable> [, ...]
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
  REVOKE [ GRANT OPTION FOR ]
      { { USAGE | SELECT | UPDATE }
      [,...] | ALL [ PRIVILEGES ] }
!     ON { SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> 
[, ...]
!     | ALL SEQUENCES IN <replaceable>schemaname</replaceable> [, ...] }
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
*************** REVOKE [ GRANT OPTION FOR ]
*** 62,68 ****
  
  REVOKE [ GRANT OPTION FOR ]
      { EXECUTE | ALL [ PRIVILEGES ] }
!     ON FUNCTION <replaceable>funcname</replaceable> ( [ [ <replaceable 
class="parameter">argmode</replaceable> ] [ <replaceable 
class="parameter">argname</replaceable> ] <replaceable 
class="parameter">argtype</replaceable> [, ...] ] ) [, ...]
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
--- 64,71 ----
  
  REVOKE [ GRANT OPTION FOR ]
      { EXECUTE | ALL [ PRIVILEGES ] }
!     ON { FUNCTION <replaceable>funcname</replaceable> ( [ [ <replaceable 
class="parameter">argmode</replaceable> ] [ <replaceable 
class="parameter">argname</replaceable> ] <replaceable 
class="parameter">argtype</replaceable> [, ...] ] ) [, ...]
!     | ALL FUNCTIONS IN <replaceable>schemaname</replaceable> [, ...] }
      FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | 
PUBLIC } [, ...]
      [ CASCADE | RESTRICT ]
  
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index ec4aaf0..0bf4eb1 100644
*** a/src/backend/catalog/aclchk.c
--- b/src/backend/catalog/aclchk.c
*************** static void ExecGrant_Namespace(Internal
*** 61,66 ****
--- 61,68 ----
  static void ExecGrant_Tablespace(InternalGrant *grantStmt);
  
  static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
+ static List *getNamespacesObjectsOids(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,
*************** ExecuteGrantStmt(GrantStmt *stmt)
*** 286,292 ****
         */
        istmt.is_grant = stmt->is_grant;
        istmt.objtype = stmt->objtype;
!       istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
        /* all_privs to be filled below */
        /* privileges to be filled below */
        istmt.col_privs = NIL;          /* may get filled below */
--- 288,297 ----
         */
        istmt.is_grant = stmt->is_grant;
        istmt.objtype = stmt->objtype;
!       if (stmt->is_schema)
!               istmt.objects = getNamespacesObjectsOids(stmt->objtype, 
stmt->objects);
!       else
!               istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
        /* all_privs to be filled below */
        /* privileges to be filled below */
        istmt.col_privs = NIL;          /* may get filled below */
*************** ExecuteGrantStmt(GrantStmt *stmt)
*** 325,330 ****
--- 330,336 ----
                         * the object type.
                         */
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_VIEW:
                        all_privileges = ACL_ALL_RIGHTS_RELATION | 
ACL_ALL_RIGHTS_SEQUENCE;
                        errormsg = gettext_noop("invalid privilege type %s for 
relation");
                        break;
*************** ExecuteGrantStmt(GrantStmt *stmt)
*** 394,400 ****
                         */
                        if (privnode->cols)
                        {
!                               if (stmt->objtype != ACL_OBJECT_RELATION)
                                        ereport(ERROR,
                                                        
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
                                                         errmsg("column 
privileges are only valid for relations")));
--- 400,406 ----
                         */
                        if (privnode->cols)
                        {
!                               if (stmt->objtype != ACL_OBJECT_RELATION && 
stmt->objtype != ACL_OBJECT_VIEW)
                                        ereport(ERROR,
                                                        
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
                                                         errmsg("column 
privileges are only valid for relations")));
*************** ExecGrantStmt_oids(InternalGrant *istmt)
*** 431,436 ****
--- 437,443 ----
        switch (istmt->objtype)
        {
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_VIEW:
                case ACL_OBJECT_SEQUENCE:
                        ExecGrant_Relation(istmt);
                        break;
*************** objectNamesToOids(GrantObjectType objtyp
*** 477,482 ****
--- 484,490 ----
        switch (objtype)
        {
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_VIEW:
                case ACL_OBJECT_SEQUENCE:
                        foreach(cell, objnames)
                        {
*************** objectNamesToOids(GrantObjectType objtyp
*** 609,614 ****
--- 617,756 ----
        return objects;
  }
  
+ 
+ /*
+  * getNamespacesObjectsOids
+  *
+  * Get all objects of a given type from specified schema list into an Oid 
list.
+  */
+ static List *
+ getNamespacesObjectsOids(GrantObjectType objtype, List *nspnames)
+ {
+       List       *objects = NIL;
+       ListCell   *cell;
+       char       *nspname;
+       Oid                     namespaceId;
+ 
+       switch (objtype)
+       {
+               case ACL_OBJECT_RELATION:
+                       foreach(cell, nspnames)
+                       {
+                               List       *relations = NIL;
+ 
+                               nspname = strVal(lfirst(cell));
+                               namespaceId = LookupExplicitNamespace(nspname);
+ 
+                               relations = 
getRelationsInNamespace(namespaceId, RELKIND_RELATION);
+ 
+                               objects = list_concat(objects, relations);
+                       }
+                       break;
+               case ACL_OBJECT_VIEW:
+                       foreach(cell, nspnames)
+                       {
+                               List       *relations = NIL;
+ 
+                               nspname = strVal(lfirst(cell));
+                               namespaceId = LookupExplicitNamespace(nspname);
+ 
+                               relations = 
getRelationsInNamespace(namespaceId, RELKIND_VIEW);
+ 
+                               objects = list_concat(objects, relations);
+                       }
+                       break;
+               case ACL_OBJECT_SEQUENCE:
+                       foreach(cell, nspnames)
+                       {
+                               List       *relations = NIL;
+ 
+                               nspname = strVal(lfirst(cell));
+                               namespaceId = LookupExplicitNamespace(nspname);
+ 
+                               relations = 
getRelationsInNamespace(namespaceId, RELKIND_SEQUENCE);
+ 
+                               objects = list_concat(objects, relations);
+                       }
+                       break;
+               case ACL_OBJECT_FUNCTION:
+                       foreach(cell, nspnames)
+                       {
+                               ScanKeyData key[1];
+                               HeapScanDesc scan;
+                               HeapTuple       tuple;
+                               Relation        rel;
+ 
+                               nspname = strVal(lfirst(cell));
+                               namespaceId = LookupExplicitNamespace(nspname);
+ 
+                               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:
+                       elog(ERROR, "unrecognized GrantStmt.objtype: %d",
+                                (int) objtype);
+       }
+ 
+       return objects;
+ }
+                       
+ /*
+  * getRelationsInNamespace
+  *
+  * Return list of relations in given namespace filtered by relation kind
+  */
+ static List *
+ getRelationsInNamespace(Oid namespaceId, char relkind)
+ {
+       List       *relations = NIL;
+       ScanKeyData key[2];
+       HeapScanDesc scan;
+       HeapTuple       tuple;
+       Relation        rel;
+ 
+       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;
+ }
+ 
+ 
  /*
   * expand_col_privileges
   *
*************** ExecGrant_Relation(InternalGrant *istmt)
*** 912,918 ****
                 * permissions.  The OR of table and sequence permissions were 
already
                 * checked.
                 */
!               if (istmt->objtype == ACL_OBJECT_RELATION)
                {
                        if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
                        {
--- 1054,1060 ----
                 * permissions.  The OR of table and sequence permissions were 
already
                 * checked.
                 */
!               if (istmt->objtype == ACL_OBJECT_RELATION || istmt->objtype == 
ACL_OBJECT_VIEW)
                {
                        if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
                        {
*************** ExecGrant_Relation(InternalGrant *istmt)
*** 986,996 ****
                aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
                                                                   &isNull);
                if (isNull)
!                       old_acl = acldefault(pg_class_tuple->relkind == 
RELKIND_SEQUENCE ?
!                                                                
ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
!                                                                ownerId);
                else
                        old_acl = DatumGetAclPCopy(aclDatum);
  
                /* Need an extra copy of original rel ACL for column handling */
                old_rel_acl = aclcopy(old_acl);
--- 1128,1150 ----
                aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
                                                                   &isNull);
                if (isNull)
!               {
!                       switch (pg_class_tuple->relkind)
!                       {
!                               case RELKIND_SEQUENCE:
!                                       old_acl = 
acldefault(ACL_OBJECT_SEQUENCE, ownerId);
!                                       break;
!                               case RELKIND_VIEW:
!                                       old_acl = acldefault(ACL_OBJECT_VIEW, 
ownerId);
!                                       break;
!                               default:
!                                       old_acl = 
acldefault(ACL_OBJECT_RELATION, ownerId);
!                       }
!               }
                else
+               {
                        old_acl = DatumGetAclPCopy(aclDatum);
+               }
  
                /* Need an extra copy of original rel ACL for column handling */
                old_rel_acl = aclcopy(old_acl);
*************** pg_class_aclmask(Oid table_oid, Oid role
*** 2434,2442 ****
        if (isNull)
        {
                /* No ACL, so build default ACL */
!               acl = acldefault(classForm->relkind == RELKIND_SEQUENCE ?
!                                                ACL_OBJECT_SEQUENCE : 
ACL_OBJECT_RELATION,
!                                                ownerId);
                aclDatum = (Datum) 0;
        }
        else
--- 2588,2604 ----
        if (isNull)
        {
                /* No ACL, so build default ACL */
!               switch (classForm->relkind)
!               {
!                       case RELKIND_SEQUENCE:
!                               acl = acldefault(ACL_OBJECT_SEQUENCE, ownerId);
!                               break;
!                       case RELKIND_VIEW:
!                               acl = acldefault(ACL_OBJECT_VIEW, ownerId);
!                               break;
!                       default:
!                               acl = acldefault(ACL_OBJECT_RELATION, ownerId);
!               }
                aclDatum = (Datum) 0;
        }
        else
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 1976648..ac2bd64 100644
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
*************** _copyGrantStmt(GrantStmt *from)
*** 2297,2302 ****
--- 2297,2303 ----
  
        COPY_SCALAR_FIELD(is_grant);
        COPY_SCALAR_FIELD(objtype);
+       COPY_SCALAR_FIELD(is_schema);
        COPY_NODE_FIELD(objects);
        COPY_NODE_FIELD(privileges);
        COPY_NODE_FIELD(grantees);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 8b466f4..0834199 100644
*** a/src/backend/nodes/equalfuncs.c
--- b/src/backend/nodes/equalfuncs.c
*************** _equalGrantStmt(GrantStmt *a, GrantStmt 
*** 979,984 ****
--- 979,985 ----
  {
        COMPARE_SCALAR_FIELD(is_grant);
        COMPARE_SCALAR_FIELD(objtype);
+       COMPARE_SCALAR_FIELD(is_schema);
        COMPARE_NODE_FIELD(objects);
        COMPARE_NODE_FIELD(privileges);
        COMPARE_NODE_FIELD(grantees);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 858e16c..c3617e7 100644
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 96,101 ****
--- 96,102 ----
  typedef struct PrivTarget
  {
        GrantObjectType objtype;
+       bool            is_schema;
        List       *objs;
  } PrivTarget;
  
*************** static TypeName *TableFuncTypeName(List 
*** 465,471 ****
        EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
  
        FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD
!       FREEZE FROM FULL FUNCTION
  
        GLOBAL GRANT GRANTED GREATEST GROUP_P
  
--- 466,472 ----
        EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
  
        FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD
!       FREEZE FROM FULL FUNCTION FUNCTIONS
  
        GLOBAL GRANT GRANTED GREATEST GROUP_P
  
*************** static TypeName *TableFuncTypeName(List 
*** 503,515 ****
        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
        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
        TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
        TRUNCATE TRUSTED TYPE_P
  
--- 504,516 ----
        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 
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 TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME 
TIMESTAMP
        TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
        TRUNCATE TRUSTED TYPE_P
  
*************** static TypeName *TableFuncTypeName(List 
*** 517,523 ****
        UPDATE USER USING
  
        VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
!       VERBOSE VERSION_P VIEW VOLATILE
  
        WHEN WHERE WHITESPACE_P WINDOW WITH WITHOUT WORK WRAPPER WRITE
  
--- 518,524 ----
        UPDATE USER USING
  
        VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
!       VERBOSE VERSION_P VIEW VIEWS VOLATILE
  
        WHEN WHERE WHITESPACE_P WINDOW WITH WITHOUT WORK WRAPPER WRITE
  
*************** GrantStmt:      GRANT privileges ON privilege
*** 4233,4238 ****
--- 4234,4240 ----
                                        n->is_grant = true;
                                        n->privileges = $2;
                                        n->objtype = ($4)->objtype;
+                                       n->is_schema = ($4)->is_schema;
                                        n->objects = ($4)->objs;
                                        n->grantees = $6;
                                        n->grant_option = $7;
*************** RevokeStmt:
*** 4249,4254 ****
--- 4251,4257 ----
                                        n->grant_option = false;
                                        n->privileges = $2;
                                        n->objtype = ($4)->objtype;
+                                       n->is_schema = ($4)->is_schema;
                                        n->objects = ($4)->objs;
                                        n->grantees = $6;
                                        n->behavior = $7;
*************** RevokeStmt:
*** 4262,4267 ****
--- 4265,4271 ----
                                        n->grant_option = true;
                                        n->privileges = $5;
                                        n->objtype = ($7)->objtype;
+                                       n->is_schema = ($7)->is_schema;
                                        n->objects = ($7)->objs;
                                        n->grantees = $9;
                                        n->behavior = $10;
*************** privilege_target:
*** 4344,4349 ****
--- 4348,4354 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_RELATION;
+                                       n->is_schema = FALSE;
                                        n->objs = $1;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4351,4356 ****
--- 4356,4370 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_RELATION;
+                                       n->is_schema = FALSE;
+                                       n->objs = $2;
+                                       $$ = n;
+                               }
+                       | VIEW qualified_name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
+                                       n->objtype = ACL_OBJECT_VIEW;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4358,4363 ****
--- 4372,4378 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_SEQUENCE;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4365,4370 ****
--- 4380,4386 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_FDW;
+                                       n->is_schema = FALSE;
                                        n->objs = $4;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4372,4377 ****
--- 4388,4394 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_FOREIGN_SERVER;
+                                       n->is_schema = FALSE;
                                        n->objs = $3;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4379,4384 ****
--- 4396,4402 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_FUNCTION;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4386,4391 ****
--- 4404,4410 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_DATABASE;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4393,4398 ****
--- 4412,4418 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_LANGUAGE;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4400,4405 ****
--- 4420,4426 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_NAMESPACE;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
*************** privilege_target:
*** 4407,4415 ****
--- 4428,4469 ----
                                {
                                        PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
                                        n->objtype = ACL_OBJECT_TABLESPACE;
+                                       n->is_schema = FALSE;
                                        n->objs = $2;
                                        $$ = n;
                                }
+                       | ALL TABLES IN_P name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
+                                       n->objtype = ACL_OBJECT_RELATION;
+                                       n->is_schema = TRUE;
+                                       n->objs = $4;
+                                       $$ = n;
+                               }
+                       | ALL VIEWS IN_P name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
+                                       n->objtype = ACL_OBJECT_VIEW;
+                                       n->is_schema = TRUE;
+                                       n->objs = $4;
+                                       $$ = n;
+                               }
+                       | ALL SEQUENCES IN_P name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
+                                       n->objtype = ACL_OBJECT_SEQUENCE;
+                                       n->is_schema = TRUE;
+                                       n->objs = $4;
+                                       $$ = n;
+                               }
+                       | ALL FUNCTIONS IN_P name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) 
palloc(sizeof(PrivTarget));
+                                       n->objtype = ACL_OBJECT_FUNCTION;
+                                       n->is_schema = TRUE;
+                                       n->objs = $4;
+                                       $$ = n;
+                               }
                ;
  
  
*************** unreserved_keyword:
*** 10228,10233 ****
--- 10282,10288 ----
                        | FORCE
                        | FORWARD
                        | FUNCTION
+                       | FUNCTIONS
                        | GLOBAL
                        | GRANTED
                        | HANDLER
*************** unreserved_keyword:
*** 10337,10342 ****
--- 10392,10398 ----
                        | SECOND_P
                        | SECURITY
                        | SEQUENCE
+                       | SEQUENCES
                        | SERIALIZABLE
                        | SERVER
                        | SESSION
*************** unreserved_keyword:
*** 10357,10362 ****
--- 10413,10419 ----
                        | SUPERUSER_P
                        | SYSID
                        | SYSTEM_P
+                       | TABLES
                        | TABLESPACE
                        | TEMP
                        | TEMPLATE
*************** unreserved_keyword:
*** 10381,10386 ****
--- 10438,10444 ----
                        | VARYING
                        | VERSION_P
                        | VIEW
+                       | VIEWS
                        | VOLATILE
                        | WHITESPACE_P
                        | WITHOUT
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 334823b..ddd92e7 100644
*** a/src/backend/utils/adt/acl.c
--- b/src/backend/utils/adt/acl.c
*************** acldefault(GrantObjectType objtype, Oid 
*** 609,614 ****
--- 609,615 ----
                        owner_default = ACL_NO_RIGHTS;
                        break;
                case ACL_OBJECT_RELATION:
+               case ACL_OBJECT_VIEW:
                        world_default = ACL_NO_RIGHTS;
                        owner_default = ACL_ALL_RIGHTS_RELATION;
                        break;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9d53ab9..eab50c3 100644
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
*************** typedef struct AlterDomainStmt
*** 1180,1186 ****
  typedef enum GrantObjectType
  {
        ACL_OBJECT_COLUMN,                      /* column */
!       ACL_OBJECT_RELATION,            /* table, view */
        ACL_OBJECT_SEQUENCE,            /* sequence */
        ACL_OBJECT_DATABASE,            /* database */
        ACL_OBJECT_FDW,                         /* foreign-data wrapper */
--- 1180,1186 ----
  typedef enum GrantObjectType
  {
        ACL_OBJECT_COLUMN,                      /* column */
!       ACL_OBJECT_RELATION,            /* table */
        ACL_OBJECT_SEQUENCE,            /* sequence */
        ACL_OBJECT_DATABASE,            /* database */
        ACL_OBJECT_FDW,                         /* foreign-data wrapper */
*************** typedef enum GrantObjectType
*** 1188,1194 ****
        ACL_OBJECT_FUNCTION,            /* function */
        ACL_OBJECT_LANGUAGE,            /* procedural language */
        ACL_OBJECT_NAMESPACE,           /* namespace */
!       ACL_OBJECT_TABLESPACE           /* tablespace */
  } GrantObjectType;
  
  typedef struct GrantStmt
--- 1188,1195 ----
        ACL_OBJECT_FUNCTION,            /* function */
        ACL_OBJECT_LANGUAGE,            /* procedural language */
        ACL_OBJECT_NAMESPACE,           /* namespace */
!       ACL_OBJECT_TABLESPACE,          /* tablespace */
!       ACL_OBJECT_VIEW,                        /* view */
  } GrantObjectType;
  
  typedef struct GrantStmt
*************** typedef struct GrantStmt
*** 1196,1201 ****
--- 1197,1204 ----
        NodeTag         type;
        bool            is_grant;               /* true = GRANT, false = REVOKE 
*/
        GrantObjectType objtype;        /* kind of object being operated on */
+       bool            is_schema;              /* if true we want all objects 
+                                                                * of objtype 
in schema */
        List       *objects;            /* list of RangeVar nodes, FuncWithArgs 
nodes,
                                                                 * or plain 
names (as Value strings) */
        List       *privileges;         /* list of AccessPriv nodes */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 67e9cb4..a6ae56c 100644
*** a/src/include/parser/kwlist.h
--- b/src/include/parser/kwlist.h
*************** PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_N
*** 163,168 ****
--- 163,169 ----
  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)
*************** PG_KEYWORD("second", SECOND_P, UNRESERVE
*** 328,333 ****
--- 329,335 ----
  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)
*************** PG_KEYWORD("symmetric", SYMMETRIC, RESER
*** 356,361 ****
--- 358,364 ----
  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)
*************** PG_KEYWORD("varying", VARYING, UNRESERVE
*** 396,401 ****
--- 399,405 ----
  PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD)
  PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD)
  PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD)
+ PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD)
  PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD)
  PG_KEYWORD("when", WHEN, RESERVED_KEYWORD)
  PG_KEYWORD("where", WHERE, RESERVED_KEYWORD)
diff --git a/src/test/regress/expected/privileges.out 
b/src/test/regress/expected/privileges.out
index a17ff59..043c0f3 100644
*** a/src/test/regress/expected/privileges.out
--- b/src/test/regress/expected/privileges.out
*************** SELECT has_table_privilege('regressuser1
*** 815,820 ****
--- 815,849 ----
   t
  (1 row)
  
+ -- Grant on all objects of given type in a schema
+ RESET SESSION AUTHORIZATION;
+ REVOKE ALL ON ALL TABLES IN public FROM regressuser1;
+ SELECT has_table_privilege('regressuser1', 'atest1', 'SELECT'); -- false
+  has_table_privilege
+ ---------------------
+  f
+ (1 row)
+ 
+ REVOKE ALL ON ALL FUNCTIONS IN public FROM regressuser1;
+ SET SESSION AUTHORIZATION regressuser1;
+ SELECT testfunc2(5); -- fail
+ ERROR:  permission denied for function testfunc2
+ RESET SESSION AUTHORIZATION;
+ GRANT ALL ON ALL TABLES IN public TO regressuser1;
+ SELECT has_table_privilege('regressuser1', 'atest2', 'SELECT'); -- true
+  has_table_privilege
+ ---------------------
+  t
+ (1 row)
+ 
+ GRANT ALL ON ALL FUNCTIONS IN public TO regressuser1;
+ SET SESSION AUTHORIZATION regressuser1;
+ SELECT testfunc2(5); -- ok
+  testfunc2
+ -----------
+         15
+ (1 row)
+ 
  -- clean up
  \c
  DROP FUNCTION testfunc2(int);
*************** DROP TABLE atestp2;
*** 839,844 ****
--- 868,875 ----
  DROP GROUP regressgroup1;
  DROP GROUP regressgroup2;
  REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
+ REVOKE ALL ON ALL TABLES IN public FROM regressuser1;
+ REVOKE ALL ON ALL FUNCTIONS IN public FROM regressuser1;
  DROP USER regressuser1;
  DROP USER regressuser2;
  DROP USER regressuser3;
diff --git a/src/test/regress/sql/privileges.sql 
b/src/test/regress/sql/privileges.sql
index 5aa1012..e574c4d 100644
*** a/src/test/regress/sql/privileges.sql
--- b/src/test/regress/sql/privileges.sql
*************** SELECT has_table_privilege('regressuser3
*** 469,474 ****
--- 469,500 ----
  SELECT has_table_privilege('regressuser1', 'atest4', 'SELECT WITH GRANT 
OPTION'); -- true
  
  
+ -- Grant on all objects of given type in a schema
+ 
+ RESET SESSION AUTHORIZATION;
+ 
+ REVOKE ALL ON ALL TABLES IN public FROM regressuser1;
+ 
+ SELECT has_table_privilege('regressuser1', 'atest1', 'SELECT'); -- false
+ 
+ REVOKE ALL ON ALL FUNCTIONS IN public FROM regressuser1;
+ 
+ SET SESSION AUTHORIZATION regressuser1;
+ 
+ SELECT testfunc2(5); -- fail
+ 
+ RESET SESSION AUTHORIZATION;
+ 
+ GRANT ALL ON ALL TABLES IN public TO regressuser1;
+ 
+ SELECT has_table_privilege('regressuser1', 'atest2', 'SELECT'); -- true
+ 
+ GRANT ALL ON ALL FUNCTIONS IN public TO regressuser1;
+ 
+ SET SESSION AUTHORIZATION regressuser1;
+ 
+ SELECT testfunc2(5); -- ok
+ 
  -- clean up
  
  \c
*************** DROP GROUP regressgroup1;
*** 497,502 ****
--- 523,530 ----
  DROP GROUP regressgroup2;
  
  REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
+ REVOKE ALL ON ALL TABLES IN public FROM regressuser1;
+ REVOKE ALL ON ALL FUNCTIONS IN public FROM regressuser1;
  DROP USER regressuser1;
  DROP USER regressuser2;
  DROP USER regressuser3;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to