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

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


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new f2556ba1823 [feature](insert)support external hive truncate table DDL 
(#37659)
f2556ba1823 is described below

commit f2556ba1823fa2a1f79253151703a42cdb272d39
Author: slothever <18522955+w...@users.noreply.github.com>
AuthorDate: Fri Jul 12 22:37:47 2024 +0800

    [feature](insert)support external hive truncate table DDL (#37659)
    
    pick: #36801
---
 .../apache/doris/analysis/TruncateTableStmt.java   |   3 -
 .../main/java/org/apache/doris/catalog/Env.java    |   6 +-
 .../org/apache/doris/datasource/CatalogIf.java     |   3 +
 .../apache/doris/datasource/ExternalCatalog.java   |  23 +++++
 .../doris/datasource/hive/HMSCachedClient.java     |   2 +
 .../doris/datasource/hive/HiveMetadataOps.java     |  16 ++++
 .../hive/PostgreSQLJdbcHMSCachedClient.java        |   4 +
 .../datasource/hive/ThriftHMSCachedClient.java     |  19 +++-
 .../datasource/iceberg/IcebergMetadataOps.java     |   5 ++
 .../datasource/operations/ExternalMetadataOps.java |   8 ++
 .../doris/datasource/TestHMSCachedClient.java      |   3 +
 .../hive/ddl/test_hive_truncate_table.out          |  24 +++++
 .../hive/ddl/test_hive_truncate_table.groovy       | 100 +++++++++++++++++++++
 13 files changed, 210 insertions(+), 6 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/TruncateTableStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/TruncateTableStmt.java
index a275879692c..1a9fbd3bafd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TruncateTableStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TruncateTableStmt.java
@@ -23,7 +23,6 @@ import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.util.InternalDatabaseUtil;
-import org.apache.doris.common.util.Util;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.qe.ConnectContext;
 
@@ -44,8 +43,6 @@ public class TruncateTableStmt extends DdlStmt {
     public void analyze(Analyzer analyzer) throws AnalysisException, 
UserException {
         super.analyze(analyzer);
         tblRef.getName().analyze(analyzer);
-        // disallow external catalog
-        Util.prohibitExternalCatalog(tblRef.getName().getCtl(), 
this.getClass().getSimpleName());
 
         if (tblRef.hasExplicitAlias()) {
             throw new AnalysisException("Not support truncate table with 
alias");
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index ea8ffd91d2e..9b73a4517f0 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -5427,8 +5427,10 @@ public class Env {
      * otherwise, it will only truncate those specified partitions.
      *
      */
-    public void truncateTable(TruncateTableStmt truncateTableStmt) throws 
DdlException {
-        getInternalCatalog().truncateTable(truncateTableStmt);
+    public void truncateTable(TruncateTableStmt stmt) throws DdlException {
+        CatalogIf<?> catalogIf = 
catalogMgr.getCatalogOrException(stmt.getTblRef().getName().getCtl(),
+                catalog -> new DdlException(("Unknown catalog " + catalog)));
+        catalogIf.truncateTable(stmt);
     }
 
     public void replayTruncateTable(TruncateTableInfo info) throws 
MetaNotFoundException {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogIf.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogIf.java
index ceee1a68157..a79897c67df 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogIf.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogIf.java
@@ -22,6 +22,7 @@ import org.apache.doris.analysis.CreateTableStmt;
 import org.apache.doris.analysis.DropDbStmt;
 import org.apache.doris.analysis.DropTableStmt;
 import org.apache.doris.analysis.TableName;
+import org.apache.doris.analysis.TruncateTableStmt;
 import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.TableIf;
@@ -194,4 +195,6 @@ public interface CatalogIf<T extends DatabaseIf> {
     boolean createTable(CreateTableStmt stmt) throws UserException;
 
     void dropTable(DropTableStmt stmt) throws DdlException;
+
+    void truncateTable(TruncateTableStmt truncateTableStmt) throws 
DdlException;
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
index 0fbedf57e66..82f4d309c82 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
@@ -22,6 +22,8 @@ import org.apache.doris.analysis.CreateTableStmt;
 import org.apache.doris.analysis.DropDbStmt;
 import org.apache.doris.analysis.DropTableStmt;
 import org.apache.doris.analysis.TableName;
+import org.apache.doris.analysis.TableRef;
+import org.apache.doris.analysis.TruncateTableStmt;
 import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.InfoSchemaDb;
@@ -821,4 +823,25 @@ public abstract class ExternalCatalog
         }
         return ret;
     }
+
+    @Override
+    public void truncateTable(TruncateTableStmt stmt) throws DdlException {
+        makeSureInitialized();
+        if (metadataOps == null) {
+            throw new UnsupportedOperationException("Truncate table not 
supported in " + getName());
+        }
+        try {
+            TableRef tableRef = stmt.getTblRef();
+            TableName tableName = tableRef.getName();
+            // delete all table data if null
+            List<String> partitions = null;
+            if (tableRef.getPartitionNames() != null) {
+                partitions = tableRef.getPartitionNames().getPartitionNames();
+            }
+            metadataOps.truncateTable(tableName.getDb(), tableName.getTbl(), 
partitions);
+        } catch (Exception e) {
+            LOG.warn("Failed to drop a table", e);
+            throw e;
+        }
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSCachedClient.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSCachedClient.java
index c9d0ce1736b..1ac77972053 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSCachedClient.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HMSCachedClient.java
@@ -94,6 +94,8 @@ public interface HMSCachedClient {
 
     void dropTable(String dbName, String tableName);
 
+    void truncateTable(String dbName, String tblName, List<String> partitions);
+
     void createTable(TableMetadata catalogTable, boolean ignoreIfExists);
 
     void updateTableStatistics(
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
index 70c61875b8a..7267297c93e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetadataOps.java
@@ -251,6 +251,22 @@ public class HiveMetadataOps implements 
ExternalMetadataOps {
         }
     }
 
+    @Override
+    public void truncateTable(String dbName, String tblName, List<String> 
partitions) throws DdlException {
+        ExternalDatabase<?> db = catalog.getDbNullable(dbName);
+        if (db == null) {
+            throw new DdlException("Failed to get database: '" + dbName + "' 
in catalog: " + catalog.getName());
+        }
+        try {
+            client.truncateTable(dbName, tblName, partitions);
+        } catch (Exception e) {
+            throw new DdlException(e.getMessage(), e);
+        }
+        
Env.getCurrentEnv().getExtMetaCacheMgr().invalidateTableCache(catalog.getId(), 
dbName, tblName);
+        db.setLastUpdateTime(System.currentTimeMillis());
+        db.setUnInitialized(true);
+    }
+
     @Override
     public List<String> listTableNames(String dbName) {
         return client.getAllTables(dbName);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/PostgreSQLJdbcHMSCachedClient.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/PostgreSQLJdbcHMSCachedClient.java
index 8e41b48bfdd..0cdb3e469c2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/PostgreSQLJdbcHMSCachedClient.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/PostgreSQLJdbcHMSCachedClient.java
@@ -546,6 +546,10 @@ public class PostgreSQLJdbcHMSCachedClient extends 
JdbcHMSCachedClient {
         throw new NotImplementedException("PostgreSQL dropDatabase not 
implemented");
     }
 
+    public void truncateTable(String dbName, String tblName, List<String> 
partitions) {
+        throw new NotImplementedException("PostgreSQL truncateTable not 
implemented");
+    }
+
     public void createTable(TableMetadata hiveTable, boolean ignoreIfExists) {
         throw new NotImplementedException("PostgreSQL createTable not 
implemented");
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/ThriftHMSCachedClient.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/ThriftHMSCachedClient.java
index 17fbcb09b02..55d8ffc2e02 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/ThriftHMSCachedClient.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/ThriftHMSCachedClient.java
@@ -244,6 +244,23 @@ public class ThriftHMSCachedClient implements 
HMSCachedClient {
         }
     }
 
+    @Override
+    public void truncateTable(String dbName, String tblName, List<String> 
partitions) {
+        try (ThriftHMSClient client = getClient()) {
+            try {
+                ugiDoAs(() -> {
+                    client.client.truncateTable(dbName, tblName, partitions);
+                    return null;
+                });
+            } catch (Exception e) {
+                client.setThrowable(e);
+                throw e;
+            }
+        } catch (Exception e) {
+            throw new HMSClientException("failed to truncate table %s in db 
%s.", e, tblName, dbName);
+        }
+    }
+
     @Override
     public boolean tableExists(String dbName, String tblName) {
         try (ThriftHMSClient client = getClient()) {
@@ -272,7 +289,7 @@ public class ThriftHMSCachedClient implements 
HMSCachedClient {
                 throw e;
             }
         } catch (Exception e) {
-            throw new HMSClientException("failed to check if table %s in db %s 
exists", e, tblName, dbName);
+            throw new HMSClientException("failed to list partitions in table 
'%s.%s'.", e, dbName, tblName);
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
index 7161f48680a..c7fef68ee97 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
@@ -173,4 +173,9 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
         catalog.dropTable(TableIdentifier.of(dbName, tableName));
         db.setUnInitialized(true);
     }
+
+    @Override
+    public void truncateTable(String dbName, String tblName, List<String> 
partitions) {
+        throw new UnsupportedOperationException("Truncate Iceberg table is not 
supported.");
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/operations/ExternalMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/operations/ExternalMetadataOps.java
index 9426442cebb..0333124b352 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/operations/ExternalMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/operations/ExternalMetadataOps.java
@@ -60,6 +60,14 @@ public interface ExternalMetadataOps {
      */
     void dropTable(DropTableStmt stmt) throws DdlException;
 
+    /**
+     *
+     * @param dbName
+     * @param tblName
+     * @param partitions
+     */
+    void truncateTable(String dbName, String tblName, List<String> partitions) 
throws DdlException;
+
     /**
      *
      * @return
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/TestHMSCachedClient.java 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/TestHMSCachedClient.java
index 6f969257245..f3cb918d6f5 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/TestHMSCachedClient.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/TestHMSCachedClient.java
@@ -235,6 +235,9 @@ public class TestHMSCachedClient implements HMSCachedClient 
{
         this.partitions.remove(new HMSTransaction.DatabaseTableName(dbName, 
tableName));
     }
 
+    @Override
+    public void truncateTable(String dbName, String tblName, List<String> 
partitions) {}
+
     @Override
     public void createTable(TableMetadata tbl, boolean ignoreIfExists) {
         String dbName = tbl.getDbName();
diff --git 
a/regression-test/data/external_table_p0/hive/ddl/test_hive_truncate_table.out 
b/regression-test/data/external_table_p0/hive/ddl/test_hive_truncate_table.out
new file mode 100644
index 00000000000..24d6cade5d2
--- /dev/null
+++ 
b/regression-test/data/external_table_p0/hive/ddl/test_hive_truncate_table.out
@@ -0,0 +1,24 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !truncate_01_pre --
+222    aoe
+3234424        44
+
+-- !truncate_01 --
+
+-- !truncate_02 --
+
+-- !truncate_03 --
+
+-- !truncate_04_pre --
+33     awe     wuu     2023-02-04
+5535   3       dre     2023-04-04
+
+-- !truncate_04 --
+
+-- !truncate_06 --
+44     etg     wuweu   2022-02-04
+555    etgf    wet     2021-05-06
+88     etg     wuweu   2022-01-04
+95     etgf    hiyr    2021-05-06
+
+-- !truncate_09 --
diff --git 
a/regression-test/suites/external_table_p0/hive/ddl/test_hive_truncate_table.groovy
 
b/regression-test/suites/external_table_p0/hive/ddl/test_hive_truncate_table.groovy
new file mode 100644
index 00000000000..94082d0287f
--- /dev/null
+++ 
b/regression-test/suites/external_table_p0/hive/ddl/test_hive_truncate_table.groovy
@@ -0,0 +1,100 @@
+// 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_hive_truncate_table", 
"p0,external,hive,external_docker,external_docker_hive") {
+    String enabled = context.config.otherConfigs.get("enableHiveTest")
+    if (enabled != null && enabled.equalsIgnoreCase("true")) {
+        String externalEnvIp = context.config.otherConfigs.get("externalEnvIp")
+        String hms_port = context.config.otherConfigs.get("hive3HmsPort")
+        String hdfs_port = context.config.otherConfigs.get("hive3HdfsPort")
+        String catalog_name = "test_hive3_truncate_table"
+        sql """drop catalog if exists ${catalog_name};"""
+
+        sql """
+            create catalog if not exists ${catalog_name} properties (
+                'type'='hms',
+                'hive.metastore.uris' = 
'thrift://${externalEnvIp}:${hms_port}',
+                'fs.defaultFS' = 'hdfs://${externalEnvIp}:${hdfs_port}',
+                'use_meta_cache' = 'true',
+                'hive.version'='3.0'
+            );
+        """
+
+        logger.info("catalog " + catalog_name + " created")
+        sql """switch ${catalog_name};"""
+        logger.info("switched to catalog " + catalog_name)
+        sql """create database if not exists `hive_truncate`;"""
+        sql """use `hive_truncate`;"""
+
+        // 1. test no partition table
+        sql """create table if not exists `table_no_pars`(col1 bigint, col2 
string) engine=hive; """
+        sql """truncate table table_no_pars;"""
+
+        sql """insert into `table_no_pars` values(3234424, '44'); """
+        sql """insert into `table_no_pars` values(222, 'aoe'); """
+        order_qt_truncate_01_pre """ select * from table_no_pars;  """
+        sql """truncate table table_no_pars;"""
+        order_qt_truncate_01 """ select * from table_no_pars; """
+
+        sql """insert into `table_no_pars` values(3234424, '44'); """
+        sql """truncate table hive_truncate.table_no_pars;"""
+        order_qt_truncate_02 """ select * from table_no_pars;  """
+
+        sql """insert into `table_no_pars` values(222, 'aoe'); """
+        sql """truncate table ${catalog_name}.hive_truncate.table_no_pars;"""
+        order_qt_truncate_03 """ select * from table_no_pars; """
+        sql """insert into `table_no_pars` values(222, 'aoe'); """
+        sql """drop table table_no_pars """
+
+        // 2. test partition table
+        sql """create table if not exists `table_with_pars`(col1 bigint, col2 
string, pt1 varchar, pt2 date) engine=hive
+               partition by list(pt1, pt2)() """
+        sql """truncate table table_with_pars;"""
+
+        sql """insert into `table_with_pars` values(33, 'awe', 'wuu', 
'2023-02-04') """
+        sql """insert into `table_with_pars` values(5535, '3', 'dre', 
'2023-04-04') """
+        order_qt_truncate_04_pre """  select * from table_with_pars; """
+        sql """truncate table table_with_pars;"""
+        order_qt_truncate_04 """ select * from table_with_pars; """
+
+        // 3. test partition table and truncate partitions
+        sql """insert into `table_with_pars` values(44, 'etg', 'wuweu', 
'2022-02-04') """
+        sql """insert into `table_with_pars` values(88, 'etg', 'wuweu', 
'2022-01-04') """
+        sql """insert into `table_with_pars` values(095, 'etgf', 'hiyr', 
'2021-05-06') """
+        sql """insert into `table_with_pars` values(555, 'etgf', 'wet', 
'2021-05-06') """
+        // sql """truncate table hive_truncate.table_with_pars partition 
pt1;"""
+        // order_qt_truncate_05 """ select * from table_with_pars; """
+        // sql """truncate table hive_truncate.table_with_pars partition 
pt2;"""
+        order_qt_truncate_06 """ select * from table_with_pars; """
+
+        sql """insert into `table_with_pars` values(22, 'ttt', 'gggw', 
'2022-02-04')"""
+        sql """insert into `table_with_pars` values(44, 'etg', 'wuweu', 
'2022-02-04') """
+        sql """insert into `table_with_pars` values(88, 'etg', 'wuweu', 
'2022-01-04') """
+        sql """insert into `table_with_pars` values(095, 'etgf', 'hiyr', 
'2021-05-06') """
+        sql """insert into `table_with_pars` values(555, 'etgf', 'wet', 
'2021-05-06') """
+        // sql """truncate table ${catalog_name}.hive_truncate.table_with_pars 
partition pt1;"""
+        // order_qt_truncate_07 """ select * from table_with_pars; """
+        // sql """truncate table ${catalog_name}.hive_truncate.table_with_pars 
partition pt2;"""
+        // order_qt_truncate_08 """ select * from table_with_pars; """
+        sql """truncate table table_with_pars"""
+        order_qt_truncate_09 """ select * from table_with_pars; """
+
+        sql """drop table table_with_pars """
+        sql """drop database hive_truncate;"""
+        sql """drop catalog ${catalog_name};"""
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to