This is an automated email from the ASF dual-hosted git repository.

ztao1987 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hawq.git


The following commit(s) were added to refs/heads/master by this push:
     new 30270d692 HAWQ-1854. Support GRANT/REVOKE ON ALL 
TABLES/SEQUENCES/FUNCTIONS IN SCHEMA
30270d692 is described below

commit 30270d69274611fd2a7c3c0367acb5cc8cc6c461
Author: ztao1987 <zhenglin.ta...@gmail.com>
AuthorDate: Sun Jan 22 21:32:29 2023 +0800

    HAWQ-1854. Support GRANT/REVOKE ON ALL TABLES/SEQUENCES/FUNCTIONS IN SCHEMA
---
 doc/src/sgml/ref/revoke.sgml   |   9 ++-
 src/backend/catalog/aclchk.c   | 124 ++++++++++++++++++++++++++++++++++++++++-
 src/backend/nodes/copyfuncs.c  |   1 +
 src/backend/nodes/equalfuncs.c |   1 +
 src/backend/parser/gram.y      |  48 ++++++++++++++--
 src/include/nodes/parsenodes.h |   9 +++
 src/include/parser/kwlist.h    |   3 +
 7 files changed, 187 insertions(+), 8 deletions(-)

diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml
index e5fe81142..cb7d79697 100755
--- a/doc/src/sgml/ref/revoke.sgml
+++ b/doc/src/sgml/ref/revoke.sgml
@@ -23,14 +23,16 @@ PostgreSQL documentation
 REVOKE [ GRANT OPTION FOR ]
     { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRUNCATE }
     [,...] | ALL [ PRIVILEGES ] }
-    ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
+    ON { [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, 
...]
+         | ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] 
}
     FROM { <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, 
...]
     [ CASCADE | RESTRICT ]
 
 REVOKE [ GRANT OPTION FOR ]
     { { USAGE | SELECT | UPDATE }
     [,...] | ALL [ PRIVILEGES ] }
-    ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, 
...]
+    ON { SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> 
[, ...]
+         | ALL SEQUENCES IN SCHEMA <replaceable>schema_name</replaceable> [, 
...] }
     FROM { <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, 
...]
     [ CASCADE | RESTRICT ]
 
@@ -42,7 +44,8 @@ REVOKE [ GRANT OPTION FOR ]
 
 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> [, ...] ] ) [, ...]
+    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 { <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, 
...]
     [ CASCADE | RESTRICT ]
 
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 062b624c2..4401ef22d 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -75,6 +75,8 @@ static void ExecGrant_Tablespace(InternalGrant *grantStmt);
 static void ExecGrant_ExtProtocol(InternalGrant *grantstmt);
 
 static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
+static List *objectsInSchemaToOids(GrantObjectType objtype, List *nspnames);
+static List *getRelationsInNamespace(Oid namespaceId, char relkind);
 static AclMode string_to_privilege(const char *privname);
 static const char *privilege_to_string(AclMode privilege);
 static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
@@ -335,7 +337,21 @@ 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);
+       }
 
        /*
         * Don't allow GRANT/REVOKE for objects managed by Ranger
@@ -838,6 +854,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, NSPDBOID_CURRENT);
+
+    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;
+}
+
+
 /*
  *     This processes both sequences and non-sequences.
  */
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index a83966fbc..a466507bb 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2912,6 +2912,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);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 55470c925..de3524edb 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -973,6 +973,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);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 10cf3196f..2c24a5d31 100755
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -523,7 +523,7 @@ static Node *makeIsNotDistinctFromNode(Node *expr, int 
position);
        EXCHANGE EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL 
EXTRACT EDGE
 
        FALSE_P FETCH FIELDS FILESPACE FILESYSTEM FILL FILTER FIRST_P FLOAT_P 
FOLLOWING FOR 
-       FORCE FOREIGN FORMAT FORMATTER FORWARD FREEZE FROM FULL FUNCTION
+       FORCE FOREIGN FORMAT FORMATTER FORWARD FREEZE FROM FULL FUNCTION 
FUNCTIONS
 
        GB GLOBAL GRANT GRANTED GREATEST GROUP_P GROUP_ID GROUPING GRAPH
 
@@ -567,7 +567,7 @@ static Node *makeIsNotDistinctFromNode(Node *expr, int 
position);
        ROLE ROLLBACK ROLLUP ROOTPARTITION ROW ROWS RULE
 
        SAVEPOINT SCATTER SCHEMA SCROLL SEARCH SECOND_P 
