This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git

commit e840102e9990541ab412e0a78849e8d2bf545097
Author: feiniaofeiafei <[email protected]>
AuthorDate: Sun Apr 28 12:15:01 2024 +0800

    [Feat](nereids)nereids support create table like (#34025)
    
    nereids support create table like statement.
    e.g. CREATE TABLE test1.table2 LIKE test1.table1
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |  3 +
 .../doris/nereids/parser/LogicalPlanBuilder.java   | 20 ++++++
 .../apache/doris/nereids/trees/plans/PlanType.java |  4 +-
 .../plans/commands/CreateTableLikeCommand.java     | 49 ++++++++++++++
 .../plans/commands/info/CreateTableLikeInfo.java   | 77 ++++++++++++++++++++++
 .../trees/plans/visitor/CommandVisitor.java        |  5 ++
 .../data/ddl_p0/test_create_table_like_nereids.out | 20 ++++++
 .../ddl_p0/test_create_table_like_nereids.groovy   | 75 +++++++++++++++++++++
 8 files changed, 251 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 764a5625185..f3f712742ed 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
@@ -65,6 +65,9 @@ statementBase
         (COMMENT STRING_LITERAL)? AS query                                
#createView
     | ALTER VIEW name=multipartIdentifier (LEFT_PAREN cols=simpleColumnDefs 
RIGHT_PAREN)?
         AS query                                                          
#alterView
+    | CREATE (EXTERNAL)? TABLE (IF NOT EXISTS)? name=multipartIdentifier
+      LIKE existedTable=multipartIdentifier
+      (WITH ROLLUP (rollupNames=identifierList)?)?           #createTableLike
     | explain? INSERT (INTO | OVERWRITE TABLE)
         (tableName=multipartIdentifier | DORIS_INTERNAL_TABLE_ID LEFT_PAREN 
tableId=INTEGER_VALUE RIGHT_PAREN)
         partitionSpec?  // partition define
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 e44609d75fc..76bd5997085 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
@@ -78,6 +78,7 @@ import org.apache.doris.nereids.DorisParser.CreateMTMVContext;
 import org.apache.doris.nereids.DorisParser.CreateProcedureContext;
 import org.apache.doris.nereids.DorisParser.CreateRowPolicyContext;
 import org.apache.doris.nereids.DorisParser.CreateTableContext;
+import org.apache.doris.nereids.DorisParser.CreateTableLikeContext;
 import org.apache.doris.nereids.DorisParser.CreateViewContext;
 import org.apache.doris.nereids.DorisParser.CteContext;
 import org.apache.doris.nereids.DorisParser.DataTypeWithNullableContext;
@@ -364,6 +365,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateTableLikeCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromUsingCommand;
@@ -393,6 +395,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.info.CancelMTMVTaskInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.ColumnDefinition;
 import org.apache.doris.nereids.trees.plans.commands.info.CreateMTMVInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.CreateTableInfo;
+import org.apache.doris.nereids.trees.plans.commands.info.CreateTableLikeInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.CreateViewInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.DMLCommandType;
 import org.apache.doris.nereids.trees.plans.commands.info.DefaultValue;
@@ -3499,4 +3502,21 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
     public Object visitUnsupported(UnsupportedContext ctx) {
         return UnsupportedCommand.INSTANCE;
     }
+
+    @Override
+    public LogicalPlan visitCreateTableLike(CreateTableLikeContext ctx) {
+        List<String> nameParts = visitMultipartIdentifier(ctx.name);
+        List<String> existedTableNameParts = 
visitMultipartIdentifier(ctx.existedTable);
+        ArrayList<String> rollupNames = Lists.newArrayList();
+        boolean withAllRollUp = false;
+        if (ctx.WITH() != null && ctx.rollupNames != null) {
+            rollupNames = new 
ArrayList<>(visitIdentifierList(ctx.rollupNames));
+        } else if (ctx.WITH() != null && ctx.rollupNames == null) {
+            withAllRollUp = true;
+        }
+        CreateTableLikeInfo info = new CreateTableLikeInfo(ctx.EXISTS() != 
null,
+                new TableNameInfo(nameParts), new 
TableNameInfo(existedTableNameParts),
+                rollupNames, withAllRollUp);
+        return new CreateTableLikeCommand(info);
+    }
 }
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 3db3ffa3d93..4aeecdfd507 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
@@ -153,6 +153,6 @@ public enum PlanType {
     SHOW_CREATE_PROCEDURE_COMMAND,
     CREATE_VIEW_COMMAND,
     ALTER_VIEW_COMMAND,
-
-    UNSUPPORTED_COMMAND
+    UNSUPPORTED_COMMAND,
+    CREATE_TABLE_LIKE_COMMAND
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableLikeCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableLikeCommand.java
new file mode 100644
index 00000000000..a271623ef08
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableLikeCommand.java
@@ -0,0 +1,49 @@
+// 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.analysis.CreateTableLikeStmt;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.commands.info.CreateTableLikeInfo;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+/** CreateTableLikeCommand */
+public class CreateTableLikeCommand extends Command implements ForwardWithSync 
{
+    private final CreateTableLikeInfo info;
+
+    public CreateTableLikeCommand(CreateTableLikeInfo info) {
+        super(PlanType.CREATE_TABLE_LIKE_COMMAND);
+        this.info = info;
+    }
+
+    @Override
+    public void run(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        executor.checkBlockRules();
+        info.validate(ctx);
+        CreateTableLikeStmt stmt = info.translateToLegacyStmt();
+        Env.getCurrentEnv().createTableLike(stmt);
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitCreateTableLikeCommand(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableLikeInfo.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableLikeInfo.java
new file mode 100644
index 00000000000..5428898d403
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableLikeInfo.java
@@ -0,0 +1,77 @@
+// 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.info;
+
+import org.apache.doris.analysis.CreateTableLikeStmt;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.DdlException;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.FeNameFormat;
+import org.apache.doris.common.util.Util;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.qe.ConnectContext;
+
+import java.util.ArrayList;
+
+/** CreateTableLikeInfo */
+public class CreateTableLikeInfo {
+    private final boolean ifNotExists;
+    private final TableNameInfo tableName;
+    private final TableNameInfo existedTableName;
+    private final ArrayList<String> rollupNames;
+    private final boolean withAllRollup;
+
+    public CreateTableLikeInfo(boolean ifNotExists, TableNameInfo tableName, 
TableNameInfo existedTableName,
+            ArrayList<String> rollupNames, boolean withAllRollup) {
+        this.ifNotExists = ifNotExists;
+        this.tableName = tableName;
+        this.existedTableName = existedTableName;
+        this.rollupNames = rollupNames;
+        this.withAllRollup = withAllRollup;
+    }
+
+    public CreateTableLikeStmt translateToLegacyStmt() throws DdlException {
+        return new CreateTableLikeStmt(ifNotExists, 
tableName.transferToTableName(),
+                existedTableName.transferToTableName(), rollupNames, 
withAllRollup);
+    }
+
+    /** validate */
+    public void validate(ConnectContext ctx) throws AnalysisException {
+        existedTableName.analyze(ctx);
+        // disallow external catalog
+        Util.prohibitExternalCatalog(existedTableName.getCtl(), 
"CreateTableLikeStmt");
+        //check privilege
+        if (!Env.getCurrentEnv().getAccessManager()
+                .checkTblPriv(ctx, existedTableName.getCtl(), 
existedTableName.getDb(),
+                        existedTableName.getTbl(), PrivPredicate.SELECT)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"SELECT");
+        }
+
+        tableName.analyze(ctx);
+        // disallow external catalog
+        Util.prohibitExternalCatalog(tableName.getCtl(), 
"CreateTableLikeStmt");
+        FeNameFormat.checkTableName(tableName.getTbl());
+        //check privilege
+        if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, 
tableName.getCtl(), tableName.getDb(),
+                tableName.getTbl(), PrivPredicate.CREATE)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"CREATE");
+        }
+    }
+}
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 f82dd1a794e..2aafd94ee42 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
@@ -27,6 +27,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateTableLikeCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromUsingCommand;
@@ -171,4 +172,8 @@ public interface CommandVisitor<R, C> {
     default R visitUnsupportedCommand(UnsupportedCommand unsupportedCommand, C 
context) {
         return visitCommand(unsupportedCommand, context);
     }
+
+    default R visitCreateTableLikeCommand(CreateTableLikeCommand 
createTableLikeCommand, C context) {
+        return visitCommand(createTableLikeCommand, context);
+    }
 }
