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 0cab080a3f5 [Enhancement] (nereids) implement cancelBuildIndexCommand
in nereids (#49631)
0cab080a3f5 is described below
commit 0cab080a3f5b5e2043b85ca59fcf237c21e61d75
Author: yaoxiao <[email protected]>
AuthorDate: Mon May 19 09:42:42 2025 +0800
[Enhancement] (nereids) implement cancelBuildIndexCommand in nereids
(#49631)
Issue Number: close #42560
---
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 10 +-
.../apache/doris/alter/SchemaChangeHandler.java | 60 ++++++++++++
.../main/java/org/apache/doris/catalog/Env.java | 8 ++
.../doris/nereids/parser/LogicalPlanBuilder.java | 11 +++
.../apache/doris/nereids/trees/plans/PlanType.java | 1 +
.../plans/commands/CancelBuildIndexCommand.java | 106 +++++++++++++++++++++
.../trees/plans/visitor/CommandVisitor.java | 5 +
.../commands/CancelBuildIndexCommandTest.java | 87 +++++++++++++++++
8 files changed, 283 insertions(+), 5 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 eeefdcc5e65..2c58279d677 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
@@ -558,16 +558,16 @@ supportedCancelStatement
: CANCEL LOAD ((FROM | IN) database=identifier)? wildWhere?
#cancelLoad
| CANCEL EXPORT ((FROM | IN) database=identifier)? wildWhere?
#cancelExport
| CANCEL WARM UP JOB wildWhere?
#cancelWarmUpJob
- ;
-
-unsupportedCancelStatement
- : CANCEL ALTER TABLE (ROLLUP | (MATERIALIZED VIEW) | COLUMN)
+ | CANCEL ALTER TABLE (ROLLUP | (MATERIALIZED VIEW) | COLUMN)
FROM tableName=multipartIdentifier (LEFT_PAREN jobIds+=INTEGER_VALUE
(COMMA jobIds+=INTEGER_VALUE)* RIGHT_PAREN)?
#cancelAlterTable
| CANCEL BUILD INDEX ON tableName=multipartIdentifier
(LEFT_PAREN jobIds+=INTEGER_VALUE
(COMMA jobIds+=INTEGER_VALUE)* RIGHT_PAREN)?
#cancelBuildIndex
- | CANCEL DECOMMISSION BACKEND hostPorts+=STRING_LITERAL
+ ;
+
+unsupportedCancelStatement
+ : CANCEL DECOMMISSION BACKEND hostPorts+=STRING_LITERAL
(COMMA hostPorts+=STRING_LITERAL)*
#cancelDecommisionBackend
| CANCEL BACKUP ((FROM | IN) database=identifier)?
#cancelBackup
| CANCEL RESTORE ((FROM | IN) database=identifier)?
#cancelRestore
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index 5e742d11caa..caa16f0ac20 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -86,6 +86,7 @@ import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.trees.plans.commands.AlterCommand;
+import org.apache.doris.nereids.trees.plans.commands.CancelBuildIndexCommand;
import org.apache.doris.nereids.trees.plans.commands.info.ColumnDefinition;
import org.apache.doris.persist.AlterLightSchemaChangeInfo;
import org.apache.doris.persist.RemoveAlterJobV2OperationLog;
@@ -2635,6 +2636,65 @@ public class SchemaChangeHandler extends AlterHandler {
}
}
+ public void cancelIndexJob(CancelBuildIndexCommand command) throws
DdlException {
+ String dbName = command.getDbName();
+ String tableName = command.getTableName();
+ Preconditions.checkState(!Strings.isNullOrEmpty(dbName));
+ Preconditions.checkState(!Strings.isNullOrEmpty(tableName));
+
+ Database db =
Env.getCurrentInternalCatalog().getDbOrDdlException(dbName);
+
+ List<IndexChangeJob> jobList = new ArrayList<>();
+
+ Table olapTable = db.getTableOrDdlException(tableName,
Table.TableType.OLAP);
+ olapTable.writeLock();
+ try {
+ // find from index change jobs first
+ if (command.getAlterJobIdList() != null
+ && command.getAlterJobIdList().size() > 0) {
+ for (Long jobId : command.getAlterJobIdList()) {
+ IndexChangeJob job = indexChangeJobs.get(jobId);
+ if (job == null) {
+ continue;
+ }
+ jobList.add(job);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("add build index job {} on table {} for
specific id", jobId, tableName);
+ }
+ }
+ } else {
+ for (IndexChangeJob job : indexChangeJobs.values()) {
+ if (!job.isDone() && job.getTableId() ==
olapTable.getId()) {
+ jobList.add(job);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("add build index job {} on table {} for
all", job.getJobId(), tableName);
+ }
+ }
+ }
+ }
+ } finally {
+ olapTable.writeUnlock();
+ }
+
+ // alter job v2's cancel must be called outside the table lock
+ if (jobList.size() > 0) {
+ for (IndexChangeJob job : jobList) {
+ long jobId = job.getJobId();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("cancel build index job {} on table {}", jobId,
tableName);
+ }
+ if (!job.cancel("user cancelled")) {
+ LOG.warn("cancel build index job {} on table {} failed",
jobId, tableName);
+ throw new DdlException("Job can not be cancelled. State: "
+ job.getJobState());
+ } else {
+ LOG.info("cancel build index job {} on table {} success",
jobId, tableName);
+ }
+ }
+ } else {
+ throw new DdlException("No job to cancel for Table[" + tableName +
"]");
+ }
+ }
+
private void cancelIndexJob(CancelAlterTableStmt cancelAlterTableStmt)
throws DdlException {
String dbName = cancelAlterTableStmt.getDbName();
String tableName = cancelAlterTableStmt.getTableName();
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 cfebc422759..da07550bda7 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
@@ -207,6 +207,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AdminSetReplicaStatusComman
import org.apache.doris.nereids.trees.plans.commands.AlterSystemCommand;
import org.apache.doris.nereids.trees.plans.commands.AlterTableCommand;
import org.apache.doris.nereids.trees.plans.commands.AnalyzeCommand;
+import org.apache.doris.nereids.trees.plans.commands.CancelBuildIndexCommand;
import
org.apache.doris.nereids.trees.plans.commands.CreateMaterializedViewCommand;
import
org.apache.doris.nereids.trees.plans.commands.DropCatalogRecycleBinCommand.IdType;
import org.apache.doris.nereids.trees.plans.commands.TruncateTableCommand;
@@ -4972,6 +4973,13 @@ public class Env {
this.alter.processDropMaterializedView(stmt);
}
+ /*
+ * used for handling CancelIndexCommand
+ */
+ public void cancelBuildIndex(CancelBuildIndexCommand command) throws
DdlException {
+ this.getSchemaChangeHandler().cancelIndexJob(command);
+ }
+
/*
* used for handling CancelAlterStmt (for client is the CANCEL ALTER
* command). including SchemaChangeHandler and RollupHandler
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 85f20b41250..f6456eea7fd 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
@@ -567,6 +567,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AlterWorkloadPolicyCommand;
import org.apache.doris.nereids.trees.plans.commands.AnalyzeDatabaseCommand;
import org.apache.doris.nereids.trees.plans.commands.AnalyzeTableCommand;
import org.apache.doris.nereids.trees.plans.commands.CallCommand;
+import org.apache.doris.nereids.trees.plans.commands.CancelBuildIndexCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelExportCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelJobTaskCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelLoadCommand;
@@ -7055,6 +7056,16 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
return new KillAnalyzeJobCommand(jobId);
}
+ @Override
+ public LogicalPlan
visitCancelBuildIndex(DorisParser.CancelBuildIndexContext ctx) {
+ TableNameInfo tableNameInfo = new
TableNameInfo(visitMultipartIdentifier(ctx.tableName));
+ List<Long> jobIs = new ArrayList<>();
+ for (Token token : ctx.jobIds) {
+ jobIs.add(Long.parseLong(token.getText()));
+ }
+ return new CancelBuildIndexCommand(tableNameInfo, jobIs);
+ }
+
@Override
public PasswordOptions
visitPasswordOption(DorisParser.PasswordOptionContext ctx) {
int historyPolicy = PasswordOptions.UNSET;
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 413f4777ea1..cf44afa6e45 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
@@ -370,6 +370,7 @@ public enum PlanType {
TRANSACTION_ROLLBACK_COMMAND,
KILL_ANALYZE_JOB_COMMAND,
DROP_ANALYZE_JOB_COMMAND,
+ CANCEL_BUILD_INDEX_COMMAND,
CREATE_USER_COMMAND,
CREATE_RESOURCE_COMMAND,
CREATE_DATA_SYNC_JOB_COMMAND,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommand.java
new file mode 100644
index 00000000000..ef72a506424
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommand.java
@@ -0,0 +1,106 @@
+// 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.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.FeConstants;
+import org.apache.doris.common.util.Util;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * CancelBuildIndexCommand
+ */
+public class CancelBuildIndexCommand extends CancelCommand {
+ private final TableNameInfo tableNameInfo;
+ private final List<Long> alterJobIdList;
+
+ /**
+ * CancelBuildIndexCommand
+ */
+ public CancelBuildIndexCommand(TableNameInfo tableNameInfo,
+ List<Long> alterJobIdList) {
+ super(PlanType.CANCEL_BUILD_INDEX_COMMAND);
+ Objects.requireNonNull(tableNameInfo, "tableNameInfo is null");
+ Objects.requireNonNull(alterJobIdList, "alterJobIdList is null");
+ this.tableNameInfo = tableNameInfo;
+ this.alterJobIdList = alterJobIdList;
+ }
+
+ public String getDbName() {
+ return tableNameInfo.getDb();
+ }
+
+ public String getTableName() {
+ return tableNameInfo.getTbl();
+ }
+
+ public List<Long> getAlterJobIdList() {
+ return alterJobIdList;
+ }
+
+ @Override
+ public void run(ConnectContext ctx, StmtExecutor executor) throws
Exception {
+ validate(ctx);
+ ctx.getEnv().cancelBuildIndex(this);
+ }
+
+ /**
+ * validate
+ */
+ public void validate(ConnectContext ctx) throws AnalysisException {
+ tableNameInfo.analyze(ctx);
+ // disallow external catalog
+ Util.prohibitExternalCatalog(tableNameInfo.getCtl(),
this.getClass().getSimpleName());
+
+ if (FeConstants.runningUnitTest) {
+ return;
+ }
+ // check access
+ if (!Env.getCurrentEnv().getAccessManager()
+ .checkTblPriv(ConnectContext.get(), tableNameInfo.getCtl(),
tableNameInfo.getDb(),
+ tableNameInfo.getTbl(),
+ PrivPredicate.ALTER)) {
+
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR,
"CANCEL ALTER TABLE",
+ ConnectContext.get().getQualifiedUser(),
+ ConnectContext.get().getRemoteIP(),
+ tableNameInfo.getDb() + ": " + tableNameInfo.getTbl());
+ }
+ }
+
+ @Override
+ public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+ return visitor.visitCancelBuildIndexCommand(this, context);
+ }
+
+ @Override
+ public StmtType stmtType() {
+ return StmtType.CANCEL;
+ }
+}
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 b032d033794..32190e1a0f1 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
@@ -45,6 +45,7 @@ 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;
import org.apache.doris.nereids.trees.plans.commands.CallCommand;
+import org.apache.doris.nereids.trees.plans.commands.CancelBuildIndexCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelExportCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelJobTaskCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelLoadCommand;
@@ -1091,6 +1092,10 @@ public interface CommandVisitor<R, C> {
return visitCommand(dropAnalyzeJobCommand, context);
}
+ default R visitCancelBuildIndexCommand(CancelBuildIndexCommand
cancelBuildIndexCommand, C context) {
+ return visitCommand(cancelBuildIndexCommand, context);
+ }
+
default R visitCreateUserCommand(CreateUserCommand createUserCommand, C
context) {
return visitCommand(createUserCommand, context);
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommandTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommandTest.java
new file mode 100644
index 00000000000..e6b7e8e4e77
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/CancelBuildIndexCommandTest.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.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.datasource.InternalCatalog;
+import org.apache.doris.mysql.privilege.AccessControllerManager;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo;
+import org.apache.doris.qe.ConnectContext;
+
+import mockit.Expectations;
+import mockit.Mocked;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CancelBuildIndexCommandTest {
+ private static final String internalCtl =
InternalCatalog.INTERNAL_CATALOG_NAME;
+ @Mocked
+ private Env env;
+ @Mocked
+ private ConnectContext connectContext;
+ @Mocked
+ private AccessControllerManager accessControllerManager;
+
+ private final String dbName = "test_db";
+ private final String tblName = "test_tbl";
+
+ private void runBefore() {
+ new Expectations() {
+ {
+ Env.getCurrentEnv();
+ minTimes = 0;
+ result = env;
+
+ env.getAccessManager();
+ minTimes = 0;
+ result = accessControllerManager;
+
+ ConnectContext.get();
+ minTimes = 0;
+ result = connectContext;
+
+ connectContext.isSkipAuth();
+ minTimes = 0;
+ result = true;
+
+ accessControllerManager.checkTblPriv(connectContext,
internalCtl, dbName, tblName, PrivPredicate.ALTER);
+ minTimes = 0;
+ result = true;
+ }
+ };
+ }
+
+ @Test
+ public void testValidateNormal() throws Exception {
+ runBefore();
+ TableNameInfo tableNameInfo = new TableNameInfo(dbName, tblName);
+ List<Long> alterJobIdList = new ArrayList<>();
+ CancelBuildIndexCommand command = new
CancelBuildIndexCommand(tableNameInfo, alterJobIdList);
+ Assertions.assertDoesNotThrow(() -> command.validate(connectContext));
+
+ TableNameInfo tableNameInfo02 = new TableNameInfo("hive", dbName,
tblName);
+ CancelBuildIndexCommand command02 = new
CancelBuildIndexCommand(tableNameInfo02, alterJobIdList);
+ Assertions.assertThrows(AnalysisException.class, () ->
command02.validate(connectContext),
+ "External catalog 'hive' is not allowed in
'CancelAlterTableCommand'");
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]