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

morrysnow 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 ad78f313be [Improvement](statistics) show analysis job info (#16305)
ad78f313be is described below

commit ad78f313be91e5c0aca728d4f54d1f43c785169e
Author: ElvinWei <[email protected]>
AuthorDate: Fri Feb 3 23:21:47 2023 +0800

    [Improvement](statistics) show analysis job info (#16305)
    
    Supports query analysis job info.
    
    syntax:
    
    ```SQL
    SHOW ANALYZE
        [TABLE | ID]
        [
            WHERE
            [STATE = ["PENDING"|"RUNNING"|"FINISHED"|"FAILED"]]
        ]
        [ORDER BY ...]
        [LIMIT limit];
    ```
    example:
    
    ```SQL
    SHOW ANALYZE test_table1 WHERE state = 'FINISHED' ORDER BY col_name LIMIT 1;
    ```
    
    result:
    
    | job_id  | catalog_name | db_name              | tbl_name    | col_name | 
job_type | analysis_type | message | last_exec_time_in_ms | state    | 
schedule_type |
    | ------ |  ------------ | -------------------- | ----------- | -------- | 
-------- | ------------- | ------- | -------------------- | -------- | 
------------- |
    | 10086   | internal     | default_cluster:test | test_table1 | pv       | 
MANUAL   | FULL          |         | 2023-02-01 09:36:41          | FINISHED | 
ONCE          |
---
 fe/fe-core/src/main/cup/sql_parser.cup             |   8 +-
 .../org/apache/doris/analysis/ShowAnalyzeStmt.java | 165 ++++++++++++---------
 .../java/org/apache/doris/qe/ShowExecutor.java     |  34 ++++-
 .../apache/doris/statistics/AnalysisManager.java   |  49 +++++-
 4 files changed, 174 insertions(+), 82 deletions(-)

diff --git a/fe/fe-core/src/main/cup/sql_parser.cup 
b/fe/fe-core/src/main/cup/sql_parser.cup
index 1873ecf5fe..cf2ae1a843 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -3831,14 +3831,14 @@ show_param ::=
         RESULT = new ShowCreateMaterializedViewStmt(mvName, tableName);
     :}
     /* show analyze job */
-    | KW_ANALYZE integer_list:jobIds
-    {:
-        RESULT = new ShowAnalyzeStmt(jobIds);
-    :}
     | KW_ANALYZE opt_table_name:tbl opt_wild_where 
order_by_clause:orderByClause limit_clause:limitClause
     {:
         RESULT = new ShowAnalyzeStmt(tbl, parser.where, orderByClause, 
limitClause);
     :}
+    | KW_ANALYZE INTEGER_LITERAL:jobId opt_wild_where 
order_by_clause:orderByClause limit_clause:limitClause
+    {:
+        RESULT = new ShowAnalyzeStmt(jobId, parser.where, orderByClause, 
limitClause);
+    :}
     | KW_CATALOG KW_RECYCLE KW_BIN opt_wild_where
     {:
         RESULT = new ShowCatalogRecycleBinStmt(parser.where);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowAnalyzeStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowAnalyzeStmt.java
index a153b77ce6..a21bb340bf 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowAnalyzeStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowAnalyzeStmt.java
@@ -18,10 +18,8 @@
 package org.apache.doris.analysis;
 
 import org.apache.doris.catalog.Column;
-import org.apache.doris.catalog.Database;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.ScalarType;
-import org.apache.doris.catalog.Table;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
@@ -31,15 +29,14 @@ import org.apache.doris.mysql.privilege.PaloAuth;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.ShowResultSetMetaData;
+import org.apache.doris.statistics.AnalysisState;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.IntStream;
 
 /**
@@ -49,33 +46,37 @@ import java.util.stream.IntStream;
  *        [TABLE | ID]
  *        [
  *            WHERE
- *            [STATE = 
["PENDING"|"SCHEDULING"|"RUNNING"|"FINISHED"|"FAILED"|"CANCELLED"]]
+ *            [STATE = ["PENDING"|"RUNNING"|"FINISHED"|"FAILED"]]
  *        ]
  *        [ORDER BY ...]
- *        [LIMIT limit][OFFSET offset];
+ *        [LIMIT limit];
  */
 public class ShowAnalyzeStmt extends ShowStmt {
     private static final String STATE_NAME = "state";
     private static final ImmutableList<String> TITLE_NAMES = new 
ImmutableList.Builder<String>()
-            .add("id")
-            .add("create_time")
-            .add("start_time")
-            .add("finish_time")
-            .add("error_msg")
-            .add("scope")
-            .add("progress")
+            .add("job_id")
+            .add("catalog_name")
+            .add("db_name")
+            .add("tbl_name")
+            .add("col_name")
+            .add("job_type")
+            .add("analysis_type")
+            .add("message")
+            .add("last_exec_time_in_ms")
             .add("state")
+            .add("schedule_type")
             .build();
 
-    private List<Long> jobIds;
+    private Long jobId;
     private TableName dbTableName;
     private Expr whereClause;
     private LimitElement limitElement;
     private List<OrderByElement> orderByElements;
 
     // after analyzed
-    private long dbId;
-    private final Set<Long> tblIds = Sets.newHashSet();
+    private String catalogName;
+    private String dbName;
+    private String tblName;
 
     private String stateValue;
     private ArrayList<OrderByPair> orderByPairs;
@@ -83,10 +84,6 @@ public class ShowAnalyzeStmt extends ShowStmt {
     public ShowAnalyzeStmt() {
     }
 
-    public ShowAnalyzeStmt(List<Long> jobIds) {
-        this.jobIds = jobIds;
-    }
-
     public ShowAnalyzeStmt(TableName dbTableName,
                            Expr whereClause,
                            List<OrderByElement> orderByElements,
@@ -97,44 +94,91 @@ public class ShowAnalyzeStmt extends ShowStmt {
         this.limitElement = limitElement;
     }
 
-    public List<Long> getJobIds() {
-        return jobIds;
+    public ShowAnalyzeStmt(Long jobId,
+            Expr whereClause,
+            List<OrderByElement> orderByElements,
+            LimitElement limitElement) {
+        this.jobId = jobId;
+        this.dbTableName = null;
+        this.whereClause = whereClause;
+        this.orderByElements = orderByElements;
+        this.limitElement = limitElement;
+    }
+
+    public ImmutableList<String> getTitleNames() {
+        return TITLE_NAMES;
+    }
+
+    public Long getJobId() {
+        return jobId;
+    }
+
+    public String getCatalogName() {
+        Preconditions.checkArgument(isAnalyzed(),
+                "The catalogName must be obtained after the parsing is 
complete");
+        return catalogName;
     }
 
-    public long getDbId() {
+    public String getDbName() {
         Preconditions.checkArgument(isAnalyzed(),
-                "The dbId must be obtained after the parsing is complete");
-        return dbId;
+                "The dbName must be obtained after the parsing is complete");
+        return dbName;
     }
 
-    public Set<Long> getTblIds() {
+    public String getTblName() {
         Preconditions.checkArgument(isAnalyzed(),
-                "The dbId must be obtained after the parsing is complete");
-        return tblIds;
+                "The tblName must be obtained after the parsing is complete");
+        return tblName;
     }
 
     public String getStateValue() {
         Preconditions.checkArgument(isAnalyzed(),
-                "The tbl name must be obtained after the parsing is complete");
+                "The stateValue must be obtained after the parsing is 
complete");
         return stateValue;
     }
 
     public ArrayList<OrderByPair> getOrderByPairs() {
         Preconditions.checkArgument(isAnalyzed(),
-                "The tbl name must be obtained after the parsing is complete");
+                "The orderByPairs must be obtained after the parsing is 
complete");
         return orderByPairs;
     }
 
-    public long getLimit() {
-        if (limitElement != null && limitElement.hasLimit()) {
-            return limitElement.getLimit();
+    public String getWhereClause() {
+        Preconditions.checkArgument(isAnalyzed(),
+                "The whereClause must be obtained after the parsing is 
complete");
+
+        StringBuilder clauseBuilder = new StringBuilder();
+
+        if (jobId != null) {
+            clauseBuilder.append("job_Id = ").append(jobId);
         }
-        return -1L;
+
+        if (!Strings.isNullOrEmpty(catalogName)) {
+            clauseBuilder.append(clauseBuilder.length() > 0 ? " AND " : "")
+                    .append("catalog_name = 
\"").append(catalogName).append("\"");
+        }
+
+        if (!Strings.isNullOrEmpty(dbName)) {
+            clauseBuilder.append(clauseBuilder.length() > 0 ? " AND " : "")
+                    .append("db_name = \"").append(dbName).append("\"");
+        }
+
+        if (!Strings.isNullOrEmpty(tblName)) {
+            clauseBuilder.append(clauseBuilder.length() > 0 ? " AND " : "")
+                    .append("tbl_name = \"").append(tblName).append("\"");
+        }
+
+        if (!Strings.isNullOrEmpty(stateValue)) {
+            clauseBuilder.append(clauseBuilder.length() > 0 ? " AND " : "")
+                    .append("state = \"").append(stateValue).append("\"");
+        }
+
+        return clauseBuilder.toString();
     }
 
-    public long getOffset() {
-        if (limitElement != null && limitElement.hasOffset()) {
-            return limitElement.getOffset();
+    public long getLimit() {
+        if (limitElement != null && limitElement.hasLimit()) {
+            return limitElement.getLimit();
         }
         return -1L;
     }
@@ -142,41 +186,15 @@ public class ShowAnalyzeStmt extends ShowStmt {
     @Override
     public void analyze(Analyzer analyzer) throws UserException {
         super.analyze(analyzer);
+        catalogName = analyzer.getEnv().getInternalCatalog().getName();
 
         if (dbTableName != null) {
             dbTableName.analyze(analyzer);
             String dbName = dbTableName.getDb();
             String tblName = dbTableName.getTbl();
             checkShowAnalyzePriv(dbName, tblName);
-
-            Database db = 
analyzer.getEnv().getInternalCatalog().getDbOrAnalysisException(dbName);
-            Table table = db.getTableOrAnalysisException(tblName);
-            dbId = db.getId();
-            tblIds.add(table.getId());
-        } else {
-            // analyze the current default db
-            String dbName = analyzer.getDefaultDb();
-            if (Strings.isNullOrEmpty(dbName)) {
-                ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_DB_ERROR);
-            }
-
-            Database db = 
analyzer.getEnv().getInternalCatalog().getDbOrAnalysisException(dbName);
-
-            db.readLock();
-            try {
-                List<Table> tables = db.getTables();
-                for (Table table : tables) {
-                    checkShowAnalyzePriv(dbName, table.getName());
-                }
-
-                dbId = db.getId();
-                for (Table table : tables) {
-                    long tblId = table.getId();
-                    tblIds.add(tblId);
-                }
-            } finally {
-                db.readUnlock();
-            }
+            this.dbName = dbName;
+            this.tblName = tblName;
         }
 
         // analyze where clause if not null
@@ -270,7 +288,7 @@ public class ShowAnalyzeStmt extends ShowStmt {
 
             stateValue = value.toUpperCase();
             try {
-                // support it later
+                AnalysisState.valueOf(stateValue);
             } catch (Exception e) {
                 valid = false;
             }
@@ -295,6 +313,12 @@ public class ShowAnalyzeStmt extends ShowStmt {
     public String toSql() {
         StringBuilder sb = new StringBuilder();
         sb.append("SHOW ANALYZE");
+
+        if (jobId != null) {
+            sb.append(" ");
+            sb.append(jobId);
+        }
+
         if (dbTableName != null) {
             sb.append(" ");
             sb.append(dbTableName.toSql());
@@ -326,13 +350,6 @@ public class ShowAnalyzeStmt extends ShowStmt {
             sb.append(getLimit());
         }
 
-        if (getOffset() != -1L) {
-            sb.append(" ");
-            sb.append("OFFSET");
-            sb.append(" ");
-            sb.append(getOffset());
-        }
-
         return sb.toString();
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
index ea4b384fb2..ddc0c12b37 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
@@ -2308,9 +2308,39 @@ public class ShowExecutor {
         resultSet = 
Env.getCurrentEnv().getCatalogMgr().showCreateCatalog(showStmt);
     }
 
+    private void handleShowAnalyze() {
+        ShowAnalyzeStmt showStmt = (ShowAnalyzeStmt) stmt;
 
-    private void handleShowAnalyze() throws AnalysisException {
-        // TODO: Support later
+        List<List<Comparable>> results;
+        List<List<String>> resultRows = Lists.newArrayList();
+
+        try {
+            results = Env.getCurrentEnv().getAnalysisManager()
+                    .showAnalysisJob(showStmt);
+        } catch (DdlException e) {
+            resultSet = new ShowResultSet(showStmt.getMetaData(), resultRows);
+            return;
+        }
+
+        // order the result
+        ListComparator<List<Comparable>> comparator;
+        List<OrderByPair> orderByPairs = showStmt.getOrderByPairs();
+        if (orderByPairs == null) {
+            // sort by id asc
+            comparator = new ListComparator<>(0);
+        } else {
+            OrderByPair[] orderByPairArr = new 
OrderByPair[orderByPairs.size()];
+            comparator = new 
ListComparator<>(orderByPairs.toArray(orderByPairArr));
+        }
+        results.sort(comparator);
+
+        // convert to result and return it
+        for (List<Comparable> result : results) {
+            List<String> row = 
result.stream().map(Object::toString).collect(Collectors.toList());
+            resultRows.add(row);
+        }
+
+        resultSet = new ShowResultSet(showStmt.getMetaData(), resultRows);
     }
 
     private void handleCopyTablet() throws AnalysisException {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java 
b/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
index 28fdd4d450..a8f95d9cd4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
@@ -18,23 +18,30 @@
 package org.apache.doris.statistics;
 
 import org.apache.doris.analysis.AnalyzeStmt;
+import org.apache.doris.analysis.ShowAnalyzeStmt;
 import org.apache.doris.analysis.TableName;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.MaterializedIndexMeta;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.TableIf.TableType;
+import org.apache.doris.common.DdlException;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.statistics.AnalysisTaskInfo.AnalysisMethod;
 import org.apache.doris.statistics.AnalysisTaskInfo.AnalysisType;
 import org.apache.doris.statistics.AnalysisTaskInfo.JobType;
 import org.apache.doris.statistics.AnalysisTaskInfo.ScheduleType;
+import org.apache.doris.statistics.util.InternalQueryResult.ResultRow;
 import org.apache.doris.statistics.util.StatisticsUtil;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.text.StringSubstitutor;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +58,14 @@ public class AnalysisManager {
             + FeConstants.INTERNAL_DB_NAME + "." + 
StatisticConstants.ANALYSIS_JOB_TABLE + " "
             + "SET state = '${jobState}' ${message} ${updateExecTime} WHERE 
job_id = ${jobId}";
 
+    private static final String SHOW_JOB_STATE_SQL_TEMPLATE = "SELECT "
+            + "job_id, catalog_name, db_name, tbl_name, col_name, job_type, "
+            + "analysis_type, message, last_exec_time_in_ms, state, 
schedule_type "
+            + "FROM " + FeConstants.INTERNAL_DB_NAME + "." + 
StatisticConstants.ANALYSIS_JOB_TABLE;
+
+    // The time field that needs to be displayed
+    private static final String LAST_EXEC_TIME_IN_MS = "last_exec_time_in_ms";
+
     private final ConcurrentMap<Long, Map<Long, AnalysisTaskInfo>> 
analysisJobIdToTaskMap;
 
     private StatisticsCache statisticsCache;
@@ -65,6 +80,10 @@ public class AnalysisManager {
         taskExecutor.start();
     }
 
+    public StatisticsCache getStatisticsCache() {
+        return statisticsCache;
+    }
+
     public void createAnalysisJob(AnalyzeStmt analyzeStmt) {
         String catalogName = analyzeStmt.getCatalogName();
         String db = analyzeStmt.getDBName();
@@ -142,7 +161,33 @@ public class AnalysisManager {
         }
     }
 
-    public StatisticsCache getStatisticsCache() {
-        return statisticsCache;
+    public List<List<Comparable>> showAnalysisJob(ShowAnalyzeStmt stmt) throws 
DdlException {
+        String whereClause = stmt.getWhereClause();
+        long limit = stmt.getLimit();
+        String executeSql = SHOW_JOB_STATE_SQL_TEMPLATE
+                + (whereClause.isEmpty() ? "" : " WHERE " + whereClause)
+                + (limit == -1L ? "" : " LIMIT " + limit);
+
+        List<List<Comparable>> results = Lists.newArrayList();
+        ImmutableList<String> titleNames = stmt.getTitleNames();
+        List<ResultRow> resultRows = 
StatisticsUtil.execStatisticQuery(executeSql);
+
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd 
HH:mm:ss");
+
+        for (ResultRow resultRow : resultRows) {
+            List<Comparable> result = Lists.newArrayList();
+            for (String column : titleNames) {
+                String value = resultRow.getColumnValue(column);
+                if (LAST_EXEC_TIME_IN_MS.equals(column)) {
+                    long timeMillis = Long.parseLong(value);
+                    value = dateFormat.format(new Date(timeMillis));
+                }
+                result.add(value);
+            }
+            results.add(result);
+        }
+
+        return results;
     }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to