-    SECURITY SEGMENT SELECT SEQUENCE
+    SECURITY SEGMENT SELECT SEQUENCE SEQUENCES
        SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SETS SHARE
        SHOW SIMILAR SIMPLE SMALLINT SOME SPLIT SQL STABLE START STATEMENT
        STATISTICS STDIN STDOUT STORAGE STRICT_P 
@@ -575,7 +575,7 @@ static Node *makeIsNotDistinctFromNode(Node *expr, int 
position);
        SUBSTRING SUPERUSER_P SYMMETRIC
        SYSID SYSTEM_P
 
-       TABLE TABLESPACE TB TEMP TEMPLATE TEMPORARY THEN THRESHOLD TIES TIME 
TIMESTAMP
+       TABLE  TABLES TABLESPACE TB TEMP TEMPLATE TEMPORARY THEN THRESHOLD TIES 
TIME TIMESTAMP
        TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
        TRUNCATE TRUSTED TYPE_P
 
@@ -6839,6 +6839,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;
@@ -6855,6 +6856,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;
@@ -6868,6 +6870,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;
@@ -6915,6 +6918,7 @@ privilege_target:
                        qualified_name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_RELATION;
                                        n->objs = $1;
                                        $$ = n;
@@ -6922,6 +6926,7 @@ privilege_target:
                        | TABLE qualified_name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_RELATION;
                                        n->objs = $2;
                                        $$ = n;
@@ -6929,6 +6934,7 @@ privilege_target:
                        | SEQUENCE qualified_name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_SEQUENCE;
                                        n->objs = $2;
                                        $$ = n;
@@ -6936,6 +6942,7 @@ privilege_target:
                        | FOREIGN DATA_P WRAPPER name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FDW;
                                        n->objs = $4;
                                        $$ = n;
@@ -6943,6 +6950,7 @@ privilege_target:
                        | FOREIGN SERVER name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FOREIGN_SERVER;
                                        n->objs = $3;
                                        $$ = n;
@@ -6950,6 +6958,7 @@ privilege_target:
                        | FUNCTION function_with_argtypes_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FUNCTION;
                                        n->objs = $2;
                                        $$ = n;
@@ -6957,6 +6966,7 @@ privilege_target:
                        | DATABASE name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_DATABASE;
                                        n->objs = $2;
                                        $$ = n;
@@ -6964,6 +6974,7 @@ privilege_target:
                        | LANGUAGE name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_LANGUAGE;
                                        n->objs = $2;
                                        $$ = n;
@@ -6971,6 +6982,7 @@ privilege_target:
                        | SCHEMA name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_NAMESPACE;
                                        n->objs = $2;
                                        $$ = n;
@@ -6978,6 +6990,7 @@ privilege_target:
                        | TABLESPACE name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_TABLESPACE;
                                        n->objs = $2;
                                        $$ = n;
@@ -6988,7 +7001,31 @@ privilege_target:
                                        n->objtype = ACL_OBJECT_EXTPROTOCOL;
                                        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;
+                               }
                ;
 
 
@@ -13030,6 +13067,7 @@ unreserved_keyword:
                        | FORMATTER
                        | FORWARD
                        | FUNCTION
+                       | FUNCTIONS
                        | GB
                        | GLOBAL
                        | GRANTED
@@ -13166,6 +13204,7 @@ unreserved_keyword:
                        | SECURITY
                        | SEGMENT
                        | SEQUENCE
+                       | SEQUENCES
                        | SERIALIZABLE
                        | SESSION
                        | SET
@@ -13187,6 +13226,7 @@ unreserved_keyword:
                        | SUPERUSER_P
                        | SYSID
                        | SYSTEM_P
+                       | TABLES
                        | TABLESPACE
                        | TB
                        | TEMP
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 897472fed..164eafeb1 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1254,6 +1254,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_RELATION,       /* table, view */
   ACL_OBJECT_SEQUENCE,       /* sequence */
@@ -1271,6 +1278,7 @@ typedef enum GrantObjectType {
 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) */
@@ -1301,6 +1309,7 @@ typedef struct FuncWithArgs {
 /* This is only used internally in gram.y. */
 typedef struct PrivTarget {
   NodeTag type;
+  GrantTargetType targtype;
   GrantObjectType objtype;
   List *objs;
 } PrivTarget;
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 8f0798469..d8f8f2452 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -185,6 +185,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("gb", GB, UNRESERVED_KEYWORD)
 PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD)
 PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD)
@@ -394,6 +395,7 @@ PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD)
 PG_KEYWORD("segment", SEGMENT, 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)
@@ -427,6 +429,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("tb", TB, UNRESERVED_KEYWORD)
 PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD)

Reply via email to