Skip to content

Commit

Permalink
[Enhancement] (nereids)implement showColumnsCommand in nereids
Browse files Browse the repository at this point in the history
  • Loading branch information
msridhar78 committed Dec 23, 2024
1 parent 7209101 commit 5633195
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ supportedShowStatement
| SHOW TABLET DIAGNOSIS tabletId=INTEGER_VALUE #showDiagnoseTablet
| SHOW FRONTENDS name=identifier? #showFrontends
| SHOW DATABASE databaseId=INTEGER_VALUE #showDatabaseId
| SHOW FULL? (COLUMNS | FIELDS) (FROM | IN) tableName=multipartIdentifier
((FROM | IN) database=multipartIdentifier)? (LIKE STRING_LITERAL)? #showColumns
| SHOW TABLE tableId=INTEGER_VALUE #showTableId
| SHOW TRASH (ON backend=STRING_LITERAL)? #showTrash
| SHOW (GLOBAL | SESSION | LOCAL)? STATUS #showStatus
Expand Down Expand Up @@ -333,8 +335,6 @@ unsupportedShowStatement
| SHOW (DATABASES | SCHEMAS) (FROM catalog=identifier)? wildWhere? #showDatabases
| SHOW CATALOGS wildWhere? #showCatalogs
| SHOW CATALOG name=identifier #showCatalog
| SHOW FULL? (COLUMNS | FIELDS) (FROM | IN) tableName=multipartIdentifier
((FROM | IN) database=multipartIdentifier)? wildWhere? #showColumns
| SHOW COUNT LEFT_PAREN ASTERISK RIGHT_PAREN (WARNINGS | ERRORS) #showWaringErrorCount
| SHOW LOAD WARNINGS ((((FROM | IN) database=multipartIdentifier)?
wildWhere? limitClause?) | (ON url=STRING_LITERAL)) #showLoadWarings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
import org.apache.doris.nereids.DorisParser.ShowBrokerContext;
import org.apache.doris.nereids.DorisParser.ShowCharsetContext;
import org.apache.doris.nereids.DorisParser.ShowCollationContext;
import org.apache.doris.nereids.DorisParser.ShowColumnsContext;
import org.apache.doris.nereids.DorisParser.ShowConfigContext;
import org.apache.doris.nereids.DorisParser.ShowConstraintContext;
import org.apache.doris.nereids.DorisParser.ShowCreateCatalogContext;
Expand Down Expand Up @@ -570,6 +571,7 @@
import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCharsetCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCollationCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowColumnsCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowConfigCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowConstraintsCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCreateCatalogCommand;
Expand Down Expand Up @@ -5036,6 +5038,19 @@ public LogicalPlan visitShowSyncJob(ShowSyncJobContext ctx) {
return new ShowSyncJobCommand(databaseName);
}

@Override
public LogicalPlan visitShowColumns(ShowColumnsContext ctx) {
boolean isFull = ctx.FULL() != null;
List<String> nameParts = visitMultipartIdentifier(ctx.tableName);
String databaseName = ctx.database != null ? ctx.database.getText() : null;
String pattern = null;
if (ctx.LIKE() != null) {
pattern = stripQuotes(ctx.STRING_LITERAL().getText());
}

return new ShowColumnsCommand(isFull, new TableNameInfo(nameParts), databaseName, pattern);
}

