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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]