This is an automated email from the ASF dual-hosted git repository.
starocean999 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 14a01734e08 [feat](nereids)support refresh table command (#45546)
14a01734e08 is described below
commit 14a01734e08cc81c47e323df8ea8fc5048386d73
Author: Petrichor <[email protected]>
AuthorDate: Thu Dec 19 11:36:12 2024 +0800
[feat](nereids)support refresh table command (#45546)
Issue Number: close https://github.com/apache/doris/issues/42578
---
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 4 +-
.../doris/nereids/parser/LogicalPlanBuilder.java | 14 ++++
.../apache/doris/nereids/trees/plans/PlanType.java | 1 +
.../commands/refresh/RefreshTableCommand.java | 84 ++++++++++++++++++++++
.../trees/plans/visitor/CommandVisitor.java | 5 ++
.../test_nereids_refresh_catalog.out | 21 ++++++
.../test_nereids_refresh_catalog.groovy | 18 +++++
7 files changed, 145 insertions(+), 2 deletions(-)
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 64ff9209bfe..ad884eefee1 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
@@ -457,6 +457,7 @@ channelDescription
supportedRefreshStatement
: REFRESH CATALOG name=identifier propertyClause?
#refreshCatalog
| REFRESH DATABASE name=multipartIdentifier propertyClause?
#refreshDatabase
+ | REFRESH TABLE name=multipartIdentifier
#refreshTable
;
supportedCleanStatement
@@ -464,8 +465,7 @@ supportedCleanStatement
;
unsupportedRefreshStatement
- : REFRESH TABLE name=multipartIdentifier
#refreshTable
- | REFRESH LDAP (ALL | (FOR user=identifierOrText))
#refreshLdap
+ : REFRESH LDAP (ALL | (FOR user=identifierOrText))
#refreshLdap
;
unsupportedCleanStatement
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 951c8b342d5..4c5d43cb4db 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
@@ -208,6 +208,7 @@ import
org.apache.doris.nereids.DorisParser.RefreshDatabaseContext;
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;
@@ -670,6 +671,7 @@ import
org.apache.doris.nereids.trees.plans.commands.load.LoadSequenceClause;
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;
@@ -4464,6 +4466,18 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
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());
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 9ed408dfe05..0cec8c48caf 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
@@ -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,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/refresh/RefreshTableCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/refresh/RefreshTableCommand.java
new file mode 100644
index 00000000000..71d77ab22b3
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/refresh/RefreshTableCommand.java
@@ -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();
+ }
+
+}
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 eb764be57c0..f988055f0f6 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
@@ -144,6 +144,7 @@ import
org.apache.doris.nereids.trees.plans.commands.insert.InsertOverwriteTable
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. */
@@ -415,6 +416,10 @@ public interface CommandVisitor<R, C> {
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);
}
diff --git
a/regression-test/data/external_table_p0/nereids_commands/test_nereids_refresh_catalog.out
b/regression-test/data/external_table_p0/nereids_commands/test_nereids_refresh_catalog.out
index c3f57d7ba81..66ca9363d71 100644
---
a/regression-test/data/external_table_p0/nereids_commands/test_nereids_refresh_catalog.out
+++
b/regression-test/data/external_table_p0/nereids_commands/test_nereids_refresh_catalog.out
@@ -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
diff --git
a/regression-test/suites/external_table_p0/nereids_commands/test_nereids_refresh_catalog.groovy
b/regression-test/suites/external_table_p0/nereids_commands/test_nereids_refresh_catalog.groovy
index 87dacd41425..8fbaa486610 100644
---
a/regression-test/suites/external_table_p0/nereids_commands/test_nereids_refresh_catalog.groovy
+++
b/regression-test/suites/external_table_p0/nereids_commands/test_nereids_refresh_catalog.groovy
@@ -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;"""
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]