From 471ceacbfd0b5fa801592373e9dbffc468647dc2 Mon Sep 17 00:00:00 2001 From: Rijesh Kunhi Parambattu Date: Tue, 26 Nov 2024 22:32:27 +0530 Subject: [PATCH] [Enhancement] (nereids)implement showTableStatusCommand in nereids --- .../org/apache/doris/nereids/DorisParser.g4 | 4 +- .../nereids/parser/LogicalPlanBuilder.java | 28 +++ .../doris/nereids/trees/plans/PlanType.java | 1 + .../commands/ShowTableStatusCommand.java | 199 ++++++++++++++++++ .../trees/plans/visitor/CommandVisitor.java | 5 + 5 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableStatusCommand.java 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 932f644fca4e7aa..52abdbff00216da 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 @@ -238,7 +238,8 @@ supportedShowStatement | SHOW TABLE tableId=INTEGER_VALUE #showTableId | SHOW WHITELIST #showWhitelist | SHOW TABLETS BELONG - tabletIds+=INTEGER_VALUE (COMMA tabletIds+=INTEGER_VALUE)* #showTabletsBelong + tabletIds+=INTEGER_VALUE (COMMA tabletIds+=INTEGER_VALUE)* #showTabletsBelong + | SHOW TABLE STATUS ((FROM | IN) database=multipartIdentifier)? wildWhere? #showTableStatus ; supportedLoadStatement @@ -279,7 +280,6 @@ unsupportedShowStatement | SHOW STORAGE (VAULT | VAULTS) #showStorageVault | SHOW CREATE REPOSITORY FOR identifier #showCreateRepository | SHOW OPEN TABLES ((FROM | IN) database=multipartIdentifier)? wildWhere? #showOpenTables - | SHOW TABLE STATUS ((FROM | IN) database=multipartIdentifier)? wildWhere? #showTableStatus | SHOW FULL? TABLES ((FROM | IN) database=multipartIdentifier)? wildWhere? #showTables | SHOW FULL? VIEWS ((FROM | IN) database=multipartIdentifier)? wildWhere? #showViews | SHOW FULL? PROCESSLIST #showProcessList 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 320043e12b8b534..bdf07d9ffccd372 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 @@ -232,6 +232,7 @@ import org.apache.doris.nereids.DorisParser.ShowSqlBlockRuleContext; import org.apache.doris.nereids.DorisParser.ShowStorageEnginesContext; import org.apache.doris.nereids.DorisParser.ShowTableIdContext; +import org.apache.doris.nereids.DorisParser.ShowTableStatusContext; import org.apache.doris.nereids.DorisParser.ShowTabletsBelongContext; import org.apache.doris.nereids.DorisParser.ShowTriggersContext; import org.apache.doris.nereids.DorisParser.ShowVariablesContext; @@ -504,6 +505,7 @@ import org.apache.doris.nereids.trees.plans.commands.ShowSqlBlockRuleCommand; import org.apache.doris.nereids.trees.plans.commands.ShowStorageEnginesCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTableIdCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowTableStatusCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTriggersCommand; import org.apache.doris.nereids.trees.plans.commands.ShowVariablesCommand; @@ -4437,4 +4439,30 @@ public LogicalPlan visitShowTabletsBelong(ShowTabletsBelongContext ctx) { }); return new ShowTabletsBelongCommand(tabletIdLists); } + + @Override + public LogicalPlan visitShowTableStatus(ShowTableStatusContext ctx) { + String databaseName = null; + String ctlName = null; + String wild = null; + + if (ctx.database != null) { + List nameParts = visitMultipartIdentifier(ctx.database); + if (nameParts.size() == 1) { + databaseName = nameParts.get(0); + } else if (nameParts.size() == 2) { + ctlName = nameParts.get(0); + databaseName = nameParts.get(1); + } else { + throw new AnalysisException("nameParts in create table should be [ctl.][db.]"); + } + } + + if (ctx.wildWhere() != null) { + if (ctx.wildWhere().LIKE() != null) { + wild = stripQuotes(ctx.wildWhere().STRING_LITERAL().getText()); + } + } + return new ShowTableStatusCommand(ctlName, databaseName, wild); + } } 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 1f7b838edfd9059..97772832df28938 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 @@ -208,6 +208,7 @@ public enum PlanType { SHOW_ROLE_COMMAND, SHOW_SMALL_FILES_COMMAND, SHOW_STORAGE_ENGINES_COMMAND, + SHOW_TABLE_STATUS_COMMAND, SHOW_TABLE_ID_COMMAND, SHOW_TRIGGERS_COMMAND, SHOW_VARIABLES_COMMAND, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableStatusCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableStatusCommand.java new file mode 100644 index 000000000000000..51ffb97e5eefd1f --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableStatusCommand.java @@ -0,0 +1,199 @@ +// 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.Column; +import org.apache.doris.catalog.DatabaseIf; +import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.PrimitiveType; +import org.apache.doris.catalog.ScalarType; +import org.apache.doris.catalog.TableIf; +import org.apache.doris.common.CaseSensibility; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.common.PatternMatcher; +import org.apache.doris.common.PatternMatcherWrapper; +import org.apache.doris.common.util.TimeUtils; +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.ShowResultSet; +import org.apache.doris.qe.ShowResultSetMetaData; +import org.apache.doris.qe.StmtExecutor; + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * ShowVariablesCommand + */ +public class ShowTableStatusCommand extends ShowCommand { + private static final ShowResultSetMetaData META_DATA = ShowResultSetMetaData.builder() + .addColumn(new Column("Name", ScalarType.createVarchar(64))) + .addColumn(new Column("Engine", ScalarType.createVarchar(10))) + .addColumn(new Column("Version", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Row_format", ScalarType.createVarchar(64))) + .addColumn(new Column("Rows", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Avg_row_length", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Data_length", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Max_data_length", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Index_length", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Data_free", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Auto_increment", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Create_time", ScalarType.createType(PrimitiveType.DATETIME))) + .addColumn(new Column("Update_time", ScalarType.createType(PrimitiveType.DATETIME))) + .addColumn(new Column("Check_time", ScalarType.createType(PrimitiveType.DATETIME))) + .addColumn(new Column("Collation", ScalarType.createVarchar(64))) + .addColumn(new Column("Checksum", ScalarType.createType(PrimitiveType.BIGINT))) + .addColumn(new Column("Create_options", ScalarType.createVarchar(64))) + .addColumn(new Column("Comment", ScalarType.createVarchar(64))) + .build(); + + private String catalog; + private String db; + private String wild; + + public ShowTableStatusCommand(String catalog, String db, String wild) { + super(PlanType.SHOW_TABLE_STATUS_COMMAND); + this.catalog = catalog; + this.db = db; + this.wild = wild; + } + + public String getCatalog() { + return catalog; + } + + public String getDb() { + return db; + } + + public String getPattern() { + return wild; + } + + public ShowResultSetMetaData getMetaData() { + return META_DATA; + } + + @Override + public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) throws Exception { + if (Strings.isNullOrEmpty(db)) { + db = ctx.getDatabase(); + if (Strings.isNullOrEmpty(db)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_DB_ERROR); + } + } + if (Strings.isNullOrEmpty(catalog)) { + catalog = ctx.getDefaultCatalog(); + if (Strings.isNullOrEmpty(catalog)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_NAME_FOR_CATALOG); + } + } + + if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ctx, + catalog, db, PrivPredicate.SHOW)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString(), db); + } + + List> rows = Lists.newArrayList(); + DatabaseIf dbName = ctx.getEnv().getCatalogMgr() + .getCatalogOrAnalysisException(getCatalog()) + .getDbOrAnalysisException(getDb()); + if (dbName != null) { + PatternMatcher matcher = null; + if (getPattern() != null) { + matcher = PatternMatcherWrapper.createMysqlPattern(getPattern(), + CaseSensibility.TABLE.getCaseSensibility()); + } + for (TableIf table : dbName.getTables()) { + if (matcher != null && !matcher.match(table.getName())) { + continue; + } + + // check tbl privs + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ctx, getCatalog(), + dbName.getFullName(), table.getName(), PrivPredicate.SHOW)) { + continue; + } + List row = Lists.newArrayList(); + // Name + row.add(table.getName()); + // Engine + row.add(table.getEngine()); + // version + row.add(null); + // Row_format + row.add(null); + // Rows + row.add(String.valueOf(table.getCachedRowCount())); + // Avg_row_length + row.add(String.valueOf(table.getAvgRowLength())); + // Data_length + row.add(String.valueOf(table.getDataLength())); + // Max_data_length + row.add(null); + // Index_length + row.add(null); + // Data_free + row.add(null); + // Auto_increment + row.add(null); + // Create_time + row.add(TimeUtils.longToTimeString(table.getCreateTime() * 1000)); + // Update_time + if (table.getUpdateTime() > 0) { + row.add(TimeUtils.longToTimeString(table.getUpdateTime())); + } else { + row.add(null); + } + // Check_time + if (table.getLastCheckTime() > 0) { + row.add(TimeUtils.longToTimeString(table.getLastCheckTime())); + } else { + row.add(null); + } + // Collation + row.add("utf-8"); + // Checksum + row.add(null); + // Create_options + row.add(null); + + row.add(table.getComment()); + rows.add(row); + } + } + // sort by table name + rows.sort((x, y) -> { + return x.get(0).compareTo(y.get(0)); + }); + return new ShowResultSet(getMetaData(), rows); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitShowTableStatusCommand(this, context); + } + +} 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 6b801524fb295f3..635c9142fdbab4d 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.ShowSqlBlockRuleCommand; import org.apache.doris.nereids.trees.plans.commands.ShowStorageEnginesCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTableIdCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowTableStatusCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTriggersCommand; import org.apache.doris.nereids.trees.plans.commands.ShowVariablesCommand; @@ -458,4 +459,8 @@ default R visitShowPrivilegesCommand(ShowPrivilegesCommand showPrivilegesCommand default R visitShowTabletsBelongCommand(ShowTabletsBelongCommand showTabletBelongCommand, C context) { return visitCommand(showTabletBelongCommand, context); } + + default R visitShowTableStatusCommand(ShowTableStatusCommand showTableStatusCommand, C context) { + return visitCommand(showTableStatusCommand, context); + } }