From 7b5b8db1bc477720a1565ee58ce5a2cf33b31c13 Mon Sep 17 00:00:00 2001 From: Rijesh Kunhi Parambattu <147430310+rijeshkp@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:08:28 +0530 Subject: [PATCH] [Enhancement] (nereids)implement showTableCreationCommand in nereids #42776 (#44703) Issue Number: close #42776 --- .../org/apache/doris/nereids/DorisParser.g4 | 3 +- .../nereids/parser/LogicalPlanBuilder.java | 20 +++- .../doris/nereids/trees/plans/PlanType.java | 3 +- .../commands/ShowTableCreationCommand.java | 101 ++++++++++++++++++ .../trees/plans/visitor/CommandVisitor.java | 5 + .../test_nereids_show_table_creation.groovy | 70 ++++++++++++ 6 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableCreationCommand.java create mode 100644 regression-test/suites/nereids_p0/show/test_nereids_show_table_creation.groovy 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 eda5dda16984c9..3bc884408c55ce 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 @@ -268,6 +268,8 @@ supportedShowStatement | SHOW TABLETS BELONG tabletIds+=INTEGER_VALUE (COMMA tabletIds+=INTEGER_VALUE)* #showTabletsBelong | SHOW DATA SKEW FROM baseTableRef #showDataSkew + | SHOW TABLE CREATION ((FROM | IN) database=multipartIdentifier)? + (LIKE STRING_LITERAL)? #showTableCreation ; supportedLoadStatement @@ -359,7 +361,6 @@ unsupportedShowStatement | SHOW QUERY PROFILE queryIdPath=STRING_LITERAL #showQueryProfile | SHOW CACHE HOTSPOT tablePath=STRING_LITERAL #showCacheHotSpot | SHOW SYNC JOB ((FROM | IN) database=multipartIdentifier)? #showSyncJob - | SHOW TABLE CREATION ((FROM | IN) database=multipartIdentifier)? wildWhere? #showTableCreation | SHOW CATALOG RECYCLE BIN wildWhere? #showCatalogRecycleBin | SHOW QUERY STATS ((FOR database=identifier) | (FROM tableName=multipartIdentifier (ALL VERBOSE?)?))? #showQueryStats 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 ff5bed55ebc857..8c964e997069a5 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 @@ -271,6 +271,7 @@ import org.apache.doris.nereids.DorisParser.ShowSmallFilesContext; import org.apache.doris.nereids.DorisParser.ShowSqlBlockRuleContext; import org.apache.doris.nereids.DorisParser.ShowStorageEnginesContext; +import org.apache.doris.nereids.DorisParser.ShowTableCreationContext; import org.apache.doris.nereids.DorisParser.ShowTableIdContext; import org.apache.doris.nereids.DorisParser.ShowTabletsBelongContext; import org.apache.doris.nereids.DorisParser.ShowTrashContext; @@ -574,6 +575,7 @@ import org.apache.doris.nereids.trees.plans.commands.ShowSmallFilesCommand; 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.ShowTableCreationCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTableIdCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTrashCommand; @@ -1402,7 +1404,7 @@ public BrokerDesc visitWithRemoteStorageSystem(WithRemoteStorageSystemContext ct @Override public List> visitMultiStatements(MultiStatementsContext ctx) { List> logicalPlans = Lists.newArrayList(); - for (org.apache.doris.nereids.DorisParser.StatementContext statement : ctx.statement()) { + for (DorisParser.StatementContext statement : ctx.statement()) { StatementContext statementContext = new StatementContext(); ConnectContext connectContext = ConnectContext.get(); if (connectContext != null) { @@ -1527,7 +1529,7 @@ public LogicalPlan visitLoad(DorisParser.LoadContext ctx) { * ******************************************************************************************** */ /** - * process lateral view, add a {@link org.apache.doris.nereids.trees.plans.logical.LogicalGenerate} on plan. + * process lateral view, add a {@link LogicalGenerate} on plan. */ protected LogicalPlan withGenerate(LogicalPlan plan, LateralViewContext ctx) { if (ctx.LATERAL() == null) { @@ -4985,5 +4987,19 @@ public LogicalPlan visitShowDataSkew(ShowDataSkewContext ctx) { TableRefInfo tableRefInfo = visitBaseTableRefContext(ctx.baseTableRef()); return new ShowDataSkewCommand(tableRefInfo); } + + @Override + public LogicalPlan visitShowTableCreation(ShowTableCreationContext ctx) { + String dbName = null; + String wild = null; + if (ctx.database != null) { + List nameParts = visitMultipartIdentifier(ctx.database); + dbName = nameParts.get(0); // only one entry possible + } + if (ctx.STRING_LITERAL() != null) { + wild = ctx.STRING_LITERAL().getText(); + } + return new ShowTableCreationCommand(dbName, 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 fac113564f857e..e98d9f6afd5ae2 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 @@ -249,5 +249,6 @@ public enum PlanType { CREATE_ENCRYPTKEY_COMMAND, CREATE_WORKLOAD_GROUP_COMMAND, CREATE_FILE_COMMAND, - CREATE_ROUTINE_LOAD_COMMAND + CREATE_ROUTINE_LOAD_COMMAND, + SHOW_TABLE_CREATION_COMMAND } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableCreationCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableCreationCommand.java new file mode 100644 index 00000000000000..8d2102a0b04182 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTableCreationCommand.java @@ -0,0 +1,101 @@ +// 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.ScalarType; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.common.util.ListComparator; +import org.apache.doris.common.util.OrderByPair; +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.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * show table id command + */ +public class ShowTableCreationCommand extends ShowCommand { + private static final ShowResultSetMetaData META_DATA = + ShowResultSetMetaData.builder() + .addColumn(new Column("Database", ScalarType.createVarchar(20))) + .addColumn(new Column("Table", ScalarType.createVarchar(20))) + .addColumn(new Column("Status", ScalarType.createVarchar(10))) + .addColumn(new Column("Create Time", ScalarType.createVarchar(20))) + .addColumn(new Column("Error Msg", ScalarType.createVarchar(100))) + .build(); + + private String dbName; + private String wild; + + /** + * constructor + */ + public ShowTableCreationCommand(String dbName, String wild) { + super(PlanType.SHOW_TABLE_CREATION_COMMAND); + this.dbName = dbName; + this.wild = wild; + } + + @Override + public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) throws Exception { + if (Strings.isNullOrEmpty(dbName)) { + dbName = ConnectContext.get().getDatabase(); + if (Strings.isNullOrEmpty(dbName)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_DB_ERROR); + } + } + + /* Need to implement fetching records from iceberg table */ + List> rowSet = Lists.newArrayList(); + // sort function rows by fourth column (Create Time) asc + ListComparator> comparator = null; + OrderByPair orderByPair = new OrderByPair(3, false); + comparator = new ListComparator<>(orderByPair); + Collections.sort(rowSet, comparator); + List> resultRowSet = Lists.newArrayList(); + + Set keyNameSet = new HashSet<>(); + for (List row : rowSet) { + List resultRow = Lists.newArrayList(); + for (Comparable column : row) { + resultRow.add(column.toString()); + } + resultRowSet.add(resultRow); + keyNameSet.add(resultRow.get(0)); + } + + return new ShowResultSet(META_DATA, resultRowSet); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitShowTableCreationCommand(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 05ee8548cfa93d..9131671f98abfd 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 @@ -116,6 +116,7 @@ import org.apache.doris.nereids.trees.plans.commands.ShowSmallFilesCommand; 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.ShowTableCreationCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTableIdCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTabletsBelongCommand; import org.apache.doris.nereids.trees.plans.commands.ShowTrashCommand; @@ -610,4 +611,8 @@ default R visitAdminCheckTabletsCommand(AdminCheckTabletsCommand adminCheckTable default R visitShowDataSkewCommand(ShowDataSkewCommand showDataSkewCommand, C context) { return visitCommand(showDataSkewCommand, context); } + + default R visitShowTableCreationCommand(ShowTableCreationCommand showTableCreationCommand, C context) { + return visitCommand(showTableCreationCommand, context); + } } diff --git a/regression-test/suites/nereids_p0/show/test_nereids_show_table_creation.groovy b/regression-test/suites/nereids_p0/show/test_nereids_show_table_creation.groovy new file mode 100644 index 00000000000000..ca29bd82ed640e --- /dev/null +++ b/regression-test/suites/nereids_p0/show/test_nereids_show_table_creation.groovy @@ -0,0 +1,70 @@ +package show +// 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. + + +suite("test_nereids_show_table_creation") { + def table = "test_nereids_show_table_creation" + // create table and insert data + String dbName = 'test_nereids_show_table_creation' + try_sql """drop database if exists ${dbName}""" + sql """create database ${dbName}""" + sql """ drop table if exists ${dbName}.${table} force""" + + sql """ + create table ${dbName}.${table} ( + `id` int(11), + `name` varchar(128), + `da` date + ) + engine=olap + duplicate key(id) + partition by range(da)( + PARTITION p3 VALUES LESS THAN ('2023-01-01'), + PARTITION p4 VALUES LESS THAN ('2024-01-01'), + PARTITION p5 VALUES LESS THAN ('2025-01-01') + ) + distributed by hash(id) buckets 2 + properties( + "replication_num"="1", + "light_schema_change"="true" + ); + """ + + checkNereidsExecute("SHOW TABLE CREATION FROM ${dbName}") + checkNereidsExecute("SHOW TABLE CREATION IN ${dbName}") + checkNereidsExecute("SHOW TABLE CREATION FROM ${dbName} like '%${table}%'") + checkNereidsExecute("SHOW TABLE CREATION like '%${table}%'") + checkNereidsExecute("SHOW TABLE CREATION") + + def res = sql """SHOW TABLE CREATION FROM ${dbName}""" + assertTrue(res.size() == 0) + + res = sql """SHOW TABLE CREATION IN ${dbName}""" + assertTrue(res.size() == 0) + + res = sql """SHOW TABLE CREATION FROM ${dbName} like '%${table}%'""" + assertTrue(res.size() == 0) + + res = sql """SHOW TABLE CREATION like '%${table}%'""" + assertTrue(res.size() == 0) + + res = sql """SHOW TABLE CREATION""" + assertTrue(res.size() == 0) + +} +