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 5fd21da747e7dd..288fa87fd9daa8 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 @@ -57,6 +57,7 @@ statementBase | supportedSetStatement #supportedSetStatementAlias | supportedUnsetStatement #supportedUnsetStatementAlias | supportedRefreshStatement #supportedRefreshStatementAlias + | supportedStatsStatement #supportedStatsStatementAlias | supportedShowStatement #supportedShowStatementAlias | supportedLoadStatement #supportedLoadStatementAlias | supportedCancelStatement #supportedCancelStatementAlias @@ -708,6 +709,10 @@ unsupportedDropStatement | DROP STAGE (IF EXISTS)? name=identifier #dropStage ; +supportedStatsStatement + : SHOW ANALYZE TASK STATUS jobId=INTEGER_VALUE #showAnalyzeTask + ; + unsupportedStatsStatement : ANALYZE TABLE name=multipartIdentifier partitionSpec? columns=identifierList? (WITH analyzeProperties)* propertyClause? #analyzeTable @@ -735,7 +740,6 @@ unsupportedStatsStatement | SHOW AUTO? ANALYZE tableName=multipartIdentifier? wildWhere? #showAnalyze | SHOW ANALYZE jobId=INTEGER_VALUE wildWhere? #showAnalyzeFromJobId | SHOW AUTO JOBS tableName=multipartIdentifier? wildWhere? #showAutoAnalyzeJobs - | SHOW ANALYZE TASK STATUS jobId=INTEGER_VALUE #showAnalyzeTask ; analyzeProperties 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 0432e06c335472..2e71cd4d4395b0 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 @@ -270,6 +270,7 @@ import org.apache.doris.nereids.DorisParser.SetUserVariableContext; import org.apache.doris.nereids.DorisParser.SetVariableWithTypeContext; import org.apache.doris.nereids.DorisParser.ShowAllPropertiesContext; +import org.apache.doris.nereids.DorisParser.ShowAnalyzeTaskContext; import org.apache.doris.nereids.DorisParser.ShowAuthorsContext; import org.apache.doris.nereids.DorisParser.ShowBackendsContext; import org.apache.doris.nereids.DorisParser.ShowBrokerContext; @@ -557,6 +558,7 @@ import org.apache.doris.nereids.trees.plans.commands.SetOptionsCommand; import org.apache.doris.nereids.trees.plans.commands.SetTransactionCommand; import org.apache.doris.nereids.trees.plans.commands.SetUserPropertiesCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowAnalyzeTaskCommand; import org.apache.doris.nereids.trees.plans.commands.ShowAuthorsCommand; import org.apache.doris.nereids.trees.plans.commands.ShowBackendsCommand; import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand; @@ -4138,6 +4140,12 @@ public LogicalPlan visitShowAuthors(ShowAuthorsContext ctx) { return new ShowAuthorsCommand(); } + @Override + public LogicalPlan visitShowAnalyzeTask(ShowAnalyzeTaskContext ctx) { + long jobId = Long.parseLong(ctx.jobId.getText()); + return new ShowAnalyzeTaskCommand(jobId); + } + @Override public LogicalPlan visitShowEvents(ShowEventsContext ctx) { return new ShowEventsCommand(); 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 1c0cb26f0f0702..2c1e03fa7cf809 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 @@ -211,6 +211,7 @@ public enum PlanType { ADMIN_SET_TABLE_STATUS_COMMAND, ALTER_CATALOG_COMMENT_COMMAND, ALTER_SQL_BLOCK_RULE_COMMAND, + SHOW_ANALYZE_TASK_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/ShowAnalyzeTaskCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowAnalyzeTaskCommand.java new file mode 100644 index 00000000000000..7d12241ab6e859 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowAnalyzeTaskCommand.java @@ -0,0 +1,104 @@ +// 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.Column; +import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.OlapTable; +import org.apache.doris.catalog.ScalarType; +import org.apache.doris.catalog.TableIf; +import org.apache.doris.common.UserException; +import org.apache.doris.common.util.TimeUtils; +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.ShowResultSet; +import org.apache.doris.qe.ShowResultSetMetaData; +import org.apache.doris.qe.StmtExecutor; +import org.apache.doris.statistics.AnalysisInfo; +import org.apache.doris.statistics.util.StatisticsUtil; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents the command for SHOW ANALYZE TASK STATUS. + */ +public class ShowAnalyzeTaskCommand extends ShowCommand { + private static final ShowResultSetMetaData ROW_META_DATA = + ShowResultSetMetaData.builder() + .addColumn(new Column("task_id", ScalarType.createVarchar(100))) + .addColumn(new Column("col_name", ScalarType.createVarchar(1000))) + .addColumn(new Column("index_name", ScalarType.createVarchar(1000))) + .addColumn(new Column("message", ScalarType.createVarchar(1000))) + .addColumn(new Column("last_state_change_time", ScalarType.createVarchar(1000))) + .addColumn(new Column("time_cost_in_ms", ScalarType.createVarchar(1000))) + .addColumn(new Column("state", ScalarType.createVarchar(1000))).build(); + + private final long jobId; + + public ShowAnalyzeTaskCommand(long jobId) { + super(PlanType.SHOW_ANALYZE_TASK_COMMAND); + this.jobId = jobId; + } + + @Override + public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) throws Exception { + if (!ConnectContext.get().getSessionVariable().enableStats) { + throw new UserException("Analyze function is forbidden, you should add `enable_stats=true`" + + "in your FE conf file"); + } + AnalysisInfo jobInfo = Env.getCurrentEnv().getAnalysisManager().findJobInfo(jobId); + TableIf table = StatisticsUtil.findTable(jobInfo.catalogId, jobInfo.dbId, jobInfo.tblId); + List analysisInfos = Env.getCurrentEnv().getAnalysisManager().findTasks(jobId); + List> rows = new ArrayList<>(); + for (AnalysisInfo analysisInfo : analysisInfos) { + List row = new ArrayList<>(); + row.add(String.valueOf(analysisInfo.taskId)); + row.add(analysisInfo.colName); + if (table instanceof OlapTable && analysisInfo.indexId != -1) { + row.add(((OlapTable) table).getIndexNameById(analysisInfo.indexId)); + } else { + row.add(table.getName()); + } + row.add(analysisInfo.message); + row.add(TimeUtils.getDatetimeFormatWithTimeZone().format( + LocalDateTime.ofInstant(Instant.ofEpochMilli(analysisInfo.lastExecTimeInMs), + ZoneId.systemDefault()))); + row.add(String.valueOf(analysisInfo.timeCostInMs)); + row.add(analysisInfo.state.toString()); + rows.add(row); + } + return new ShowResultSet(ROW_META_DATA, rows); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitShowAnalyzeTaskCommand(this, context); + } + + @Override + public RedirectStatus toRedirectStatus() { + return RedirectStatus.FORWARD_NO_SYNC; + } +} + 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 0f5cafa919227c..401b852583d374 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 @@ -90,6 +90,7 @@ import org.apache.doris.nereids.trees.plans.commands.SetOptionsCommand; import org.apache.doris.nereids.trees.plans.commands.SetTransactionCommand; import org.apache.doris.nereids.trees.plans.commands.SetUserPropertiesCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowAnalyzeTaskCommand; import org.apache.doris.nereids.trees.plans.commands.ShowAuthorsCommand; import org.apache.doris.nereids.trees.plans.commands.ShowBackendsCommand; import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand; @@ -388,6 +389,10 @@ default R visitUnsupportedCommand(UnsupportedCommand unsupportedCommand, C conte return visitCommand(unsupportedCommand, context); } + default R visitShowAnalyzeTaskCommand(ShowAnalyzeTaskCommand showAnalyzeTaskCommand, C context) { + return visitCommand(showAnalyzeTaskCommand, context); + } + default R visitUnsetVariableCommand(UnsetVariableCommand unsetVariableCommand, C context) { return visitCommand(unsetVariableCommand, context); }