Skip to content

Commit

Permalink
[feat](nereids)support refresh table command (#45546)
Browse files Browse the repository at this point in the history
Issue Number: close #42578
  • Loading branch information
vinlee19 authored Dec 19, 2024
1 parent 011d393 commit 14a0173
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -457,15 +457,15 @@ channelDescription
supportedRefreshStatement
: REFRESH CATALOG name=identifier propertyClause? #refreshCatalog
| REFRESH DATABASE name=multipartIdentifier propertyClause? #refreshDatabase
| REFRESH TABLE name=multipartIdentifier #refreshTable
;

supportedCleanStatement
: CLEAN ALL PROFILE #cleanAllProfile
;

unsupportedRefreshStatement
: REFRESH TABLE name=multipartIdentifier #refreshTable
| REFRESH LDAP (ALL | (FOR user=identifierOrText)) #refreshLdap
: REFRESH LDAP (ALL | (FOR user=identifierOrText)) #refreshLdap
;

unsupportedCleanStatement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
import org.apache.doris.nereids.DorisParser.RefreshMTMVContext;
import org.apache.doris.nereids.DorisParser.RefreshMethodContext;
import org.apache.doris.nereids.DorisParser.RefreshScheduleContext;
import org.apache.doris.nereids.DorisParser.RefreshTableContext;
import org.apache.doris.nereids.DorisParser.RefreshTriggerContext;
import org.apache.doris.nereids.DorisParser.RegularQuerySpecificationContext;
import org.apache.doris.nereids.DorisParser.RelationContext;
Expand Down Expand Up @@ -670,6 +671,7 @@
import org.apache.doris.nereids.trees.plans.commands.load.LoadWhereClause;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshCatalogCommand;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshDatabaseCommand;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshTableCommand;
import org.apache.doris.nereids.trees.plans.commands.use.SwitchCommand;
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTE;
Expand Down Expand Up @@ -4464,6 +4466,18 @@ public RefreshDatabaseCommand visitRefreshDatabase(RefreshDatabaseContext ctx) {
throw new ParseException("Only one dot can be in the name: " + String.join(".", parts));
}

@Override
public Object visitRefreshTable(RefreshTableContext ctx) {
List<String> parts = visitMultipartIdentifier(ctx.name);
int size = parts.size();
if (size == 0) {
throw new ParseException("table name can't be empty");
} else if (size <= 3) {
return new RefreshTableCommand(new TableNameInfo(parts));
}
throw new ParseException("Only one or two dot can be in the name: " + String.join(".", parts));
}

@Override
public LogicalPlan visitShowCreateRepository(ShowCreateRepositoryContext ctx) {
return new ShowCreateRepositoryCommand(ctx.identifier().getText());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public enum PlanType {
SET_DEFAULT_STORAGE_VAULT_COMMAND,
REFRESH_CATALOG_COMMAND,
REFRESH_DATABASE_COMMAND,
REFRESH_TABLE_COMMAND,
PREPARED_COMMAND,
EXECUTE_COMMAND,
DROP_SQL_BLOCK_RULE_COMMAND,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// 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.refresh;

import org.apache.doris.analysis.StmtType;
import org.apache.doris.catalog.Env;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.commands.Command;
import org.apache.doris.nereids.trees.plans.commands.ForwardWithSync;
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.StmtExecutor;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
* Refresh table command.
*/
public class RefreshTableCommand extends Command implements ForwardWithSync {
private static final Logger LOG = LogManager.getLogger(RefreshTableCommand.class);
private TableNameInfo tableNameInfo;

public RefreshTableCommand(TableNameInfo tableName) {
super(PlanType.REFRESH_TABLE_COMMAND);
this.tableNameInfo = tableName;
}

@Override
public void run(ConnectContext ctx, StmtExecutor executor) throws Exception {
tableNameInfo.analyze(ctx);
checkRefreshTableAccess();
// refresh table execute logic
Env.getCurrentEnv().getRefreshManager()
.refreshTable(tableNameInfo.getCtl(), tableNameInfo.getDb(), tableNameInfo.getTbl(), false);
}

@Override
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
return visitor.visitRefreshTableCommand(this, context);
}

@Override
public StmtType stmtType() {
return StmtType.REFRESH;
}

/**
* check access.
*/
private void checkRefreshTableAccess() throws AnalysisException {
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.getTbl());
}
}

public String toSql() {
return "REFRESH TABLE " + tableNameInfo.toSql();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
import org.apache.doris.nereids.trees.plans.commands.load.CreateRoutineLoadCommand;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshCatalogCommand;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshDatabaseCommand;
import org.apache.doris.nereids.trees.plans.commands.refresh.RefreshTableCommand;
import org.apache.doris.nereids.trees.plans.commands.use.SwitchCommand;

/** CommandVisitor. */
Expand Down Expand Up @@ -415,6 +416,10 @@ default R visitRefreshDatabaseCommand(RefreshDatabaseCommand refreshDatabaseComm
return visitCommand(refreshDatabaseCommand, context);
}

default R visitRefreshTableCommand(RefreshTableCommand refreshTableCommand, C context) {
return visitCommand(refreshTableCommand, context);
}

default R visitShowBackendsCommand(ShowBackendsCommand showBackendsCommand, C context) {
return visitCommand(showBackendsCommand, context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ new_mysql_table1
new_mysql_table1
new_mysql_table2

-- !show_create_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !preceding_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !subsequent_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL,\n `new_column` int NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !preceding_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL,\n `new_column` int NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !subsequent_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL,\n `new_column` int NULL,\n `new_column_1` int NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !preceding_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL,\n `new_column` int NULL,\n `new_column_1` int NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !subsequent_refresh_table --
new_mysql_table2 CREATE TABLE `new_mysql_table2` (\n `id` int NULL,\n `name` varchar(20) NULL,\n `new_column` int NULL,\n `new_column_1` int NULL,\n `new_column_2` int NULL\n) ENGINE=JDBC_EXTERNAL_TABLE;

-- !preceding_drop_external_database --
DORIS
Doris
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,24 @@ suite("test_nereids_refresh_catalog", "p0,external,mysql,external_docker,externa
checkNereidsExecute("refresh database ${catalog_name}.${new_mysql_db} ;")
qt_subsequent_refresh_database """show tables;"""

qt_show_create_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
// add a column in external table
sql """CALL EXECUTE_STMT("${catalog_name}", "alter table ${new_mysql_db}.${new_mysql_table2} add new_column int;");"""
qt_preceding_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
//refresh table ctl.db.tb1
checkNereidsExecute("refresh table ${catalog_name}.${new_mysql_db}.${new_mysql_table2} ;")
qt_subsequent_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
sql """CALL EXECUTE_STMT("${catalog_name}", "alter table ${new_mysql_db}.${new_mysql_table2} add new_column_1 int;");"""
qt_preceding_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
// refresh table db.tbl
checkNereidsExecute("refresh table ${new_mysql_db}.${new_mysql_table2} ;")
qt_subsequent_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
sql """CALL EXECUTE_STMT("${catalog_name}", "alter table ${new_mysql_db}.${new_mysql_table2} add new_column_2 int;");"""
qt_preceding_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""
//refresh table tbl1
checkNereidsExecute("refresh table ${new_mysql_table2};")
qt_subsequent_refresh_table """show create table ${new_mysql_db}.${new_mysql_table2};"""

sql """CALL EXECUTE_STMT("${catalog_name}", "drop database if exists ${new_mysql_db} ;");"""
qt_preceding_drop_external_database """show databases;"""

Expand Down

0 comments on commit 14a0173

Please sign in to comment.