@Override
public LogicalPlan visitDropFile(DropFileContext ctx) {
String dbName = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ public enum PlanType {
SHOW_BROKER_COMMAND,
SHOW_CHARSET_COMMAND,
SHOW_COLLATION_COMMAND,
SHOW_COLUMNS_COMMAND,
SHOW_CONFIG_COMMAND,
SHOW_CREATE_CATALOG_COMMAND,
SHOW_CREATE_DATABASE_COMMAND,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// 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.ScalarType;
import org.apache.doris.catalog.TableIf;
import org.apache.doris.common.AnalysisException;
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.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.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;
import java.util.Locale;

/**
* Represents the SHOW COLUMNS command.
*/
public class ShowColumnsCommand extends ShowCommand {
private static final ShowResultSetMetaData META_DATA = ShowResultSetMetaData.builder()
.addColumn(new Column("Field", ScalarType.createVarchar(20)))
.addColumn(new Column("Type", ScalarType.createVarchar(20)))
.addColumn(new Column("Null", ScalarType.createVarchar(20)))
.addColumn(new Column("Key", ScalarType.createVarchar(20)))
.addColumn(new Column("Default", ScalarType.createVarchar(20)))
.addColumn(new Column("Extra", ScalarType.createVarchar(20))).build();

private static final ShowResultSetMetaData META_DATA_VERBOSE =
ShowResultSetMetaData.builder()
.addColumn(new Column("Field", ScalarType.createVarchar(20)))
.addColumn(new Column("Type", ScalarType.createVarchar(20)))
.addColumn(new Column("Collation", ScalarType.createVarchar(20)))
.addColumn(new Column("Null", ScalarType.createVarchar(20)))
.addColumn(new Column("Key", ScalarType.createVarchar(20)))
.addColumn(new Column("Default", ScalarType.createVarchar(20)))
.addColumn(new Column("Extra", ScalarType.createVarchar(20)))
.addColumn(new Column("Privileges", ScalarType.createVarchar(20)))
.addColumn(new Column("Comment", ScalarType.createVarchar(20)))
.build();

private ShowResultSetMetaData metaData;
private final boolean isFull;
private TableNameInfo tableNameInfo;
private final String databaseName;
private final String likePattern;

public ShowColumnsCommand(boolean isFull, TableNameInfo tableNameInfo, String databaseName, String likePattern) {
super(PlanType.SHOW_COLUMNS_COMMAND);
this.isFull = isFull;
this.tableNameInfo = tableNameInfo;
this.databaseName = databaseName;
this.likePattern = likePattern;
}

private void validate(ConnectContext ctx) throws AnalysisException {
if (!Strings.isNullOrEmpty(databaseName)) {
tableNameInfo.setDb(databaseName);
}
tableNameInfo.analyze(ctx);
if (isFull) {
metaData = META_DATA_VERBOSE;
} else {
metaData = META_DATA;
}
if (!Env.getCurrentEnv().getAccessManager()
.checkTblPriv(ConnectContext.get(), tableNameInfo.getCtl(), tableNameInfo.getDb(),
tableNameInfo.getTbl(), PrivPredicate.SHOW)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR,
PrivPredicate.SHOW.getPrivs().toString(), tableNameInfo);
}
}

@Override
public ShowResultSet doRun(ConnectContext ctx, StmtExecutor executor) throws Exception {
validate(ctx);
List<List<String>> rows = Lists.newArrayList();
String ctl = tableNameInfo.getCtl();
DatabaseIf db = Env.getCurrentEnv().getCatalogMgr().getCatalogOrAnalysisException(ctl)
.getDbOrAnalysisException(tableNameInfo.getDb());
TableIf table = db.getTableOrAnalysisException(tableNameInfo.getTbl());
PatternMatcher matcher = null;
if (likePattern != null) {
matcher = PatternMatcherWrapper.createMysqlPattern(likePattern,
CaseSensibility.COLUMN.getCaseSensibility());
}
table.readLock();
try {
List<Column> columns = table.getBaseSchema();
for (Column col : columns) {
if (matcher != null && !matcher.match(col.getName())) {
continue;
}
final String columnName = col.getName();
final String columnType = col.getOriginType().toString().toLowerCase(Locale.ROOT);
final String isAllowNull = col.isAllowNull() ? "YES" : "NO";
final String isKey = col.isKey() ? "YES" : "NO";
final String defaultValue = col.getDefaultValue();
final String aggType = col.getAggregationType() == null ? "" : col.getAggregationType().toSql();
if (isFull) {
// Field Type Collation Null Key Default Extra
// Privileges Comment
rows.add(Lists.newArrayList(columnName,
columnType,
"",
isAllowNull,
isKey,
defaultValue,
aggType,
"",
col.getComment()));
} else {
// Field Type Null Key Default Extra
rows.add(Lists.newArrayList(columnName,
columnType,
isAllowNull,
isKey,
defaultValue,
aggType));
}
}
} finally {
table.readUnlock();
}
return new ShowResultSet(metaData, rows);
}

@Override
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
return visitor.visitShowColumnsCommand(this, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import org.apache.doris.nereids.trees.plans.commands.ShowBrokerCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCharsetCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCollationCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowColumnsCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowConfigCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowConstraintsCommand;
import org.apache.doris.nereids.trees.plans.commands.ShowCreateCatalogCommand;
Expand Down Expand Up @@ -349,6 +350,10 @@ default R visitAlterViewCommand(AlterViewCommand alterViewCommand, C context) {
return visitCommand(alterViewCommand, context);
}

default R visitShowColumnsCommand(ShowColumnsCommand showColumnsCommand, C context) {
return visitCommand(showColumnsCommand, context);
}

default R visitDropCatalogCommand(DropCatalogCommand dropCatalogCommand, C context) {
return visitCommand(dropCatalogCommand, context);
}
Expand Down
14 changes: 14 additions & 0 deletions regression-test/data/nereids_p0/show/test_show_columns_command.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !cmd --
id int YES YES \N
name text YES NO \N NONE
score float YES NO \N NONE

-- !cmd --
id int YES YES \N
name text YES NO \N NONE
score float YES NO \N NONE

-- !cmd --
score float YES NO \N NONE

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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_show_columns_command", "nereids_p0") {
def dbName = "test_show_columns_db"
def tableName = "test_show_columns_table"

try {
sql """CREATE DATABASE IF NOT EXISTS ${dbName}"""
sql """
CREATE TABLE IF NOT EXISTS ${dbName}.${tableName} (
id INT,
name STRING,
score FLOAT
)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES ("replication_num" = "1");
"""

// Test SHOW COLUMNS
checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName}""")
qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName}""")

// Test SHOW FULL COLUMNS
checkNereidsExecute("""SHOW FULL COLUMNS FROM ${dbName}.${tableName}""")
qt_cmd("""SHOW FULL COLUMNS FROM ${dbName}.${tableName}""")

// Test SHOW COLUMNS with LIKE
checkNereidsExecute("""SHOW COLUMNS FROM ${dbName}.${tableName} LIKE 's%'""")
qt_cmd("""SHOW COLUMNS FROM ${dbName}.${tableName} LIKE 's%'""")

} finally {
sql """DROP TABLE IF EXISTS ${dbName}.${tableName}"""
sql """DROP DATABASE IF EXISTS ${dbName}"""
}
}

0 comments on commit 5633195

Please sign in to comment.