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 2e02d541a21 [Enhancement] (nereids)implement
adminSetFrontendConfigCommand in nereids (#50616)
2e02d541a21 is described below
commit 2e02d541a21d97224a80425ae034cb439958fa0d
Author: csding <[email protected]>
AuthorDate: Tue Jun 17 09:13:11 2025 +0800
[Enhancement] (nereids)implement adminSetFrontendConfigCommand in nereids
(#50616)
Issue Number: close https://github.com/apache/doris/issues/42842
---
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 6 +-
.../main/java/org/apache/doris/catalog/Env.java | 31 +++++
.../doris/nereids/parser/LogicalPlanBuilder.java | 12 ++
.../apache/doris/nereids/trees/plans/PlanType.java | 1 +
.../commands/AdminSetFrontendConfigCommand.java | 126 +++++++++++++++++++++
.../trees/plans/commands/GrantRoleCommand.java | 15 +++
.../trees/plans/visitor/CommandVisitor.java | 5 +
.../AdminSetFrontendConfigCommandTest.java | 99 ++++++++++++++++
8 files changed, 292 insertions(+), 3 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 c96f26d9dbe..f10eb703354 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
@@ -573,6 +573,8 @@ supportedAdminStatement
| ADMIN COMPACT TABLE baseTableRef (WHERE TYPE EQ STRING_LITERAL)?
#adminCompactTable
| ADMIN CHECK tabletList properties=propertyClause?
#adminCheckTablets
| ADMIN SHOW TABLET STORAGE FORMAT VERBOSE?
#adminShowTabletStorageFormat
+ | ADMIN SET (FRONTEND | (ALL FRONTENDS)) CONFIG
+ (LEFT_PAREN propertyItemList RIGHT_PAREN)? ALL?
#adminSetFrontendConfig
| ADMIN CLEAN TRASH
(ON LEFT_PAREN backends+=STRING_LITERAL
(COMMA backends+=STRING_LITERAL)* RIGHT_PAREN)?
#adminCleanTrash
@@ -593,9 +595,7 @@ supportedRecoverStatement
;
unsupportedAdminStatement
- : ADMIN SET (FRONTEND | (ALL FRONTENDS)) CONFIG
- (LEFT_PAREN propertyItemList RIGHT_PAREN)? ALL?
#adminSetFrontendConfig
- | ADMIN SET TABLE name=multipartIdentifier
+ : ADMIN SET TABLE name=multipartIdentifier
PARTITION VERSION properties=propertyClause?
#adminSetPartitionVersion
;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index f3473197d31..6572f435c1e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -200,6 +200,7 @@ import org.apache.doris.mysql.privilege.Auth;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.jobs.load.LabelProcessor;
import org.apache.doris.nereids.stats.HboPlanStatisticsManager;
+import
org.apache.doris.nereids.trees.plans.commands.AdminSetFrontendConfigCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaStatusCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaVersionCommand;
import org.apache.doris.nereids.trees.plans.commands.AlterSystemCommand;
@@ -6230,6 +6231,36 @@ public class Env {
}
}
+ public void setConfig(AdminSetFrontendConfigCommand command) throws
Exception {
+ Map<String, String> configs = command.getConfigs();
+ Preconditions.checkState(configs.size() == 1);
+
+ for (Map.Entry<String, String> entry : configs.entrySet()) {
+ try {
+ setMutableConfigWithCallback(entry.getKey(), entry.getValue());
+ } catch (ConfigException e) {
+ throw new DdlException(e.getMessage());
+ }
+ }
+
+ if (command.isApplyToAll()) {
+ for (Frontend fe : Env.getCurrentEnv().getFrontends(null /* all
*/)) {
+ if (!fe.isAlive() ||
fe.getHost().equals(Env.getCurrentEnv().getSelfNode().getHost())) {
+ continue;
+ }
+
+ TNetworkAddress feAddr = new TNetworkAddress(fe.getHost(),
fe.getRpcPort());
+ FEOpExecutor executor = new FEOpExecutor(feAddr,
command.getLocalSetStmt(),
+ ConnectContext.get(), false);
+ executor.execute();
+ if (executor.getStatusCode() != TStatusCode.OK.getValue()) {
+ throw new DdlException(String.format("failed to apply to
fe %s:%s, error message: %s",
+ fe.getHost(), fe.getRpcPort(), executor.getErrMsg()));
+ }
+ }
+ }
+ }
+
public void replayBackendReplicasInfo(BackendReplicasInfo
backendReplicasInfo) {
long backendId = backendReplicasInfo.getBackendId();
List<BackendReplicasInfo.ReplicaReportInfo> replicaInfos =
backendReplicasInfo.getReplicaReportInfos();
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 787c2822829..d7ce43c3c5a 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
@@ -564,6 +564,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AdminCompactTableCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminCopyTabletCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRepairTableCommand;
+import
org.apache.doris.nereids.trees.plans.commands.AdminSetFrontendConfigCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaStatusCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaVersionCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetTableStatusCommand;
@@ -5839,6 +5840,17 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
return new
AdminSetReplicaVersionCommand(visitPropertyItemList(ctx.propertyItemList()));
}
+ @Override
+ public LogicalPlan
visitAdminSetFrontendConfig(DorisParser.AdminSetFrontendConfigContext ctx) {
+ Map<String, String> configs =
visitPropertyItemList(ctx.propertyItemList());
+ boolean applyToAll = !ctx.ALL().isEmpty();
+
+ return new AdminSetFrontendConfigCommand(
+ NodeType.FRONTEND,
+ configs,
+ applyToAll);
+ }
+
@Override
public LogicalPlan visitShowFrontends(ShowFrontendsContext ctx) {
String detail = (ctx.name != null) ? ctx.name.getText() : null;
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 6bf9bb8938b..76f0ae6c464 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
@@ -332,6 +332,7 @@ public enum PlanType {
ADMIN_REBALANCE_DISK_COMMAND,
ADMIN_SET_REPLICA_VERSION_COMMAND,
ADMIN_CANCEL_REBALANCE_DISK_COMMAND,
+ ADMIN_SET_FRONTEND_CONFIG_COMMAND,
CREATE_ENCRYPTKEY_COMMAND,
CREATE_WORKLOAD_GROUP_COMMAND,
CREATE_CATALOG_COMMAND,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommand.java
new file mode 100644
index 00000000000..3c7e8d282f2
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommand.java
@@ -0,0 +1,126 @@
+// 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.RedirectStatus;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.ConfigBase;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.UserException;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+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.OriginStatement;
+import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.system.NodeType;
+
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * admin set frontend config ("key" = "value");
+ */
+public class AdminSetFrontendConfigCommand extends Command implements
ForwardWithSync {
+ private boolean applyToAll;
+ private NodeType type;
+ private Map<String, String> configs;
+ private OriginStatement originStmt;
+
+ private RedirectStatus redirectStatus = RedirectStatus.NO_FORWARD;
+
+ /**
+ * AdminSetFrontendConfigCommand
+ */
+ public AdminSetFrontendConfigCommand(NodeType type, Map<String, String>
configs, boolean applyToAll) {
+ super(PlanType.ADMIN_SET_FRONTEND_CONFIG_COMMAND);
+ this.type = type;
+ this.configs = configs;
+ if (this.configs == null) {
+ this.configs = Maps.newHashMap();
+ }
+ this.applyToAll = applyToAll;
+
+ // we have to analyze configs here to determine whether to forward it
to master
+ for (String key : this.configs.keySet()) {
+ if (ConfigBase.checkIsMasterOnly(key)) {
+ redirectStatus = RedirectStatus.FORWARD_NO_SYNC;
+ this.applyToAll = false;
+ }
+ }
+ }
+
+ @Override
+ public void run(ConnectContext ctx, StmtExecutor executor) throws
Exception {
+ validate();
+ originStmt = ctx.getStatementContext().getOriginStatement();
+ Env.getCurrentEnv().setConfig(this);
+ }
+
+ /**
+ * validate
+ */
+ public void validate() throws UserException {
+ if (configs.size() != 1) {
+ throw new AnalysisException("config parameter size is not equal to
1");
+ }
+ // check auth
+ if
(!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(),
PrivPredicate.ADMIN)) {
+
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR,
"ADMIN");
+ }
+
+ if (type != NodeType.FRONTEND) {
+ throw new AnalysisException("Only support setting Frontend configs
now");
+ }
+ }
+
+ @Override
+ public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+ return visitor.visitAdminSetFrontendConfigCommand(this, context);
+ }
+
+ public boolean isApplyToAll() {
+ return applyToAll;
+ }
+
+ public NodeType getNodeTypeType() {
+ return type;
+ }
+
+ public Map<String, String> getConfigs() {
+ return configs;
+ }
+
+ public RedirectStatus getRedirectStatus() {
+ return redirectStatus;
+ }
+
+ /**
+ * getLocalSetStmt
+ */
+ public OriginStatement getLocalSetStmt() {
+ Object[] keyArr = configs.keySet().toArray();
+ String sql = String.format("ADMIN SET FRONTEND CONFIG (\"%s\" =
\"%s\");",
+ keyArr[0].toString(), configs.get(keyArr[0].toString()));
+
+ return new OriginStatement(sql, originStmt.idx);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/GrantRoleCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/GrantRoleCommand.java
index a685f574512..531a9e6e196 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/GrantRoleCommand.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/GrantRoleCommand.java
@@ -21,8 +21,10 @@ import org.apache.doris.analysis.StmtType;
import org.apache.doris.analysis.UserIdentity;
import org.apache.doris.catalog.Env;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.FeNameFormat;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
@@ -55,8 +57,21 @@ public class GrantRoleCommand extends Command implements
ForwardWithSync {
Env.getCurrentEnv().getAuth().grantRoleCommand(this);
}
+ /**
+ * validate
+ */
public void validate() throws AnalysisException {
+ if (Config.access_controller_type.equalsIgnoreCase("ranger-doris")) {
+ throw new AnalysisException("Grant is prohibited when Ranger is
enabled.");
+ }
+
userIdentity.analyze();
+
+ for (int i = 0; i < roles.size(); i++) {
+ String originalRoleName = roles.get(i);
+ FeNameFormat.checkRoleName(originalRoleName, true /* can be admin
*/, "Can not grant role");
+ }
+
checkRolePrivileges();
}
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 9e11ffc4857..73c6727395b 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
@@ -26,6 +26,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AdminCompactTableCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminCopyTabletCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRepairTableCommand;
+import
org.apache.doris.nereids.trees.plans.commands.AdminSetFrontendConfigCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaStatusCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaVersionCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetTableStatusCommand;
@@ -1278,6 +1279,10 @@ public interface CommandVisitor<R, C> {
return visitCommand(command, context);
}
+ default R visitAdminSetFrontendConfigCommand(AdminSetFrontendConfigCommand
command, C context) {
+ return visitCommand(command, context);
+ }
+
default R visitRevokeRoleCommand(RevokeRoleCommand revokeRoleCommand, C
context) {
return visitCommand(revokeRoleCommand, context);
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommandTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommandTest.java
new file mode 100644
index 00000000000..5884e5c2422
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/AdminSetFrontendConfigCommandTest.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.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.CaseSensibility;
+import org.apache.doris.common.Config;
+import org.apache.doris.common.ConfigBase;
+import org.apache.doris.common.PatternMatcher;
+import org.apache.doris.common.PatternMatcherWrapper;
+import org.apache.doris.common.VariableAnnotation;
+import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.utframe.TestWithFeService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+public class AdminSetFrontendConfigCommandTest extends TestWithFeService {
+ @Test
+ public void testNormal() throws Exception {
+ String sql = "admin set frontend config(\"alter_table_timeout_second\"
= \"60\");";
+ LogicalPlan plan = new NereidsParser().parseSingle(sql);
+ Assertions.assertTrue(plan instanceof AdminSetFrontendConfigCommand);
+ Assertions.assertDoesNotThrow(() -> ((AdminSetFrontendConfigCommand)
plan).validate());
+ }
+
+ @Test
+ public void testEmptyConfig() {
+ String sql = "admin set frontend config;";
+ LogicalPlan plan = new NereidsParser().parseSingle(sql);
+ Assertions.assertTrue(plan instanceof AdminSetFrontendConfigCommand);
+ AnalysisException exception =
Assertions.assertThrows(AnalysisException.class,
+ () -> ((AdminSetFrontendConfigCommand) plan).validate());
+ Assertions.assertEquals("errCode = 2, detailMessage = config parameter
size is not equal to 1",
+ exception.getMessage());
+ }
+
+ @Test
+ public void testExperimentalConfig() throws Exception {
+ // 1. set without experimental
+ boolean enableMtmv = Config.enable_mtmv;
+ String sql = "admin set frontend config('enable_mtmv' = '" +
String.valueOf(!enableMtmv) + "');";
+ LogicalPlan plan = new NereidsParser().parseSingle(sql);
+
+ Assertions.assertTrue(plan instanceof AdminSetFrontendConfigCommand);
+ Env.getCurrentEnv().setConfig((AdminSetFrontendConfigCommand) plan);
+ Assertions.assertNotEquals(enableMtmv, Config.enable_mtmv);
+
+ // 2. set with experimental
+ enableMtmv = Config.enable_mtmv;
+ sql = "admin set frontend config('experimental_enable_mtmv' = '" +
String.valueOf(!enableMtmv) + "');";
+ plan = new NereidsParser().parseSingle(sql);
+
+ Assertions.assertTrue(plan instanceof AdminSetFrontendConfigCommand);
+ Env.getCurrentEnv().setConfig((AdminSetFrontendConfigCommand) plan);
+ Assertions.assertNotEquals(enableMtmv, Config.enable_mtmv);
+
+ // 3. show config
+ int num =
ConfigBase.getConfigNumByVariableAnnotation(VariableAnnotation.EXPERIMENTAL);
+ PatternMatcher matcher =
PatternMatcherWrapper.createMysqlPattern("%experimental%",
+ CaseSensibility.CONFIG.getCaseSensibility());
+ List<List<String>> results = ConfigBase.getConfigInfo(matcher);
+ Assertions.assertEquals(num, results.size());
+
+ num =
ConfigBase.getConfigNumByVariableAnnotation(VariableAnnotation.DEPRECATED);
+ matcher = PatternMatcherWrapper.createMysqlPattern("%deprecated%",
+ CaseSensibility.CONFIG.getCaseSensibility());
+ results = ConfigBase.getConfigInfo(matcher);
+ Assertions.assertEquals(num, results.size());
+ }
+
+ @Test
+ public void testTrimPropertyKey() throws Exception {
+ String sql = "admin set frontend config(\" alter_table_timeout_second
\" = \"60\");";
+ LogicalPlan plan = new NereidsParser().parseSingle(sql);
+
+ Assertions.assertTrue(plan instanceof AdminSetFrontendConfigCommand);
+ Assertions.assertEquals("60", ((AdminSetFrontendConfigCommand)
plan).getConfigs().get("alter_table_timeout_second"));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]