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

starocean999 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 2bd293c560a [Enhancement] (nereids)implement CreateSqlBlockCommand and 
AlterSqlBlockCommand in nereids (#44702)
2bd293c560a is described below

commit 2bd293c560afdb7665f05ae513f1354d6dfb6371
Author: Vallish Pai <vallish...@gmail.com>
AuthorDate: Mon Dec 2 08:30:54 2024 +0530

    [Enhancement] (nereids)implement CreateSqlBlockCommand and 
AlterSqlBlockCommand in nereids (#44702)
    
    Issue Number: close #42592  #42796
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   8 +-
 .../apache/doris/blockrule/SqlBlockRuleMgr.java    |  12 ++-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  18 ++++
 .../apache/doris/nereids/trees/plans/PlanType.java |   2 +
 .../plans/commands/AlterSqlBlockRuleCommand.java   |  87 +++++++++++++++
 .../plans/commands/CreateSqlBlockRuleCommand.java  |  99 +++++++++++++++++
 .../trees/plans/commands/SqlBlockRuleCommand.java  | 117 +++++++++++++++++++++
 .../trees/plans/visitor/CommandVisitor.java        |  10 ++
 .../sql_block_rule_p0/test_sql_block_rule.groovy   |  11 +-
 9 files changed, 349 insertions(+), 15 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 fd5ae1bd574..6e2a518ec20 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
@@ -185,7 +185,9 @@ supportedCreateStatement
         ON table=multipartIdentifier
         AS type=(RESTRICTIVE | PERMISSIVE)
         TO (user=userIdentify | ROLE roleName=identifier)
-        USING LEFT_PAREN booleanExpression RIGHT_PAREN                 
#createRowPolicy
+        USING LEFT_PAREN booleanExpression RIGHT_PAREN                    
#createRowPolicy
+    | CREATE SQL_BLOCK_RULE (IF NOT EXISTS)?
+        name=identifier properties=propertyClause?                        
#createSqlBlockRule
     ;
 
 supportedAlterStatement
@@ -197,6 +199,7 @@ supportedAlterStatement
         properties=propertyClause?                                             
     #alterWorkloadGroup
     | ALTER WORKLOAD POLICY name=identifierOrText
         properties=propertyClause?                                             
     #alterWorkloadPolicy
+    | ALTER SQL_BLOCK_RULE name=identifier properties=propertyClause?          
     #alterSqlBlockRule
     ;
 
 supportedDropStatement
@@ -573,7 +576,6 @@ unsupportedAlterStatement
         SET LEFT_PAREN propertyItemList RIGHT_PAREN                            
     #alterColocateGroup
     | ALTER ROUTINE LOAD FOR name=multipartIdentifier 
properties=propertyClause?
             (FROM type=identifier LEFT_PAREN propertyItemList RIGHT_PAREN)?    
     #alterRoutineLoad
-    | ALTER SQL_BLOCK_RULE name=identifier properties=propertyClause?          
     #alterSqlBlockRule
     | ALTER TABLE name=multipartIdentifier
         SET LEFT_PAREN propertyItemList RIGHT_PAREN                            
     #alterTableProperties
     | ALTER STORAGE POLICY name=identifierOrText
@@ -765,8 +767,6 @@ unsupportedCreateStatement
         (ACTIONS LEFT_PAREN workloadPolicyActions RIGHT_PAREN)?
         properties=propertyClause?                                             
 #createWorkloadPolicy
     | CREATE ENCRYPTKEY (IF NOT EXISTS)? multipartIdentifier AS STRING_LITERAL 
 #createEncryptkey
-    | CREATE SQL_BLOCK_RULE (IF NOT EXISTS)?
-        name=identifier properties=propertyClause?                             
 #createSqlBlockRule
     | CREATE STORAGE POLICY (IF NOT EXISTS)?
         name=identifier properties=propertyClause?                             
 #createStoragePolicy
     | BUILD INDEX name=identifier ON tableName=multipartIdentifier
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 aa3b844f3e3..e4e288bc14b 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
@@ -116,12 +116,15 @@ public class SqlBlockRuleMgr implements Writable {
      * Create SqlBlockRule for create stmt.
      **/
     public void createSqlBlockRule(CreateSqlBlockRuleStmt stmt) throws 
UserException {
+        createSqlBlockRule(SqlBlockRule.fromCreateStmt(stmt), 
stmt.isIfNotExists());
+    }
+
+    public void createSqlBlockRule(SqlBlockRule sqlBlockRule, boolean 
isIfNotExists) throws UserException {
         writeLock();
         try {
-            SqlBlockRule sqlBlockRule = SqlBlockRule.fromCreateStmt(stmt);
             String ruleName = sqlBlockRule.getName();
             if (existRule(ruleName)) {
-                if (stmt.isIfNotExists()) {
+                if (isIfNotExists) {
                     return;
                 }
                 throw new DdlException("the sql block rule " + ruleName + " 
already create");
@@ -146,9 +149,12 @@ public class SqlBlockRuleMgr implements Writable {
      * Alter SqlBlockRule for alter stmt.
      **/
     public void alterSqlBlockRule(AlterSqlBlockRuleStmt stmt) throws 
AnalysisException, DdlException {
+        alterSqlBlockRule(SqlBlockRule.fromAlterStmt(stmt));
+    }
+
+    public void alterSqlBlockRule(SqlBlockRule sqlBlockRule) throws 
AnalysisException, DdlException {
         writeLock();
         try {
-            SqlBlockRule sqlBlockRule = SqlBlockRule.fromAlterStmt(stmt);
             String ruleName = sqlBlockRule.getName();
             if (!existRule(ruleName)) {
                 throw new DdlException("the sql block rule " + ruleName + " 
not exist");
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 70c4f61e403..dfe879e7d44 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
@@ -57,6 +57,7 @@ import org.apache.doris.nereids.DorisParser.AliasQueryContext;
 import org.apache.doris.nereids.DorisParser.AliasedQueryContext;
 import org.apache.doris.nereids.DorisParser.AlterMTMVContext;
 import org.apache.doris.nereids.DorisParser.AlterRoleContext;
+import org.apache.doris.nereids.DorisParser.AlterSqlBlockRuleContext;
 import org.apache.doris.nereids.DorisParser.AlterStorageVaultContext;
 import org.apache.doris.nereids.DorisParser.AlterViewContext;
 import org.apache.doris.nereids.DorisParser.AlterWorkloadGroupContext;
@@ -92,6 +93,7 @@ import org.apache.doris.nereids.DorisParser.CreateMTMVContext;
 import org.apache.doris.nereids.DorisParser.CreateProcedureContext;
 import org.apache.doris.nereids.DorisParser.CreateRoutineLoadContext;
 import org.apache.doris.nereids.DorisParser.CreateRowPolicyContext;
+import org.apache.doris.nereids.DorisParser.CreateSqlBlockRuleContext;
 import org.apache.doris.nereids.DorisParser.CreateTableContext;
 import org.apache.doris.nereids.DorisParser.CreateTableLikeContext;
 import org.apache.doris.nereids.DorisParser.CreateViewContext;
@@ -460,6 +462,7 @@ import 
org.apache.doris.nereids.trees.plans.algebra.SetOperation.Qualifier;
 import org.apache.doris.nereids.trees.plans.commands.AddConstraintCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterRoleCommand;
+import org.apache.doris.nereids.trees.plans.commands.AlterSqlBlockRuleCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterStorageVaultCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterWorkloadGroupCommand;
@@ -477,6 +480,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateJobCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateSqlBlockRuleCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableLikeCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
@@ -4154,6 +4158,20 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         return ParserUtils.withOrigin(ctx, () -> new 
ShowCreateProcedureCommand(procedureName));
     }
 
+    @Override
+    public LogicalPlan visitCreateSqlBlockRule(CreateSqlBlockRuleContext ctx) {
+        Map<String, String> properties = ctx.propertyClause() != null
+                        ? 
Maps.newHashMap(visitPropertyClause(ctx.propertyClause())) : Maps.newHashMap();
+        return new CreateSqlBlockRuleCommand(stripQuotes(ctx.name.getText()), 
ctx.EXISTS() != null, properties);
+    }
+
+    @Override
+    public LogicalPlan visitAlterSqlBlockRule(AlterSqlBlockRuleContext ctx) {
+        Map<String, String> properties = ctx.propertyClause() != null
+                        ? 
Maps.newHashMap(visitPropertyClause(ctx.propertyClause())) : Maps.newHashMap();
+        return new AlterSqlBlockRuleCommand(stripQuotes(ctx.name.getText()), 
properties);
+    }
+
     @Override
     public LogicalPlan visitDropCatalogRecycleBin(DropCatalogRecycleBinContext 
ctx) {
         String idTypeStr = ctx.idType.getText().substring(1, 
ctx.idType.getText().length() - 1);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
index 6a8fcadaf52..14a1b13a466 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
@@ -134,6 +134,7 @@ public enum PlanType {
     // commands
     CREATE_POLICY_COMMAND,
     CREATE_TABLE_COMMAND,
+    CREATE_SQL_BLOCK_RULE_COMMAND,
     DELETE_COMMAND,
     EXPLAIN_COMMAND,
     EXPORT_COMMAND,
@@ -194,6 +195,7 @@ public enum PlanType {
     DROP_USER_COMMAND,
     DROP_WORKLOAD_GROUP_NAME,
     DROP_WORKLOAD_POLICY_COMMAND,
+    ALTER_SQL_BLOCK_RULE_COMMAND,
     SHOW_BACKENDS_COMMAND,
     SHOW_BLOCK_RULE_COMMAND,
     SHOW_BROKER_COMMAND,
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterSqlBlockRuleCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterSqlBlockRuleCommand.java
new file mode 100644
index 00000000000..481eb64a58d
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterSqlBlockRuleCommand.java
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.analysis.StmtType;
+import org.apache.doris.blockrule.SqlBlockRule;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.util.SqlBlockUtil;
+import org.apache.doris.common.util.Util;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+/**
+ * alter Sql block rule Commands.
+ */
+public class AlterSqlBlockRuleCommand extends SqlBlockRuleCommand {
+
+    /**
+    * constructor
+    */
+    public AlterSqlBlockRuleCommand(String ruleName, Map<String, String> 
properties) {
+        super(ruleName, properties, PlanType.ALTER_SQL_BLOCK_RULE_COMMAND);
+    }
+
+    @Override
+    public void doRun(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        Env.getCurrentEnv().getSqlBlockRuleMgr().alterSqlBlockRule(new 
SqlBlockRule(ruleName,
+                    sql, sqlHash, partitionNum,
+                    tabletNum, cardinality, global, enable));
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitAlterSqlBlockRuleCommand(this, context);
+    }
+
+    @Override
+    public StmtType stmtType() {
+        return StmtType.ALTER;
+    }
+
+    @Override
+    public void setProperties(Map<String, String> properties) throws 
AnalysisException {
+        this.sql = properties.getOrDefault(SQL_PROPERTY, 
SqlBlockRuleCommand.STRING_NOT_SET);
+        this.sqlHash = properties.getOrDefault(SQL_HASH_PROPERTY, 
SqlBlockRuleCommand.STRING_NOT_SET);
+        String partitionNumString = properties.get(SCANNED_PARTITION_NUM);
+        String tabletNumString = properties.get(SCANNED_TABLET_NUM);
+        String cardinalityString = properties.get(SCANNED_CARDINALITY);
+
+        SqlBlockUtil.checkSqlAndSqlHashSetBoth(sql, sqlHash);
+        SqlBlockUtil.checkSqlAndLimitationsSetBoth(sql, sqlHash,
+                partitionNumString, tabletNumString, cardinalityString);
+        this.partitionNum = Util.getLongPropertyOrDefault(partitionNumString, 
SqlBlockRuleCommand.LONG_NOT_SET, null,
+                SCANNED_PARTITION_NUM + " should be a long");
+        this.tabletNum = Util.getLongPropertyOrDefault(tabletNumString, 
SqlBlockRuleCommand.LONG_NOT_SET, null,
+                SCANNED_TABLET_NUM + " should be a long");
+        this.cardinality = Util.getLongPropertyOrDefault(cardinalityString, 
SqlBlockRuleCommand.LONG_NOT_SET, null,
+                SCANNED_CARDINALITY + " should be a long");
+        // allow null, represents no modification
+        String globalStr = properties.get(GLOBAL_PROPERTY);
+        this.global = StringUtils.isNotEmpty(globalStr) ? 
Boolean.parseBoolean(globalStr) : null;
+        String enableStr = properties.get(ENABLE_PROPERTY);
+        this.enable = StringUtils.isNotEmpty(enableStr) ? 
Boolean.parseBoolean(enableStr) : null;
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateSqlBlockRuleCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateSqlBlockRuleCommand.java
new file mode 100644
index 00000000000..ab8e1a1b268
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateSqlBlockRuleCommand.java
@@ -0,0 +1,99 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.analysis.StmtType;
+import org.apache.doris.blockrule.SqlBlockRule;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.FeNameFormat;
+import org.apache.doris.common.UserException;
+import org.apache.doris.common.util.SqlBlockUtil;
+import org.apache.doris.common.util.Util;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * create Sql block rule Commands.
+ */
+public class CreateSqlBlockRuleCommand extends SqlBlockRuleCommand {
+    private static final String NAME_TYPE = "SQL BLOCK RULE NAME";
+    private final boolean ifNotExists;
+
+    /**
+    * constructor
+    */
+    public CreateSqlBlockRuleCommand(String ruleName, boolean ifNotExists, 
Map<String, String> properties) {
+        super(ruleName, properties, PlanType.CREATE_SQL_BLOCK_RULE_COMMAND);
+        this.ifNotExists = ifNotExists;
+    }
+
+    @Override
+    public void doRun(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        // check name
+        FeNameFormat.checkCommonName(NAME_TYPE, ruleName);
+        // avoid a rule block any ddl for itself
+        if (StringUtils.isNotEmpty(sql) && 
Pattern.compile(sql).matcher(this.ruleName).find()) {
+            throw new AnalysisException("sql of SQL_BLOCK_RULE should not 
match its name");
+        }
+        Env.getCurrentEnv().getSqlBlockRuleMgr().createSqlBlockRule(new 
SqlBlockRule(ruleName, sql,
+                    sqlHash, partitionNum,
+                    tabletNum, cardinality, global, enable), ifNotExists);
+    }
+
+    @Override
+    public void setProperties(Map<String, String> properties) throws 
UserException {
+        this.sql = properties.getOrDefault(SQL_PROPERTY, 
SqlBlockRuleCommand.STRING_NOT_SET);
+        this.sqlHash = properties.getOrDefault(SQL_HASH_PROPERTY, 
SqlBlockRuleCommand.STRING_NOT_SET);
+        String partitionNumString = properties.get(SCANNED_PARTITION_NUM);
+        String tabletNumString = properties.get(SCANNED_TABLET_NUM);
+        String cardinalityString = properties.get(SCANNED_CARDINALITY);
+
+        SqlBlockUtil.checkSqlAndSqlHashSetBoth(sql, sqlHash);
+        SqlBlockUtil.checkPropertiesValidate(sql, sqlHash, partitionNumString, 
tabletNumString, cardinalityString);
+
+        this.partitionNum = Util.getLongPropertyOrDefault(partitionNumString, 
0L, null,
+                SCANNED_PARTITION_NUM + " should be a long");
+        this.tabletNum = Util.getLongPropertyOrDefault(tabletNumString, 0L, 
null,
+                SCANNED_TABLET_NUM + " should be a long");
+        this.cardinality = Util.getLongPropertyOrDefault(cardinalityString, 
0L, null,
+                SCANNED_CARDINALITY + " should be a long");
+
+        this.global = 
Util.getBooleanPropertyOrDefault(properties.get(GLOBAL_PROPERTY), false,
+                GLOBAL_PROPERTY + " should be a boolean");
+        this.enable = 
Util.getBooleanPropertyOrDefault(properties.get(ENABLE_PROPERTY), true,
+                ENABLE_PROPERTY + " should be a boolean");
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitCreateSqlBlockRuleCommand(this, context);
+    }
+
+    @Override
+    public StmtType stmtType() {
+        return StmtType.CREATE;
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/SqlBlockRuleCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/SqlBlockRuleCommand.java
new file mode 100644
index 00000000000..785da1aeb58
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/SqlBlockRuleCommand.java
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.UserException;
+import org.apache.doris.common.util.SqlBlockUtil;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Common class for SqlBlockRule Commands.
+ */
+public abstract class SqlBlockRuleCommand extends Command {
+    public static final String SQL_PROPERTY = "sql";
+
+    public static final String SQL_HASH_PROPERTY = "sqlHash";
+
+    public static final String SCANNED_PARTITION_NUM = "partition_num";
+
+    public static final String SCANNED_TABLET_NUM = "tablet_num";
+
+    public static final String SCANNED_CARDINALITY = "cardinality";
+
+    public static final String GLOBAL_PROPERTY = "global";
+
+    public static final String ENABLE_PROPERTY = "enable";
+
+    public static final Long LONG_NOT_SET = SqlBlockUtil.LONG_MINUS_ONE;
+
+    public static final String STRING_NOT_SET = SqlBlockUtil.STRING_DEFAULT;
+
+    private static final ImmutableSet<String> PROPERTIES_SET = new 
ImmutableSet.Builder<String>().add(SQL_PROPERTY)
+                        
.add(SQL_HASH_PROPERTY).add(GLOBAL_PROPERTY).add(ENABLE_PROPERTY).add(SCANNED_PARTITION_NUM)
+                        
.add(SCANNED_TABLET_NUM).add(SCANNED_CARDINALITY).build();
+
+    protected final String ruleName;
+
+    protected String sql;
+
+    protected String sqlHash;
+
+    protected Long partitionNum;
+
+    protected Long tabletNum;
+
+    protected Long cardinality;
+
+    // whether effective global, default is false
+    protected Boolean global;
+
+    // whether to use the rule, default is true
+    protected Boolean enable;
+
+    protected final Map<String, String> properties;
+
+    /**
+    * constructor
+    */
+    public SqlBlockRuleCommand(String ruleName, Map<String, String> 
properties, PlanType planType) {
+        super(planType);
+        this.ruleName = ruleName;
+        this.properties = properties;
+    }
+
+    private static void checkCommonProperties(Map<String, String> properties) 
throws UserException {
+        if (properties == null || properties.isEmpty()) {
+            throw new AnalysisException("Not set properties");
+        }
+        Optional<String> optional = properties.keySet().stream().filter(entity 
-> !PROPERTIES_SET.contains(entity))
+                .findFirst();
+        if (optional.isPresent()) {
+            throw new AnalysisException(optional.get() + " is invalid 
property");
+        }
+    }
+
+    @Override
+    public void run(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        if 
(!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), 
PrivPredicate.ADMIN)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"ADMIN");
+        }
+        // check properties
+        checkCommonProperties(properties);
+        setProperties(properties);
+        doRun(ctx, executor);
+    }
+
+    public abstract void doRun(ConnectContext ctx, StmtExecutor executor) 
throws Exception;
+
+    public abstract void setProperties(Map<String, String> properties) throws 
UserException;
+}
+
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
index fec52fd395f..d386d097a93 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
@@ -21,6 +21,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.AddConstraintCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterJobStatusCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterRoleCommand;
+import org.apache.doris.nereids.trees.plans.commands.AlterSqlBlockRuleCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterWorkloadGroupCommand;
 import 
org.apache.doris.nereids.trees.plans.commands.AlterWorkloadPolicyCommand;
@@ -36,6 +37,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateJobCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateSqlBlockRuleCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableLikeCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
@@ -471,6 +473,14 @@ public interface CommandVisitor<R, C> {
         return visitCommand(showLoadProfileCommand, context);
     }
 
+    default R visitAlterSqlBlockRuleCommand(AlterSqlBlockRuleCommand 
dropRoleCommand, C context) {
+        return visitCommand(dropRoleCommand, context);
+    }
+
+    default R visitCreateSqlBlockRuleCommand(CreateSqlBlockRuleCommand 
dropRoleCommand, C context) {
+        return visitCommand(dropRoleCommand, context);
+    }
+
     default R visitDropRoleCommand(DropRoleCommand dropRoleCommand, C context) 
{
         return visitCommand(dropRoleCommand, context);
     }
diff --git 
a/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy 
b/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
index 001c64fbc0d..f90b89dfb6e 100644
--- a/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
+++ b/regression-test/suites/sql_block_rule_p0/test_sql_block_rule.groovy
@@ -47,10 +47,7 @@ suite("test_sql_block_rule", "nonConcurrent") {
     """
     sql """ INSERT INTO table_2 VALUES ('H220427011909850160918','2022-04-27 
16:00:33'),('T220427400109910160949','2022-04-27 
16:00:54'),('T220427400123770120058','2022-04-27 
16:00:56'),('T220427400126530112854','2022-04-27 
16:00:34'),('T220427400127160144672','2022-04-27 
16:00:10'),('T220427400127900184511','2022-04-27 
16:00:34'),('T220427400129940120380','2022-04-27 
16:00:23'),('T220427400139720192986','2022-04-27 
16:00:34'),('T220427400140260152375','2022-04-27 16:00:02'),('T220427400 [...]
 
-    sql """
-                CREATE SQL_BLOCK_RULE if not exists test_rule_sql
-                PROPERTIES("sql"="SELECT \\\\* FROM table_2", "global"= 
"true", "enable"= "true")
-              """
+    checkNereidsExecute("CREATE SQL_BLOCK_RULE if not exists test_rule_sql 
PROPERTIES(\"sql\"=\"SELECT \\\\* FROM table_2\", \"global\"= \"true\", 
\"enable\"= \"true\")")
 
     test {
         sql("SELECT * FROM table_2", false)
@@ -66,10 +63,8 @@ suite("test_sql_block_rule", "nonConcurrent") {
         exception "sql match regex sql block rule: test_rule_sql"
     }
 
-    sql """
-        ALTER SQL_BLOCK_RULE test_rule_sql PROPERTIES("enable"="false")
-        """
-
+    checkNereidsExecute("ALTER SQL_BLOCK_RULE test_rule_sql 
PROPERTIES(\"enable\"=\"false\")")
+      
     sql "SELECT * FROM table_2"
 
     sql """


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

Reply via email to