diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java index 2af297c2a59fef..8df13b1df6dfcb 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java @@ -2467,4 +2467,8 @@ public class Config extends ConfigBase { @ConfField(mutable = true) public static boolean enable_cooldown_replica_affinity = true; + + @ConfField(mutable = true, description = { + "设置为 true,root 和 admin 将跳过 sql block rule", "Set to true, root and admin will skip SQL block rule"}) + public static boolean sql_block_rule_ignore_admin = false; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRule.java b/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRule.java index 87d1830a170c78..41eecf9492533a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRule.java @@ -22,6 +22,7 @@ import org.apache.doris.common.io.Text; import org.apache.doris.common.io.Writable; import org.apache.doris.common.util.SqlBlockUtil; +import org.apache.doris.persist.gson.GsonPostProcessable; import org.apache.doris.persist.gson.GsonUtils; import com.google.common.collect.Lists; @@ -37,7 +38,7 @@ /** * Use for block some sql by rule. **/ -public class SqlBlockRule implements Writable { +public class SqlBlockRule implements Writable, GsonPostProcessable { public static final String NAME_TYPE = "SQL BLOCK RULE NAME"; @@ -191,11 +192,14 @@ public void write(DataOutput out) throws IOException { **/ public static SqlBlockRule read(DataInput in) throws IOException { String json = Text.readString(in); - SqlBlockRule sqlBlockRule = GsonUtils.GSON.fromJson(json, SqlBlockRule.class); - if (StringUtils.isNotEmpty(sqlBlockRule.getSql()) && !SqlBlockUtil.STRING_DEFAULT.equals( - sqlBlockRule.getSql())) { - sqlBlockRule.setSqlPattern(Pattern.compile(sqlBlockRule.getSql())); + return GsonUtils.GSON.fromJson(json, SqlBlockRule.class); + } + + @Override + public void gsonPostProcess() { + if (StringUtils.isNotEmpty(this.getSql()) && !SqlBlockUtil.STRING_DEFAULT.equals( + this.getSql())) { + this.setSqlPattern(Pattern.compile(this.getSql())); } - return sqlBlockRule; } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRuleMgr.java b/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRuleMgr.java index 1bc5505edfd291..02e0db4ff5cbfe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRuleMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/blockrule/SqlBlockRuleMgr.java @@ -23,12 +23,14 @@ import org.apache.doris.analysis.ShowSqlBlockRuleStmt; import org.apache.doris.catalog.Env; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.Config; import org.apache.doris.common.DdlException; import org.apache.doris.common.UserException; import org.apache.doris.common.io.Text; import org.apache.doris.common.io.Writable; import org.apache.doris.common.util.SqlBlockUtil; import org.apache.doris.metric.MetricRepo; +import org.apache.doris.mysql.privilege.Auth; import org.apache.doris.persist.gson.GsonUtils; import com.google.common.collect.Lists; @@ -224,6 +226,9 @@ public void unprotectedDrop(List ruleNames) { * Match SQL according to rules. **/ public void matchSql(String originSql, String sqlHash, String user) throws AnalysisException { + if (Config.sql_block_rule_ignore_admin && (Auth.ROOT_USER.equals(user) || Auth.ADMIN_USER.equals(user))) { + return; + } // match global rule List globalRules = nameToSqlBlockRuleMap.values().stream().filter(SqlBlockRule::getGlobal).collect(Collectors.toList()); diff --git a/fe/fe-core/src/test/java/org/apache/doris/blockrule/SqlBlockRuleMgrTest.java b/fe/fe-core/src/test/java/org/apache/doris/blockrule/SqlBlockRuleMgrTest.java index 2f93ee5beaa152..b1684ef74a0420 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/blockrule/SqlBlockRuleMgrTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/blockrule/SqlBlockRuleMgrTest.java @@ -22,6 +22,7 @@ import org.apache.doris.analysis.ShowSqlBlockRuleStmt; import org.apache.doris.catalog.Env; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.Config; import org.apache.doris.common.DdlException; import org.apache.doris.common.ExceptionChecker; import org.apache.doris.metric.MetricRepo; @@ -303,4 +304,28 @@ public void testIfNotExists() throws Exception { () -> dropSqlBlockRule("DROP SQL_BLOCK_RULE test_rule")); dropSqlBlockRule("DROP SQL_BLOCK_RULE if exists test_rule"); } + + @Test + public void testIgnoreAdmin() throws Exception { + String sql = "select * from test_table1 limit 10"; + String sqlHash = DigestUtils.md5Hex(sql); + String sqlRule = "CREATE SQL_BLOCK_RULE test_rule PROPERTIES(\"sql\"=\"select \\\\* from test_table1\"," + + " \"global\"=\"true\", \"enable\"=\"true\");"; + createSqlBlockRule(sqlRule); + Config.sql_block_rule_ignore_admin = false; + ExceptionChecker.expectThrowsWithMsg(AnalysisException.class, + "sql match regex sql block rule: test_rule", + () -> mgr.matchSql(sql, sqlHash, "root")); + ExceptionChecker.expectThrowsWithMsg(AnalysisException.class, + "sql match regex sql block rule: test_rule", + () -> mgr.matchSql(sql, sqlHash, "admin")); + Config.sql_block_rule_ignore_admin = true; + ExceptionChecker.expectThrowsNoException(() -> mgr.matchSql(sql, sqlHash, "root")); + ExceptionChecker.expectThrowsNoException(() -> mgr.matchSql(sql, sqlHash, "admin")); + ExceptionChecker.expectThrowsWithMsg(AnalysisException.class, + "sql match regex sql block rule: test_rule", + () -> mgr.matchSql(sql, sqlHash, "other_user")); + Config.sql_block_rule_ignore_admin = false; + dropSqlBlockRule(dropSqlRule); + } }