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

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


The following commit(s) were added to refs/heads/master by this push:
     new db8d18eb40 [Enhance](auth)row policy support role (#23022)
db8d18eb40 is described below

commit db8d18eb40d152f342754c9e3da6a0679d7399dc
Author: zhangdong <493738...@qq.com>
AuthorDate: Sat Aug 26 10:24:59 2023 +0800

    [Enhance](auth)row policy support role (#23022)
    
    ```
    CREATE ROW POLICY test_row_policy_1 ON test.table1
    AS {RESTRICTIVE|PERMISSIVE} [TO  user] [TO ROLE role] USING (id in (1, 2)); 
// add `to role`
    
    DROP [ROW] POLICY [IF EXISTS] test_row_policy;//delete `for user` and `on 
table`
    
    SHOW ROW POLICY [FOR user][FOR ROLE role] // add `for role`
    ```
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   2 +-
 fe/fe-core/src/main/cup/sql_parser.cup             |  27 ++-
 .../apache/doris/analysis/CreatePolicyStmt.java    |  26 ++-
 .../org/apache/doris/analysis/DropPolicyStmt.java  |  28 +--
 .../org/apache/doris/analysis/ShowPolicyStmt.java  |  12 +-
 .../org/apache/doris/analysis/StmtRewriter.java    |   7 +-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |   4 +-
 .../trees/plans/commands/CreatePolicyCommand.java  |   4 +-
 .../trees/plans/logical/LogicalCheckPolicy.java    |   6 +-
 .../org/apache/doris/policy/DropPolicyLog.java     |  30 +--
 .../main/java/org/apache/doris/policy/Policy.java  |  11 +-
 .../java/org/apache/doris/policy/PolicyMgr.java    | 221 ++++++++++-----------
 .../java/org/apache/doris/policy/RowPolicy.java    |  49 ++---
 .../nereids/rules/analysis/CheckRowPolicyTest.java |   5 +-
 .../java/org/apache/doris/policy/PolicyTest.java   | 148 ++++++++++----
 .../account_p0/test_nereids_row_policy.groovy      |   2 +-
 16 files changed, 310 insertions(+), 272 deletions(-)

diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index 2b014d3610..cd178cd220 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -38,7 +38,7 @@ statement
     | CREATE ROW POLICY (IF NOT EXISTS)? name=identifier
         ON table=multipartIdentifier
         AS type=(RESTRICTIVE | PERMISSIVE)
-        TO user=userIdentify
+        TO (user=userIdentify | ROLE roleName=identifier)
         USING LEFT_PAREN booleanExpression RIGHT_PAREN                 
#createRowPolicy
     | explain? INSERT INTO tableName=multipartIdentifier
         (PARTITION partition=identifierList)?  // partition define
diff --git a/fe/fe-core/src/main/cup/sql_parser.cup 
b/fe/fe-core/src/main/cup/sql_parser.cup
index c4258b2330..19d4c22037 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -1999,7 +1999,12 @@ create_stmt ::=
     | KW_CREATE KW_ROW KW_POLICY opt_if_not_exists:ifNotExists 
ident:policyName KW_ON table_name:tbl KW_AS ident:filterType KW_TO 
user_identity:user
     KW_USING LPAREN expr:wherePredicate RPAREN
     {:
-        RESULT = new CreatePolicyStmt(PolicyTypeEnum.ROW, ifNotExists, 
policyName, tbl, filterType, user, wherePredicate);
+        RESULT = new CreatePolicyStmt(PolicyTypeEnum.ROW, ifNotExists, 
policyName, tbl, filterType, user, null, wherePredicate);
+    :}
+    | KW_CREATE KW_ROW KW_POLICY opt_if_not_exists:ifNotExists 
ident:policyName KW_ON table_name:tbl KW_AS ident:filterType KW_TO KW_ROLE 
ident:role
+    KW_USING LPAREN expr:wherePredicate RPAREN
+    {:
+        RESULT = new CreatePolicyStmt(PolicyTypeEnum.ROW, ifNotExists, 
policyName, tbl, filterType, null, role, wherePredicate);
     :}
     /* storage policy */
     | KW_CREATE KW_STORAGE KW_POLICY opt_if_not_exists:ifNotExists 
ident:policyName opt_properties:properties
@@ -3133,17 +3138,13 @@ drop_stmt ::=
     {:
         RESULT = new DropSqlBlockRuleStmt(ifExists, ruleNames);
     :}
-    | KW_DROP KW_ROW KW_POLICY opt_if_exists:ifExists ident:policyName KW_ON 
table_name:tbl
+    | KW_DROP KW_ROW KW_POLICY opt_if_exists:ifExists ident:policyName
     {:
-        RESULT = new DropPolicyStmt(PolicyTypeEnum.ROW, ifExists, policyName, 
tbl, null);
-    :}
-    | KW_DROP KW_ROW KW_POLICY opt_if_exists:ifExists ident:policyName KW_ON 
table_name:tbl KW_FOR user_identity:user
-    {:
-        RESULT = new DropPolicyStmt(PolicyTypeEnum.ROW, ifExists, policyName, 
tbl, user);
+        RESULT = new DropPolicyStmt(PolicyTypeEnum.ROW, ifExists, policyName);
     :}
     | KW_DROP KW_STORAGE KW_POLICY opt_if_exists:ifExists ident:policyName
     {:
-        RESULT = new DropPolicyStmt(PolicyTypeEnum.STORAGE, ifExists, 
policyName, null, null);
+        RESULT = new DropPolicyStmt(PolicyTypeEnum.STORAGE, ifExists, 
policyName);
     :}
     /* statistics */
     | KW_DROP KW_STATS table_name:tbl opt_col_list:cols
@@ -3793,15 +3794,19 @@ show_stmt ::=
     :}
     | KW_SHOW KW_ROW KW_POLICY KW_FOR user_identity:user
     {:
-        RESULT = new ShowPolicyStmt(PolicyTypeEnum.ROW, user);
+        RESULT = new ShowPolicyStmt(PolicyTypeEnum.ROW, user, null);
+    :}
+    | KW_SHOW KW_ROW KW_POLICY KW_FOR KW_ROLE STRING_LITERAL:role
+    {:
+        RESULT = new ShowPolicyStmt(PolicyTypeEnum.ROW, null, role);
     :}
     | KW_SHOW KW_ROW KW_POLICY
     {:
-        RESULT = new ShowPolicyStmt(PolicyTypeEnum.ROW, null);
+        RESULT = new ShowPolicyStmt(PolicyTypeEnum.ROW, null, null);
     :}
     | KW_SHOW KW_STORAGE KW_POLICY
     {:
-        RESULT = new ShowPolicyStmt(PolicyTypeEnum.STORAGE, null);
+        RESULT = new ShowPolicyStmt(PolicyTypeEnum.STORAGE, null, null);
     :}
     ;
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java
index 7b38af073c..06430a8bd9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java
@@ -57,6 +57,9 @@ public class CreatePolicyStmt extends DdlStmt {
     @Getter
     private UserIdentity user = null;
 
+    @Getter
+    private String roleName = null;
+
     @Getter
     private Expr wherePredicate;
 
@@ -67,13 +70,14 @@ public class CreatePolicyStmt extends DdlStmt {
      * Use for cup.
      **/
     public CreatePolicyStmt(PolicyTypeEnum type, boolean ifNotExists, String 
policyName, TableName tableName,
-                            String filterType, UserIdentity user, Expr 
wherePredicate) {
+            String filterType, UserIdentity user, String roleName, Expr 
wherePredicate) {
         this.type = type;
         this.ifNotExists = ifNotExists;
         this.policyName = policyName;
         this.tableName = tableName;
         this.filterType = FilterType.of(filterType);
         this.user = user;
+        this.roleName = roleName;
         this.wherePredicate = wherePredicate;
     }
 
@@ -81,7 +85,7 @@ public class CreatePolicyStmt extends DdlStmt {
      * Use for cup.
      */
     public CreatePolicyStmt(PolicyTypeEnum type, boolean ifNotExists, String 
policyName,
-                            Map<String, String> properties) {
+            Map<String, String> properties) {
         this.type = type;
         this.ifNotExists = ifNotExists;
         this.policyName = policyName;
@@ -101,10 +105,12 @@ public class CreatePolicyStmt extends DdlStmt {
             case ROW:
             default:
                 tableName.analyze(analyzer);
-                user.analyze(analyzer.getClusterName());
-                if (user.isRootUser() || user.isAdminUser()) {
-                    
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, 
"CreatePolicyStmt",
-                            user.getQualifiedUser(), user.getHost(), 
tableName.getTbl());
+                if (user != null) {
+                    user.analyze(analyzer.getClusterName());
+                    if (user.isRootUser() || user.isAdminUser()) {
+                        
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, 
"CreatePolicyStmt",
+                                user.getQualifiedUser(), user.getHost(), 
tableName.getTbl());
+                    }
                 }
         }
         // check auth
@@ -128,7 +134,13 @@ public class CreatePolicyStmt extends DdlStmt {
             case ROW:
             default:
                 sb.append(" ON ").append(tableName.toSql()).append(" AS 
").append(filterType)
-                    .append(" TO ").append(user.getQualifiedUser()).append(" 
USING ").append(wherePredicate.toSql());
+                        .append(" TO ");
+                if (user == null) {
+                    sb.append("ROLE ").append(roleName);
+                } else {
+                    sb.append(user.getQualifiedUser());
+                }
+                sb.append(" USING ").append(wherePredicate.toSql());
         }
         return sb.toString();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java
index bd3fb0f375..541206bef0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java
@@ -31,7 +31,7 @@ import lombok.Getter;
 /**
  * Drop policy statement.
  * syntax:
- * DROP [ROW] POLICY [IF EXISTS] test_row_policy ON test_table [FOR user]
+ * DROP [ROW] POLICY [IF EXISTS] test_row_policy
  **/
 @AllArgsConstructor
 public class DropPolicyStmt extends DdlStmt {
@@ -45,25 +45,9 @@ public class DropPolicyStmt extends DdlStmt {
     @Getter
     private final String policyName;
 
-    @Getter
-    private final TableName tableName;
-
-    @Getter
-    private final UserIdentity user;
-
     @Override
     public void analyze(Analyzer analyzer) throws UserException {
         super.analyze(analyzer);
-        switch (type) {
-            case STORAGE:
-                break;
-            case ROW:
-            default:
-                tableName.analyze(analyzer);
-                if (user != null) {
-                    user.analyze(analyzer.getClusterName());
-                }
-        }
         // check auth
         if 
(!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), 
PrivPredicate.ADMIN)) {
             
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"ADMIN");
@@ -78,16 +62,6 @@ public class DropPolicyStmt extends DdlStmt {
             sb.append("IF EXISTS ");
         }
         sb.append(policyName);
-        switch (type) {
-            case STORAGE:
-                break;
-            case ROW:
-            default:
-                sb.append(" ON ").append(tableName.toSql());
-                if (user != null) {
-                    sb.append(" FOR ").append(user.getQualifiedUser());
-                }
-        }
         return sb.toString();
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPolicyStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPolicyStmt.java
index 9cc8ba549f..8da1ea4b43 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPolicyStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPolicyStmt.java
@@ -29,11 +29,12 @@ import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.ShowResultSetMetaData;
 
 import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * Show policy statement
  * syntax:
- * SHOW ROW POLICY [FOR user]
+ * SHOW ROW POLICY [FOR user|ROLE role]
  **/
 public class ShowPolicyStmt extends ShowStmt {
 
@@ -43,9 +44,13 @@ public class ShowPolicyStmt extends ShowStmt {
     @Getter
     private final UserIdentity user;
 
-    public ShowPolicyStmt(PolicyTypeEnum type, UserIdentity user) {
+    @Getter
+    private final String roleName;
+
+    public ShowPolicyStmt(PolicyTypeEnum type, UserIdentity user, String 
roleName) {
         this.type = type;
         this.user = user;
+        this.roleName = roleName;
     }
 
     @Override
@@ -72,6 +77,9 @@ public class ShowPolicyStmt extends ShowStmt {
                 if (user != null) {
                     sb.append(" FOR ").append(user);
                 }
+                if (!StringUtils.isEmpty(roleName)) {
+                    sb.append(" FOR ROLE ").append(roleName);
+                }
         }
         return sb.toString();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/StmtRewriter.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/StmtRewriter.java
index b15db8703f..89c1113bcc 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/StmtRewriter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/StmtRewriter.java
@@ -1293,13 +1293,10 @@ public class StmtRewriter {
     public static boolean rewriteByPolicy(StatementBase statementBase, 
Analyzer analyzer) throws UserException {
         Env currentEnv = Env.getCurrentEnv();
         UserIdentity currentUserIdentity = 
ConnectContext.get().getCurrentUserIdentity();
-        String user = analyzer.getQualifiedUser();
         if (currentUserIdentity.isRootUser() || 
currentUserIdentity.isAdminUser()) {
             return false;
         }
-        if (!currentEnv.getPolicyMgr().existPolicy(user)) {
-            return false;
-        }
+
         if (!(statementBase instanceof SelectStmt)) {
             return false;
         }
@@ -1324,7 +1321,7 @@ public class StmtRewriter {
                     .getDbOrAnalysisException(dbName);
             long dbId = db.getId();
             long tableId = table.getId();
-            RowPolicy matchPolicy = 
currentEnv.getPolicyMgr().getMatchTablePolicy(dbId, tableId, user);
+            RowPolicy matchPolicy = 
currentEnv.getPolicyMgr().getMatchTablePolicy(dbId, tableId, 
currentUserIdentity);
             if (matchPolicy == null) {
                 continue;
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 679e3d457e..f0a270bdb6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -458,7 +458,9 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         FilterType filterType = FilterType.of(ctx.type.getText());
         List<String> nameParts = visitMultipartIdentifier(ctx.table);
         return new CreatePolicyCommand(PolicyTypeEnum.ROW, ctx.name.getText(),
-                ctx.EXISTS() != null, nameParts, Optional.of(filterType), 
visitUserIdentify(ctx.user),
+                ctx.EXISTS() != null, nameParts, Optional.of(filterType),
+                ctx.user == null ? null : visitUserIdentify(ctx.user),
+                ctx.roleName == null ? null : ctx.roleName.getText(),
                 Optional.of(getExpression(ctx.booleanExpression())), 
ImmutableMap.of());
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreatePolicyCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreatePolicyCommand.java
index 8509803589..318d1b5e79 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreatePolicyCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreatePolicyCommand.java
@@ -39,6 +39,7 @@ public class CreatePolicyCommand extends Command implements 
ForwardWithSync {
     private final List<String> nameParts;
     private final Optional<FilterType> filterType;
     private final UserIdentity user;
+    private final String roleName;
     private final Optional<Expression> wherePredicate;
     private final Map<String, String> properties;
 
@@ -46,7 +47,7 @@ public class CreatePolicyCommand extends Command implements 
ForwardWithSync {
      * ctor of this command.
      */
     public CreatePolicyCommand(PolicyTypeEnum policyType, String policyName, 
boolean ifNotExists,
-            List<String> nameParts, Optional<FilterType> filterType, 
UserIdentity user,
+            List<String> nameParts, Optional<FilterType> filterType, 
UserIdentity user, String roleName,
             Optional<Expression> wherePredicate, Map<String, String> 
properties) {
         super(PlanType.CREATE_POLICY_COMMAND);
         this.policyType = policyType;
@@ -55,6 +56,7 @@ public class CreatePolicyCommand extends Command implements 
ForwardWithSync {
         this.nameParts = nameParts;
         this.filterType = filterType;
         this.user = user;
+        this.roleName = roleName;
         this.wherePredicate = wherePredicate;
         this.properties = properties;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCheckPolicy.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCheckPolicy.java
index 78578fa7b5..b9fc7ecfe6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCheckPolicy.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCheckPolicy.java
@@ -125,18 +125,14 @@ public class LogicalCheckPolicy<CHILD_TYPE extends Plan> 
extends LogicalUnary<CH
 
         PolicyMgr policyMgr = connectContext.getEnv().getPolicyMgr();
         UserIdentity currentUserIdentity = 
connectContext.getCurrentUserIdentity();
-        String user = connectContext.getQualifiedUser();
         if (currentUserIdentity.isRootUser() || 
currentUserIdentity.isAdminUser()) {
             return Optional.empty();
         }
-        if (!policyMgr.existPolicy(user)) {
-            return Optional.empty();
-        }
 
         CatalogRelation catalogRelation = (CatalogRelation) logicalRelation;
         long dbId = catalogRelation.getDatabase().getId();
         long tableId = catalogRelation.getTable().getId();
-        List<RowPolicy> policies = policyMgr.getMatchRowPolicy(dbId, tableId, 
currentUserIdentity);
+        List<RowPolicy> policies = policyMgr.getUserPolicies(dbId, tableId, 
currentUserIdentity);
         if (policies.isEmpty()) {
             return Optional.empty();
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/policy/DropPolicyLog.java 
b/fe/fe-core/src/main/java/org/apache/doris/policy/DropPolicyLog.java
index 603dee86ed..7ff18ed413 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/policy/DropPolicyLog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/policy/DropPolicyLog.java
@@ -18,15 +18,10 @@
 package org.apache.doris.policy;
 
 import org.apache.doris.analysis.DropPolicyStmt;
-import org.apache.doris.analysis.UserIdentity;
-import org.apache.doris.catalog.Database;
-import org.apache.doris.catalog.Env;
-import org.apache.doris.catalog.Table;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.io.Text;
 import org.apache.doris.common.io.Writable;
 import org.apache.doris.persist.gson.GsonUtils;
-import org.apache.doris.qe.ConnectContext;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.AllArgsConstructor;
@@ -42,41 +37,18 @@ import java.io.IOException;
 @AllArgsConstructor
 @Getter
 public class DropPolicyLog implements Writable {
-
-    @SerializedName(value = "dbId")
-    private long dbId;
-
-    @SerializedName(value = "tableId")
-    private long tableId;
-
     @SerializedName(value = "type")
     private PolicyTypeEnum type;
 
     @SerializedName(value = "policyName")
     private String policyName;
 
-    @SerializedName(value = "user")
-    private UserIdentity user;
 
     /**
      * Generate delete logs through stmt.
      **/
     public static DropPolicyLog fromDropStmt(DropPolicyStmt stmt) throws 
AnalysisException {
-        switch (stmt.getType()) {
-            case STORAGE:
-                return new DropPolicyLog(-1, -1, stmt.getType(), 
stmt.getPolicyName(), null);
-            case ROW:
-                String curDb = stmt.getTableName().getDb();
-                if (curDb == null) {
-                    curDb = ConnectContext.get().getDatabase();
-                }
-                Database db = 
Env.getCurrentInternalCatalog().getDbOrAnalysisException(curDb);
-                Table table = 
db.getTableOrAnalysisException(stmt.getTableName().getTbl());
-                return new DropPolicyLog(db.getId(), table.getId(), 
stmt.getType(),
-                                         stmt.getPolicyName(), stmt.getUser());
-            default:
-                throw new AnalysisException("Invalid policy type: " + 
stmt.getType().name());
-        }
+        return new DropPolicyLog(stmt.getType(), stmt.getPolicyName());
     }
 
     @Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/policy/Policy.java 
b/fe/fe-core/src/main/java/org/apache/doris/policy/Policy.java
index 8c1231f35d..b06cd19d0c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/policy/Policy.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/policy/Policy.java
@@ -82,7 +82,8 @@ public abstract class Policy implements Writable, 
GsonPostProcessable {
     }
 
     // just for subclass lombok @Data
-    public Policy() {}
+    public Policy() {
+    }
 
     public Policy(PolicyTypeEnum type) {
         this.type = type;
@@ -117,9 +118,11 @@ public abstract class Policy implements Writable, 
GsonPostProcessable {
                         
.getCatalogOrAnalysisException(stmt.getTableName().getCtl())
                         .getDbOrAnalysisException(stmt.getTableName().getDb());
                 UserIdentity userIdent = stmt.getUser();
-                userIdent.analyze(ConnectContext.get().getClusterName());
+                if (userIdent != null) {
+                    userIdent.analyze(ConnectContext.get().getClusterName());
+                }
                 TableIf table = 
db.getTableOrAnalysisException(stmt.getTableName().getTbl());
-                return new RowPolicy(policyId, stmt.getPolicyName(), 
db.getId(), userIdent,
+                return new RowPolicy(policyId, stmt.getPolicyName(), 
db.getId(), userIdent, stmt.getRoleName(),
                         stmt.getOrigStmt().originStmt, table.getId(), 
stmt.getFilterType(), stmt.getWherePredicate());
             default:
                 throw new AnalysisException("Unknown policy type: " + 
stmt.getType());
@@ -149,7 +152,7 @@ public abstract class Policy implements Writable, 
GsonPostProcessable {
 
     protected boolean checkMatched(PolicyTypeEnum type, String policyName) {
         return (type == null || type.equals(this.type))
-               && (policyName == null || StringUtils.equals(policyName, 
this.policyName));
+                && (policyName == null || StringUtils.equals(policyName, 
this.policyName));
     }
 
     // it is used to check whether this policy is in PolicyMgr
diff --git a/fe/fe-core/src/main/java/org/apache/doris/policy/PolicyMgr.java 
b/fe/fe-core/src/main/java/org/apache/doris/policy/PolicyMgr.java
index ce47793ffe..96004adf66 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/policy/PolicyMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/policy/PolicyMgr.java
@@ -27,6 +27,7 @@ import org.apache.doris.catalog.Database;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.Table;
+import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.UserException;
@@ -39,13 +40,13 @@ import org.apache.doris.task.AgentBatchTask;
 import org.apache.doris.task.AgentTaskExecutor;
 import org.apache.doris.task.PushStoragePolicyTask;
 
-import com.google.common.base.Joiner;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 import com.google.gson.annotations.SerializedName;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -54,8 +55,6 @@ import java.io.DataOutput;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -74,13 +73,8 @@ public class PolicyMgr implements Writable {
     @SerializedName(value = "typeToPolicyMap")
     private Map<PolicyTypeEnum, List<Policy>> typeToPolicyMap = 
Maps.newConcurrentMap();
 
-    /**
-     * Cache merge policy for match.
-     * key:dbId:tableId-type-user
-     **/
-    private Map<Long, Map<String, RowPolicy>> dbIdToMergeTablePolicyMap = 
Maps.newConcurrentMap();
-
-    private Set<String> userPolicySet = Sets.newConcurrentHashSet();
+    // dbId -> tableId -> List<RowPolicy>
+    private Map<Long, Map<Long, List<RowPolicy>>> tablePolicies = 
Maps.newConcurrentMap();
 
     private void writeLock() {
         lock.writeLock().lock();
@@ -173,16 +167,6 @@ public class PolicyMgr implements Writable {
         }
     }
 
-    /**
-     * Check whether this user has policy.
-     *
-     * @param user user who has policy
-     * @return exist or not
-     */
-    public boolean existPolicy(String user) {
-        return userPolicySet.contains(user);
-    }
-
     /**
      * Check whether the policy exist.
      *
@@ -267,7 +251,10 @@ public class PolicyMgr implements Writable {
         List<Policy> dbPolicies = getPoliciesByType(policy.getType());
         dbPolicies.add(policy);
         typeToPolicyMap.put(policy.getType(), dbPolicies);
-        updateMergeTablePolicyMap();
+        if (PolicyTypeEnum.ROW == policy.getType()) {
+            addTablePolicies((RowPolicy) policy);
+        }
+
     }
 
     public void replayDrop(DropPolicyLog log) {
@@ -290,51 +277,88 @@ public class PolicyMgr implements Writable {
                 if (policy instanceof StoragePolicy) {
                     ((StoragePolicy) policy).removeResourceReference();
                 }
+                if (policy instanceof RowPolicy) {
+                    dropTablePolicies((RowPolicy) policy);
+                }
                 return true;
             }
             return false;
         });
         typeToPolicyMap.put(log.getType(), policies);
-        updateMergeTablePolicyMap();
     }
 
     /**
      * Match row policy and return it.
      **/
-    public RowPolicy getMatchTablePolicy(long dbId, long tableId, String user) 
{
+    public RowPolicy getMatchTablePolicy(long dbId, long tableId, UserIdentity 
user) {
+        List<RowPolicy> res = getUserPolicies(dbId, tableId, user);
+        if (CollectionUtils.isEmpty(res)) {
+            return null;
+        }
+        return mergeRowPolicies(res);
+    }
+
+    public List<RowPolicy> getUserPolicies(long dbId, long tableId, 
UserIdentity user) {
+        List<RowPolicy> res = Lists.newArrayList();
+        // Make a judgment in advance to reduce the number of times to obtain 
getRoles
+        if (!tablePolicies.containsKey(dbId) || 
!tablePolicies.get(dbId).containsKey(tableId)) {
+            return res;
+        }
+        Set<String> roles = 
Env.getCurrentEnv().getAccessManager().getAuth().getRolesByUserWithLdap(user).stream()
+                .map(role -> 
ClusterNamespace.getNameFromFullName(role.getRoleName())).collect(Collectors.toSet());
         readLock();
         try {
-            if (!dbIdToMergeTablePolicyMap.containsKey(dbId)) {
-                return null;
+            // double check in lock,avoid NPE
+            if (!tablePolicies.containsKey(dbId) || 
!tablePolicies.get(dbId).containsKey(tableId)) {
+                return res;
             }
-            String key = Joiner.on("-").join(tableId, 
PolicyTypeEnum.ROW.name(), user);
-            if (!dbIdToMergeTablePolicyMap.get(dbId).containsKey(key)) {
-                return null;
+            List<RowPolicy> policys = tablePolicies.get(dbId).get(tableId);
+            for (RowPolicy rowPolicy : policys) {
+                // on rowPolicy to user
+                if ((rowPolicy.getUser() != null && 
rowPolicy.getUser().getQualifiedUser()
+                        .equals(user.getQualifiedUser()))
+                        || !StringUtils.isEmpty(rowPolicy.getRoleName()) && 
roles.contains(rowPolicy.getRoleName())) {
+                    res.add(rowPolicy);
+                }
             }
-            return dbIdToMergeTablePolicyMap.get(dbId).get(key);
+            return res;
         } finally {
             readUnlock();
         }
     }
 
-    /**
-     *  Match all row policy and return them.
-     **/
-    public List<RowPolicy> getMatchRowPolicy(long dbId, long tableId, 
UserIdentity user) {
-        RowPolicy checkedPolicy = new RowPolicy();
-        checkedPolicy.setDbId(dbId);
-        checkedPolicy.setTableId(tableId);
-        checkedPolicy.setUser(user);
-        readLock();
-        try {
-            return getPoliciesByType(PolicyTypeEnum.ROW).stream()
-                .filter(p -> p.matchPolicy(checkedPolicy))
-                .filter(p -> !p.isInvalid())
-                .map(p -> (RowPolicy) p)
-                .collect(Collectors.toList());
-        } finally {
-            readUnlock();
+    private RowPolicy mergeRowPolicies(List<RowPolicy> policys) {
+        if (CollectionUtils.isEmpty(policys)) {
+            return null;
+        }
+        RowPolicy andPolicy = null;
+        RowPolicy orPolicy = null;
+        for (RowPolicy rowPolicy : policys) {
+            if 
(CompoundPredicate.Operator.AND.equals(rowPolicy.getFilterType().getOp())) {
+                if (andPolicy == null) {
+                    andPolicy = rowPolicy.clone();
+                } else {
+                    andPolicy.setWherePredicate(new 
CompoundPredicate(CompoundPredicate.Operator.AND,
+                            andPolicy.getWherePredicate(), 
rowPolicy.getWherePredicate()));
+                }
+            } else {
+                if (orPolicy == null) {
+                    orPolicy = rowPolicy;
+                } else {
+                    orPolicy.setWherePredicate(new 
CompoundPredicate(CompoundPredicate.Operator.OR,
+                            orPolicy.getWherePredicate(), 
rowPolicy.getWherePredicate()));
+                }
+            }
+        }
+        if (andPolicy == null) {
+            return orPolicy;
         }
+        if (orPolicy == null) {
+            return andPolicy;
+        }
+        andPolicy.setWherePredicate(new 
CompoundPredicate(CompoundPredicate.Operator.AND, andPolicy.getWherePredicate(),
+                orPolicy.getWherePredicate()));
+        return andPolicy;
     }
 
     /**
@@ -354,6 +378,9 @@ public class PolicyMgr implements Writable {
                 if (showStmt.getUser() != null) {
                     rowPolicy.setUser(showStmt.getUser());
                 }
+                if (!StringUtils.isEmpty(showStmt.getRoleName())) {
+                    rowPolicy.setRoleName(showStmt.getRoleName());
+                }
                 if (currentDbId != -1) {
                     rowPolicy.setDbId(currentDbId);
                 }
@@ -382,84 +409,48 @@ public class PolicyMgr implements Writable {
         }
     }
 
+    private void addTablePolicies(RowPolicy policy) {
+        if (policy.getUser() != null) {
+            policy.getUser().setIsAnalyzed();
+        }
+        List<RowPolicy> policys = getOrCreateTblPolicies(policy.getDbId(), 
policy.getTableId());
+        policys.add(policy);
+    }
+
+    private void dropTablePolicies(RowPolicy policy) {
+        List<RowPolicy> policys = getOrCreateTblPolicies(policy.getDbId(), 
policy.getTableId());
+        policys.removeIf(p -> p.matchPolicy(policy));
+    }
+
+    private List<RowPolicy> getOrCreateTblPolicies(long dbId, long tableId) {
+        Map<Long, List<RowPolicy>> dbPolicyMap = getOrCreateDbPolicyMap(dbId);
+        if (!dbPolicyMap.containsKey(tableId)) {
+            dbPolicyMap.put(tableId, Lists.newArrayList());
+        }
+        return dbPolicyMap.get(tableId);
+    }
+
+    private Map<Long, List<RowPolicy>> getOrCreateDbPolicyMap(Long dbId) {
+        if (!tablePolicies.containsKey(dbId)) {
+            tablePolicies.put(dbId, Maps.newConcurrentMap());
+        }
+        return tablePolicies.get(dbId);
+    }
+
     /**
      * The merge policy cache needs to be regenerated after the update.
      **/
-    private void updateMergeTablePolicyMap() {
+    private void updateTablePolicies() {
         readLock();
         try {
             if (!typeToPolicyMap.containsKey(PolicyTypeEnum.ROW)) {
                 return;
             }
             List<Policy> allPolicies = typeToPolicyMap.get(PolicyTypeEnum.ROW);
-            Map<Long, List<RowPolicy>> policyMap = new HashMap<>();
-            dbIdToMergeTablePolicyMap.clear();
-            userPolicySet.clear();
             for (Policy policy : allPolicies) {
-                if (!(policy instanceof RowPolicy)) {
-                    continue;
-                }
-                RowPolicy rowPolicy = (RowPolicy) policy;
-                if (!policyMap.containsKey(rowPolicy.getDbId())) {
-                    policyMap.put(rowPolicy.getDbId(), new ArrayList<>());
-                }
-                policyMap.get(rowPolicy.getDbId()).add(rowPolicy);
-                if (rowPolicy.getUser() != null) {
-                    userPolicySet.add(rowPolicy.getUser().getQualifiedUser());
-                }
-            }
-            for (Map.Entry<Long, List<RowPolicy>> entry : 
policyMap.entrySet()) {
-                List<RowPolicy> policies = entry.getValue();
-                Map<String, RowPolicy> andMap = new HashMap<>();
-                Map<String, RowPolicy> orMap = new HashMap<>();
-                for (RowPolicy rowPolicy : policies) {
-                    // read from json, need set isAnalyzed
-                    rowPolicy.getUser().setIsAnalyzed();
-                    String key = Joiner.on("-")
-                            .join(rowPolicy.getTableId(), rowPolicy.getType(), 
rowPolicy.getUser().getQualifiedUser());
-                    // merge wherePredicate
-                    if 
(CompoundPredicate.Operator.AND.equals(rowPolicy.getFilterType().getOp())) {
-                        RowPolicy frontPolicy = andMap.get(key);
-                        if (frontPolicy == null) {
-                            andMap.put(key, rowPolicy.clone());
-                        } else {
-                            frontPolicy.setWherePredicate(new 
CompoundPredicate(CompoundPredicate.Operator.AND,
-                                    frontPolicy.getWherePredicate(), 
rowPolicy.getWherePredicate()));
-                            andMap.put(key, frontPolicy.clone());
-                        }
-                    } else {
-                        RowPolicy frontPolicy = orMap.get(key);
-                        if (frontPolicy == null) {
-                            orMap.put(key, rowPolicy.clone());
-                        } else {
-                            frontPolicy.setWherePredicate(new 
CompoundPredicate(CompoundPredicate.Operator.OR,
-                                    frontPolicy.getWherePredicate(), 
rowPolicy.getWherePredicate()));
-                            orMap.put(key, frontPolicy.clone());
-                        }
-                    }
-                }
-                Map<String, RowPolicy> mergeMap = new HashMap<>();
-                Set<String> policyKeys = new HashSet<>();
-                policyKeys.addAll(andMap.keySet());
-                policyKeys.addAll(orMap.keySet());
-                policyKeys.forEach(key -> {
-                    if (andMap.containsKey(key) && orMap.containsKey(key)) {
-                        RowPolicy mergePolicy = andMap.get(key).clone();
-                        mergePolicy.setWherePredicate(
-                                new 
CompoundPredicate(CompoundPredicate.Operator.AND, 
mergePolicy.getWherePredicate(),
-                                        orMap.get(key).getWherePredicate()));
-                        mergeMap.put(key, mergePolicy);
-                    }
-                    if (!andMap.containsKey(key)) {
-                        mergeMap.put(key, orMap.get(key));
-                    }
-                    if (!orMap.containsKey(key)) {
-                        mergeMap.put(key, andMap.get(key));
-                    }
-                });
-                long dbId = entry.getKey();
-                dbIdToMergeTablePolicyMap.put(dbId, mergeMap);
+                addTablePolicies((RowPolicy) policy);
             }
+
         } finally {
             readUnlock();
         }
@@ -477,7 +468,7 @@ public class PolicyMgr implements Writable {
         String json = Text.readString(in);
         PolicyMgr policyMgr = GsonUtils.GSON.fromJson(json, PolicyMgr.class);
         // update merge policy cache and userPolicySet
-        policyMgr.updateMergeTablePolicyMap();
+        policyMgr.updateTablePolicies();
         return policyMgr;
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/policy/RowPolicy.java 
b/fe/fe-core/src/main/java/org/apache/doris/policy/RowPolicy.java
index 2708462b42..d1d2cc6636 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/policy/RowPolicy.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/policy/RowPolicy.java
@@ -41,6 +41,7 @@ import org.apache.logging.log4j.Logger;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Save policy for filtering data.
@@ -50,15 +51,16 @@ public class RowPolicy extends Policy {
 
     public static final ShowResultSetMetaData ROW_META_DATA =
             ShowResultSetMetaData.builder()
-                .addColumn(new Column("PolicyName", 
ScalarType.createVarchar(100)))
-                .addColumn(new Column("DbName", ScalarType.createVarchar(100)))
-                .addColumn(new Column("TableName", 
ScalarType.createVarchar(100)))
-                .addColumn(new Column("Type", ScalarType.createVarchar(20)))
-                .addColumn(new Column("FilterType", 
ScalarType.createVarchar(20)))
-                .addColumn(new Column("WherePredicate", 
ScalarType.createVarchar(65535)))
-                .addColumn(new Column("User", ScalarType.createVarchar(20)))
-                .addColumn(new Column("OriginStmt", 
ScalarType.createVarchar(65535)))
-                .build();
+                    .addColumn(new Column("PolicyName", 
ScalarType.createVarchar(100)))
+                    .addColumn(new Column("DbName", 
ScalarType.createVarchar(100)))
+                    .addColumn(new Column("TableName", 
ScalarType.createVarchar(100)))
+                    .addColumn(new Column("Type", 
ScalarType.createVarchar(20)))
+                    .addColumn(new Column("FilterType", 
ScalarType.createVarchar(20)))
+                    .addColumn(new Column("WherePredicate", 
ScalarType.createVarchar(65535)))
+                    .addColumn(new Column("User", 
ScalarType.createVarchar(20)))
+                    .addColumn(new Column("Role", 
ScalarType.createVarchar(20)))
+                    .addColumn(new Column("OriginStmt", 
ScalarType.createVarchar(65535)))
+                    .build();
 
     private static final Logger LOG = LogManager.getLogger(RowPolicy.class);
 
@@ -68,6 +70,9 @@ public class RowPolicy extends Policy {
     @SerializedName(value = "user")
     private UserIdentity user = null;
 
+    @SerializedName(value = "roleName")
+    private String roleName = null;
+
     @SerializedName(value = "dbId")
     private long dbId = -1;
 
@@ -99,15 +104,18 @@ public class RowPolicy extends Policy {
      * @param policyName policy name
      * @param dbId database i
      * @param user username
+     * @param roleName roleName
      * @param originStmt origin stmt
      * @param tableId table id
      * @param filterType filter type
      * @param wherePredicate where predicate
      */
-    public RowPolicy(long policyId, final String policyName, long dbId, 
UserIdentity user, String originStmt,
+    public RowPolicy(long policyId, final String policyName, long dbId, 
UserIdentity user, String roleName,
+            String originStmt,
             final long tableId, final FilterType filterType, final Expr 
wherePredicate) {
         super(policyId, PolicyTypeEnum.ROW, policyName);
         this.user = user;
+        this.roleName = roleName;
         this.dbId = dbId;
         this.tableId = tableId;
         this.filterType = filterType;
@@ -122,7 +130,8 @@ public class RowPolicy extends Policy {
         Database database = 
Env.getCurrentInternalCatalog().getDbOrAnalysisException(this.dbId);
         Table table = database.getTableOrAnalysisException(this.tableId);
         return Lists.newArrayList(this.policyName, database.getFullName(), 
table.getName(), this.type.name(),
-                this.filterType.name(), this.wherePredicate.toSql(), 
this.user.getQualifiedUser(), this.originStmt);
+                this.filterType.name(), this.wherePredicate.toSql(),
+                this.user == null ? null : this.user.getQualifiedUser(), 
this.roleName, this.originStmt);
     }
 
     @Override
@@ -142,17 +151,18 @@ public class RowPolicy extends Policy {
 
     @Override
     public RowPolicy clone() {
-        return new RowPolicy(this.id, this.policyName, this.dbId, this.user, 
this.originStmt, this.tableId,
+        return new RowPolicy(this.id, this.policyName, this.dbId, this.user, 
this.roleName, this.originStmt,
+                this.tableId,
                 this.filterType, this.wherePredicate);
     }
 
     private boolean checkMatched(long dbId, long tableId, PolicyTypeEnum type,
-                                 String policyName, UserIdentity user) {
+            String policyName, UserIdentity user, String roleName) {
         return super.checkMatched(type, policyName)
                 && (dbId == -1 || dbId == this.dbId)
                 && (tableId == -1 || tableId == this.tableId)
-                && (user == null || this.user == null
-                        || StringUtils.equals(user.getQualifiedUser(), 
this.user.getQualifiedUser()));
+                && (StringUtils.isEmpty(roleName) || 
StringUtils.equals(roleName, this.roleName))
+                && (user == null || Objects.equals(user, this.user));
     }
 
     @Override
@@ -162,14 +172,7 @@ public class RowPolicy extends Policy {
         }
         RowPolicy rowPolicy = (RowPolicy) checkedPolicyCondition;
         return checkMatched(rowPolicy.getDbId(), rowPolicy.getTableId(), 
rowPolicy.getType(),
-                            rowPolicy.getPolicyName(), rowPolicy.getUser());
-    }
-
-    @Override
-    public boolean matchPolicy(DropPolicyLog checkedDropPolicyLogCondition) {
-        return checkMatched(checkedDropPolicyLogCondition.getDbId(), 
checkedDropPolicyLogCondition.getTableId(),
-                            checkedDropPolicyLogCondition.getType(), 
checkedDropPolicyLogCondition.getPolicyName(),
-                            checkedDropPolicyLogCondition.getUser());
+                rowPolicy.getPolicyName(), rowPolicy.getUser(), 
rowPolicy.getRoleName());
     }
 
     @Override
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/CheckRowPolicyTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/CheckRowPolicyTest.java
index 1464de74d8..1e81db8bf9 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/CheckRowPolicyTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/CheckRowPolicyTest.java
@@ -144,9 +144,6 @@ public class CheckRowPolicyTest extends TestWithFeService {
         
Assertions.assertTrue(ImmutableList.copyOf(filter.getConjuncts()).get(0) 
instanceof EqualTo);
         Assertions.assertTrue(filter.getConjuncts().toString().contains("'k1 = 
1"));
 
-        dropPolicy("DROP ROW POLICY "
-                + policyName
-                + " ON "
-                + tableName);
+        dropPolicy("DROP ROW POLICY " + policyName);
     }
 }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
index b678f33614..ba912baf79 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java
@@ -18,6 +18,7 @@
 package org.apache.doris.policy;
 
 import org.apache.doris.analysis.Analyzer;
+import org.apache.doris.analysis.CreateRoleStmt;
 import org.apache.doris.analysis.CreateUserStmt;
 import org.apache.doris.analysis.Expr;
 import org.apache.doris.analysis.GrantStmt;
@@ -77,6 +78,16 @@ public class PolicyTest extends TestWithFeService {
         Analyzer analyzer = new Analyzer(connectContext.getEnv(), 
connectContext);
         grantStmt.analyze(analyzer);
         Env.getCurrentEnv().getAuth().grant(grantStmt);
+        //create role
+        String role = "role1";
+        CreateRoleStmt createRoleStmt = new CreateRoleStmt(role);
+        createRoleStmt.analyze(analyzer);
+        Env.getCurrentEnv().getAuth().createRole(createRoleStmt);
+        // grant role to user
+        grantStmt = new GrantStmt(Lists.newArrayList(role), user);
+        grantStmt.analyze(analyzer);
+        Env.getCurrentEnv().getAuth().grant(grantStmt);
+
         useUser("test_policy");
     }
 
@@ -90,23 +101,35 @@ public class PolicyTest extends TestWithFeService {
     }
 
     @Test
-    public void testExistPolicy() throws Exception {
-        createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
-        
Assertions.assertTrue(Env.getCurrentEnv().getPolicyMgr().existPolicy("default_cluster:test_policy"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
-        
Assertions.assertFalse(Env.getCurrentEnv().getPolicyMgr().existPolicy("default_cluster:test_policy"));
+    public void testNormalSql() throws Exception {
+        // test user
         createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1");
-        
Assertions.assertFalse(Env.getCurrentEnv().getPolicyMgr().existPolicy("default_cluster:test_policy"));
+        String queryStr = "EXPLAIN select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1";
+        String explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("`k1` = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
+        // test role
+        createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO ROLE role1 USING (k1 = 2)");
+        queryStr = "EXPLAIN select /*+ SET_VAR(enable_nereids_planner=false) 
*/ * from test.table1";
+        explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("`k1` = 2"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
     }
 
     @Test
-    public void testNormalSql() throws Exception {
+    public void testNormalSqlNereidsPlanners() throws Exception {
+        // test user
         createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
-        String queryStr = "EXPLAIN select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1";
+        String queryStr = "EXPLAIN select * from test.table1";
         String explainString = getSQLPlanOrErrorMsg(queryStr);
-        Assertions.assertTrue(explainString.contains("`k1` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
+        Assertions.assertTrue(explainString.contains("k1[#0] = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
+        //test role
+        createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO ROLE role1 USING (k1 = 2)");
+        queryStr = "EXPLAIN select * from test.table1";
+        explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("k1[#0] = 2"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
     }
 
     @Test
@@ -118,7 +141,7 @@ public class PolicyTest extends TestWithFeService {
         queryStr = "EXPLAIN select /*+ SET_VAR(enable_nereids_planner=false) 
*/ * from test.table1 b";
         explainString = getSQLPlanOrErrorMsg(queryStr);
         Assertions.assertTrue(explainString.contains("`b`.`k1` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
+        dropPolicy("DROP ROW POLICY test_row_policy");
     }
 
     @Test
@@ -132,26 +155,46 @@ public class PolicyTest extends TestWithFeService {
         queryStr = "EXPLAIN select * from test.table1 b";
         explainString = getSQLPlanOrErrorMsg(queryStr);
         Assertions.assertTrue(explainString.contains("k1[#0] = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
+        dropPolicy("DROP ROW POLICY test_row_policy");
         
connectContext.getSessionVariable().setEnableNereidsPlanner(beforeConfig);
     }
 
     @Test
     public void testUnionSql() throws Exception {
         createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
-        String queryStr = "EXPLAIN select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1 union all select * 
from test.table1";
+        String queryStr
+                = "EXPLAIN select /*+ SET_VAR(enable_nereids_planner=false) */ 
* from test.table1 union all select * from test.table1";
         String explainString = getSQLPlanOrErrorMsg(queryStr);
         Assertions.assertTrue(explainString.contains("`k1` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
+        dropPolicy("DROP ROW POLICY test_row_policy");
+    }
+
+    @Test
+    public void testUnionSqlNereidsPlanner() throws Exception {
+        createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
+        String queryStr = "EXPLAIN select * from test.table1 union all select 
* from test.table1";
+        String explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("k1[#0] = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
     }
 
     @Test
     public void testInsertSelectSql() throws Exception {
         createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
-        String queryStr = "EXPLAIN insert into test.table1 select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1";
+        String queryStr
+                = "EXPLAIN insert into test.table1 select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1";
         String explainString = getSQLPlanOrErrorMsg(queryStr);
         Assertions.assertTrue(explainString.contains("`k1` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy ON test.table1 FOR 
test_policy");
+        dropPolicy("DROP ROW POLICY test_row_policy");
+    }
+
+    @Test
+    public void testInsertSelectSqlNereidsPlanner() throws Exception {
+        createPolicy("CREATE ROW POLICY test_row_policy ON test.table1 AS 
PERMISSIVE TO test_policy USING (k1 = 1)");
+        String queryStr = "EXPLAIN insert into test.table1 select * from 
test.table1";
+        String explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("k1[#0] = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy");
     }
 
     @Test
@@ -162,7 +205,7 @@ public class PolicyTest extends TestWithFeService {
         ExceptionChecker.expectThrowsWithMsg(DdlException.class, "the policy 
test_row_policy1 already create",
                 () -> createPolicy("CREATE ROW POLICY test_row_policy1 ON 
test.table1 AS PERMISSIVE"
                         + " TO test_policy USING (k1 = 1)"));
-        dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
+        dropPolicy("DROP ROW POLICY test_row_policy1");
     }
 
     @Test
@@ -181,8 +224,8 @@ public class PolicyTest extends TestWithFeService {
                 (ShowPolicyStmt) parseAndAnalyzeStmt("SHOW ROW POLICY");
         int firstSize = 
Env.getCurrentEnv().getPolicyMgr().showPolicy(showPolicyStmt).getResultRows().size();
         Assertions.assertTrue(firstSize > 0);
-        dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
-        dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1");
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY test_row_policy2");
         int secondSize = 
Env.getCurrentEnv().getPolicyMgr().showPolicy(showPolicyStmt).getResultRows().size();
         Assertions.assertEquals(2, firstSize - secondSize);
     }
@@ -190,41 +233,74 @@ public class PolicyTest extends TestWithFeService {
     @Test
     public void testDropPolicy() throws Exception {
         createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
PERMISSIVE TO test_policy USING (k2 = 1)");
-        dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
-        dropPolicy("DROP ROW POLICY IF EXISTS test_row_policy5 ON 
test.table1");
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY IF EXISTS test_row_policy5");
         ExceptionChecker.expectThrowsWithMsg(DdlException.class, "the policy 
test_row_policy1 not exist",
-                () -> dropPolicy("DROP ROW POLICY test_row_policy1 ON 
test.table1"));
+                () -> dropPolicy("DROP ROW POLICY test_row_policy1"));
     }
 
     @Test
     public void testMergeFilter() throws Exception {
         createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k1 = 1)");
-        createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k2 = 1)");
-        createPolicy("CREATE ROW POLICY test_row_policy3 ON test.table1 AS 
PERMISSIVE TO test_policy USING (k2 = 2)");
+        createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS 
RESTRICTIVE TO ROLE role1 USING (k2 = 1)");
+        createPolicy("CREATE ROW POLICY test_row_policy3 ON test.table1 AS 
PERMISSIVE TO ROLE role1 USING (k2 = 2)");
         createPolicy("CREATE ROW POLICY test_row_policy4 ON test.table1 AS 
PERMISSIVE TO test_policy USING (k2 = 1)");
         String queryStr = "EXPLAIN select /*+ 
SET_VAR(enable_nereids_planner=false) */ * from test.table1";
         String explainString = getSQLPlanOrErrorMsg(queryStr);
         Assertions.assertTrue(explainString.contains("`k1` = 1 AND `k2` = 1 
AND `k2` = 2 OR `k2` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
-        dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1");
-        dropPolicy("DROP ROW POLICY test_row_policy3 ON test.table1");
-        dropPolicy("DROP ROW POLICY test_row_policy4 ON test.table1");
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY test_row_policy2");
+        dropPolicy("DROP ROW POLICY test_row_policy3");
+        dropPolicy("DROP ROW POLICY test_row_policy4");
+    }
+
+    @Test
+    public void testMergeFilterNereidsPlanner() throws Exception {
+        createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k1 = 1)");
+        createPolicy("CREATE ROW POLICY test_row_policy3 ON test.table1 AS 
PERMISSIVE TO ROLE role1 USING (k2 = 2)");
+        createPolicy("CREATE ROW POLICY test_row_policy4 ON test.table1 AS 
PERMISSIVE TO test_policy USING (k2 = 1)");
+        String queryStr = "EXPLAIN select * from test.table1";
+        String explainString = getSQLPlanOrErrorMsg(queryStr);
+        Assertions.assertTrue(explainString.contains("k2[#1] IN (1, 2) AND 
k1[#0] = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY test_row_policy3");
+        dropPolicy("DROP ROW POLICY test_row_policy4");
     }
 
     @Test
     public void testComplexSql() throws Exception {
         createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k1 = 1)");
         createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k2 = 1)");
-        String joinSql = "select /*+ SET_VAR(enable_nereids_planner=false) */ 
* from table1 join table2 on table1.k1=table2.k1";
+        String joinSql
+                = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from 
table1 join table2 on table1.k1=table2.k1";
         
Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: `k1` 
= 1 AND `k2` = 1"));
-        String unionSql = "select /*+ SET_VAR(enable_nereids_planner=false) */ 
* from table1 union select * from table2";
+        String unionSql
+                = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from 
table1 union select * from table2";
         
Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: `k1` 
= 1 AND `k2` = 1"));
-        String subQuerySql = "select /*+ SET_VAR(enable_nereids_planner=false) 
*/ * from table2 where k1 in (select k1 from table1)";
+        String subQuerySql
+                = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from 
table2 where k1 in (select k1 from table1)";
         
Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: 
`k1` = 1 AND `k2` = 1"));
-        String aliasSql = "select /*+ SET_VAR(enable_nereids_planner=false) */ 
* from table1 t1 join table2 t2 on t1.k1=t2.k1";
+        String aliasSql
+                = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from 
table1 t1 join table2 t2 on t1.k1=t2.k1";
         
Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: 
`t1`.`k1` = 1 AND `t1`.`k2` = 1"));
-        dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1");
-        dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1");
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY test_row_policy2");
+    }
+
+    @Test
+    public void testComplexSqlNereidsPlanner() throws Exception {
+        createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k1 = 1)");
+        createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS 
RESTRICTIVE TO test_policy USING (k2 = 1)");
+        String joinSql = "select * from table1 join table2 on 
table1.k1=table2.k1";
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: k1 = 
1 AND k2 = 1"));
+        String unionSql = "select * from table1 union select * from table2";
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: k1 = 
1 AND k2 = 1"));
+        String subQuerySql = "select * from table2 where k1 in (select k1 from 
table1)";
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: 
k1 = 1 AND k2 = 1"));
+        String aliasSql = "select * from table1 t1 join table2 t2 on 
t1.k1=t2.k1";
+        
Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: k1 = 
1 AND k2 = 1"));
+        dropPolicy("DROP ROW POLICY test_row_policy1");
+        dropPolicy("DROP ROW POLICY test_row_policy2");
     }
 
     @Test
@@ -240,7 +316,7 @@ public class PolicyTest extends TestWithFeService {
         FilterType filterType = FilterType.PERMISSIVE;
         Expr wherePredicate = null;
 
-        Policy rowPolicy = new RowPolicy(10000, policyName, dbId, user, 
originStmt, tableId, filterType,
+        Policy rowPolicy = new RowPolicy(10000, policyName, dbId, user, null, 
originStmt, tableId, filterType,
                 wherePredicate);
 
         ByteArrayOutputStream emptyOutputStream = new ByteArrayOutputStream();
diff --git a/regression-test/suites/account_p0/test_nereids_row_policy.groovy 
b/regression-test/suites/account_p0/test_nereids_row_policy.groovy
index d12b11261d..bcc1a7b817 100644
--- a/regression-test/suites/account_p0/test_nereids_row_policy.groovy
+++ b/regression-test/suites/account_p0/test_nereids_row_policy.groovy
@@ -51,7 +51,7 @@ suite("test_nereids_row_policy") {
 
     def dropPolciy = { name ->
         sql """
-            DROP ROW POLICY IF EXISTS ${name} ON ${dbName}.${tableName} FOR 
${user}
+            DROP ROW POLICY IF EXISTS ${name}
         """
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to