diff --git a/regression-test/data/ddl_p0/test_create_table_like_nereids.out 
b/regression-test/data/ddl_p0/test_create_table_like_nereids.out
new file mode 100644
index 00000000000..4ecbecb1505
--- /dev/null
+++ b/regression-test/data/ddl_p0/test_create_table_like_nereids.out
@@ -0,0 +1,20 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !test_without_roll_up --
+1      1       2
+1      1       4
+1      3       6
+2      1       3
+2      1       4
+2      1       7
+2      3       5
+2      3       9
+2      4       2
+3      2       8
+3      5       \N
+3      5       6
+3      5       6
+3      5       8
+4      5       6
+6      \N      6
+6      7       1
+
diff --git 
a/regression-test/suites/ddl_p0/test_create_table_like_nereids.groovy 
b/regression-test/suites/ddl_p0/test_create_table_like_nereids.groovy
new file mode 100644
index 00000000000..c1a0f74e034
--- /dev/null
+++ b/regression-test/suites/ddl_p0/test_create_table_like_nereids.groovy
@@ -0,0 +1,75 @@
+// 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_create_table_like_nereids") {
+    sql "SET enable_nereids_planner=true;"
+    sql "SET enable_fallback_to_original_planner=false;"
+
+    sql "drop table if exists mal_test_create_table_like"
+    sql """create table mal_test_create_table_like(pk int, a int, b int) 
distributed by hash(pk) buckets 10
+    properties('replication_num' = '1');"""
+    sql """insert into mal_test_create_table_like 
values(2,1,3),(1,1,2),(3,5,6),(6,null,6),(4,5,6),(2,1,4),(2,3,5),(1,1,4)
+    
,(3,5,6),(3,5,null),(6,7,1),(2,1,7),(2,4,2),(2,3,9),(1,3,6),(3,5,8),(3,2,8);"""
+    sql "sync"
+    sql "alter table mal_test_create_table_like add rollup ru1(a,pk);"
+    sleep(2000)
+    sql "alter table mal_test_create_table_like add rollup ru2(b,pk);"
+    sleep(2000)
+
+    // no rollup
+    sql "drop table if exists table_like"
+    sql "CREATE TABLE table_like LIKE mal_test_create_table_like;"
+    sql """insert into table_like 
values(2,1,3),(1,1,2),(3,5,6),(6,null,6),(4,5,6),(2,1,4),(2,3,5),(1,1,4)
+    
,(3,5,6),(3,5,null),(6,7,1),(2,1,7),(2,4,2),(2,3,9),(1,3,6),(3,5,8),(3,2,8);"""
+    "sync"
+    qt_test_without_roll_up "select * from table_like order by pk,a,b;"
+
+    // with all rollup
+    sql "drop table if exists table_like_with_roll_up"
+    sql "CREATE TABLE table_like_with_roll_up LIKE mal_test_create_table_like 
with rollup;"
+    explain {
+        sql ("select sum(a) from table_like_with_roll_up group by a")
+        contains "ru1"
+    } ;
+    explain {
+        sql ("select sum(b) from table_like_with_roll_up group by b,pk ;")
+        contains "ru2"
+    } ;
+
+    // with partial rollup
+    sql "drop table if exists table_like_with_partial_roll_up;"
+    sql "CREATE TABLE table_like_with_partial_roll_up LIKE 
mal_test_create_table_like with rollup (ru1);"
+    sql "select * from table_like_with_partial_roll_up order by pk, a, b"
+    explain {
+        sql("select sum(a) from table_like_with_partial_roll_up group by a")
+        contains("ru1")
+    } ;
+    explain {
+        sql ("select sum(b) from table_like_with_partial_roll_up group by b,pk 
;")
+        notContains "ru2"
+    } ;
+    sql """insert into table_like_with_partial_roll_up 
values(2,1,3),(1,1,2),(3,5,6),(6,null,6),(4,5,6),(2,1,4),(2,3,5),(1,1,4)
+    
,(3,5,6),(3,5,null),(6,7,1),(2,1,7),(2,4,2),(2,3,9),(1,3,6),(3,5,8),(3,2,8);"""
+    sql "sync"
+    sleep(2000)
+    sql "select sum(a) from table_like_with_partial_roll_up group by a order 
by 1"
+
+    // test if not exists
+    sql "drop table if exists table_like_with_partial_roll_up_exists"
+    sql """CREATE TABLE if not exists table_like_with_partial_roll_up_exists
+    LIKE mal_test_create_table_like with rollup (ru1);"""
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to