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

michaelsmith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/master by this push:
     new 6a0eedf4a IMPALA-13299: Support CREATE TABLE LIKE for Iceberg from 
HDFS sources
6a0eedf4a is described below

commit 6a0eedf4af137828257529501ace360208af0a3c
Author: Arnab Karmakar <[email protected]>
AuthorDate: Tue Dec 2 23:17:38 2025 +0530

    IMPALA-13299: Support CREATE TABLE LIKE for Iceberg from HDFS sources
    
    This patch enables creating Iceberg tables from non-Iceberg HDFS source
    tables (Parquet, ORC, etc.) using CREATE TABLE LIKE with STORED BY ICEBERG.
    This provides a metadata-only operation to convert table schemas to Iceberg
    format without copying data.
    
    Supported source types: Parquet, ORC, Avro, Text, and other HDFS-based 
formats
    Not supported: Kudu tables, JDBC tables, Paimon tables
    
    Use case: This is particularly useful for Apache Hive 3.1 environments where
    CTAS (CREATE TABLE AS SELECT) with STORED BY ICEBERG is not supported - that
    feature requires Hive 4.0+. Users can use CREATE TABLE LIKE to create the
    Iceberg schema, then use INSERT INTO to migrate data.
    
    Testing:
    - Comprehensive tests covering schema conversion with various data types,
      partitioned and external tables, complex types (STRUCT, ARRAY, MAP)
    - Bidirectional conversion tests (non-Iceberg → Iceberg and reverse)
    - Hive interoperability tests verifying data round-trips correctly
    
    Change-Id: Id162f217e49e9f396419b09815b92eb7f351881e
    Reviewed-on: http://gerrit.cloudera.org:8080/23733
    Reviewed-by: Impala Public Jenkins <[email protected]>
    Tested-by: Impala Public Jenkins <[email protected]>
---
 docs/topics/impala_iceberg.xml                     |  46 ++-
 .../impala/analysis/CreateTableLikeStmt.java       |  18 +-
 .../apache/impala/service/CatalogOpExecutor.java   |  69 ++++
 .../org/apache/impala/analysis/AnalyzeDDLTest.java |  19 ++
 .../iceberg-create-table-like-non-iceberg.test     | 349 +++++++++++++++++++++
 .../queries/QueryTest/iceberg-negative.test        |   3 +-
 tests/query_test/test_iceberg.py                   |   6 +
 7 files changed, 497 insertions(+), 13 deletions(-)

diff --git a/docs/topics/impala_iceberg.xml b/docs/topics/impala_iceberg.xml
index f2d474032..70e6b446d 100644
--- a/docs/topics/impala_iceberg.xml
+++ b/docs/topics/impala_iceberg.xml
@@ -1054,15 +1054,53 @@ ORDER BY made_current_at;
     <conbody>
       <p>
         Use <codeph>CREATE TABLE ... LIKE ...</codeph> to create an empty 
Iceberg table
-        based on the definition of another Iceberg table, including any column 
attributes in
-        the original table:
+        based on the definition of another table, including any column 
attributes in
+        the original table. When cloning from an Iceberg table, the 
<codeph>STORED BY
+        ICEBERG</codeph> clause is optional (the format is inherited). When 
cloning from
+        a non-Iceberg table, you must explicitly specify <codeph>STORED BY 
ICEBERG</codeph>:
         <codeblock>
+          -- From an Iceberg table (format inherited)
           CREATE TABLE new_ice_tbl LIKE orig_ice_tbl;
+
+          -- From a non-Iceberg table (must specify format)
+          CREATE TABLE new_ice_tbl LIKE parquet_tbl STORED BY ICEBERG;
+        </codeblock>
+      </p>
+      <p>
+        When creating from a non-Iceberg source table, Impala automatically 
converts
+        the schema to Iceberg's format. All supported Impala types (including 
complex
+        types like STRUCT, ARRAY, and MAP) are converted to their Iceberg 
equivalents.
+        If the source table has partition columns, they are converted to 
identity-partitioned
+        columns in the new Iceberg table.
+      </p>
+      <p>
+        Example creating an Iceberg table from a Parquet table:
+        <codeblock>
+          CREATE TABLE my_ice_tbl LIKE functional_parquet.complextypestbl 
STORED BY ICEBERG;
         </codeblock>
       </p>
       <p>
-        Because of the Data Types of Iceberg and Impala do not correspond one 
by one, Impala
-        can only clone between Iceberg tables.
+        <b>Limitations for CREATE TABLE LIKE with Iceberg:</b>
+      </p>
+      <p>
+        <b>Unsupported table types:</b>
+        <ul>
+          <li><b>Kudu tables:</b> CREATE TABLE LIKE is not supported between 
Kudu and
+            Iceberg tables because Kudu-specific features (hash partitioning, 
range
+            partitioning, primary key uniqueness constraints) do not have 
direct equivalents
+            in Iceberg's partitioning model.</li>
+          <li><b>JDBC tables:</b> Cannot be created as target tables with 
CREATE TABLE LIKE.</li>
+          <li><b>Paimon tables:</b> Cannot be used as source or target for 
CREATE TABLE LIKE.</li>
+          <li><b>Iceberg to non-Iceberg:</b> Creating non-Iceberg tables 
(Parquet, ORC, Text, etc.)
+            from Iceberg sources is not currently supported.</li>
+        </ul>
+      </p>
+      <p>
+        <b>Unsupported data types:</b>
+        <ul>
+          <li><b>TINYINT:</b> Iceberg does not support TINYINT type. Use INT 
instead.</li>
+          <li><b>SMALLINT:</b> Iceberg does not support SMALLINT type. Use INT 
instead.</li>
+        </ul>
       </p>
     </conbody>
   </concept>
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/CreateTableLikeStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/CreateTableLikeStmt.java
index 026b817a5..4b829fa66 100644
--- a/fe/src/main/java/org/apache/impala/analysis/CreateTableLikeStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/CreateTableLikeStmt.java
@@ -175,19 +175,21 @@ public class CreateTableLikeStmt extends StatementBase {
 
     validateCreateKuduTableParams(srcTable);
 
-    // Only clone between Iceberg tables because the Data Types of Iceberg and 
Impala
-    // do not correspond one by one, the transformation logic is in
-    // org.apache.impala.util.IcebergSchemaConverter.fromImpalaType method.
-    if (fileFormat_ == THdfsFileFormat.ICEBERG && !IcebergTable.isIcebergTable(
-        srcTable.getMetaStoreTable())) {
-      throw new AnalysisException(srcTable.getFullName() + " cannot be cloned 
into an "
-          + "Iceberg table because it is not an Iceberg table.");
-    } else if (fileFormat_ == THdfsFileFormat.JDBC) {
+    // Validate table format restrictions:
+    // - JDBC tables cannot be created with CREATE TABLE LIKE (target 
restriction)
+    // - Paimon tables cannot be used as source or target
+    // - Iceberg tables cannot be used to create non-Iceberg tables
+    if (fileFormat_ == THdfsFileFormat.JDBC) {
       throw new AnalysisException("CREATE TABLE LIKE is not supported for JDBC 
tables.");
     } else if (fileFormat_ == THdfsFileFormat.PAIMON
         || srcTable instanceof FePaimonTable) {
       throw new AnalysisException("CREATE TABLE LIKE is not supported for " +
           "PAIMON tables.");
+    } else if (IcebergTable.isIcebergTable(srcTable.getMetaStoreTable())
+        && fileFormat_ != null && fileFormat_ != THdfsFileFormat.ICEBERG) {
+      throw new AnalysisException(String.format(
+          "CREATE TABLE LIKE is not supported for creating %s table from 
Iceberg " +
+          "table %s.", fileFormat_.toString(), srcTable.getFullName()));
     }
 
     srcDbName_ = srcTable.getDb().getName();
diff --git a/fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java 
b/fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java
index 6c4319136..979983c2e 100644
--- a/fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java
+++ b/fe/src/main/java/org/apache/impala/service/CatalogOpExecutor.java
@@ -233,7 +233,10 @@ import org.apache.impala.thrift.THdfsCachingOp;
 import org.apache.impala.thrift.THdfsFileFormat;
 import org.apache.impala.thrift.TIcebergCatalog;
 import org.apache.impala.thrift.TImpalaTableType;
+import org.apache.impala.thrift.TIcebergPartitionField;
 import org.apache.impala.thrift.TIcebergPartitionSpec;
+import org.apache.impala.thrift.TIcebergPartitionTransform;
+import org.apache.impala.thrift.TIcebergPartitionTransformType;
 import org.apache.impala.thrift.TKuduPartitionParam;
 import org.apache.impala.thrift.TPaimonCatalog;
 import org.apache.impala.thrift.TPartitionDef;
@@ -4662,6 +4665,46 @@ public class CatalogOpExecutor {
           params.if_not_exists, columns, partitionSpec,
           
Lists.newArrayList(srcIceTable.getIcebergSchema().identifierFieldNames()),
           tableProperties, params.getComment(), debugAction);
+    } else if (!IcebergTable.isIcebergTable(srcTable.getMetaStoreTable())
+        && IcebergTable.isIcebergTable(tbl)) {
+      // Creating an Iceberg table from a non-Iceberg source table
+      // Kudu tables should have been rejected during analysis
+      // in validateCreateKuduTableParams()
+      Preconditions.checkState(!(srcTable instanceof KuduTable),
+          "Kudu tables should be rejected in analysis phase");
+
+      // For Iceberg, all columns (including partition columns) must be in the 
schema
+      // Column order matters: non-partitioning columns first, then 
partitioning columns
+      // This matches Hive's convention for INSERT and Iceberg's flat schema 
model
+      List<TColumn> columns = new ArrayList<>();
+      for (Column col: srcTable.getColumnsInHiveOrder()) {
+        TColumn tcol = col.toThrift();
+        // Default to nullable for Iceberg (optional fields) if not explicitly 
set
+        if (!tcol.isSetIs_nullable()) {
+          tcol.setIs_nullable(true);
+        }
+        columns.add(tcol);
+      }
+
+      // Convert partition keys to Iceberg partition spec with identity 
transforms
+      TIcebergPartitionSpec partitionSpec = null;
+      if (srcTable.getMetaStoreTable().isSetPartitionKeys()
+          && !srcTable.getMetaStoreTable().getPartitionKeys().isEmpty()) {
+        partitionSpec = createIdentityPartitionSpec(
+            srcTable.getMetaStoreTable().getPartitionKeys());
+      }
+
+      // Clear partition keys from the HMS table - Iceberg uses partition 
transforms
+      // instead. The partition columns are already included in the schema 
above
+      tbl.getPartitionKeys().clear();
+
+      // Use empty table properties since we're creating from a non-Iceberg 
source
+      Map<String, String> tableProperties = new HashMap<>();
+
+      createIcebergTable(tbl, wantMinimalResult, response, catalogTimeline,
+          params.if_not_exists, columns, partitionSpec,
+          new ArrayList<>(), // No primary keys for non-Iceberg source
+          tableProperties, params.getComment(), debugAction);
     } else if (srcTable instanceof KuduTable && KuduTable.isKuduTable(tbl)) {
       TCreateTableParams createTableParams =
           extractKuduCreateTableParams(params, tblName, (KuduTable) srcTable, 
tbl);
@@ -4674,6 +4717,32 @@ public class CatalogOpExecutor {
     }
   }
 
+  /**
+   * Creates a TIcebergPartitionSpec with IDENTITY transforms
+   * for the given partition keys. This is used when creating an
+   * Iceberg table from a non-Iceberg source table.
+   */
+  private TIcebergPartitionSpec createIdentityPartitionSpec(
+      List<FieldSchema> partitionKeys) {
+    TIcebergPartitionSpec partitionSpec = new TIcebergPartitionSpec();
+    List<TIcebergPartitionField> partitionFields = new ArrayList<>();
+
+    for (FieldSchema partitionKey : partitionKeys) {
+      TIcebergPartitionField field = new TIcebergPartitionField();
+      field.setOrig_field_name(partitionKey.getName());
+      field.setField_name(partitionKey.getName());
+
+      TIcebergPartitionTransform transform = new TIcebergPartitionTransform();
+      transform.setTransform_type(TIcebergPartitionTransformType.IDENTITY);
+      field.setTransform(transform);
+
+      partitionFields.add(field);
+    }
+
+    partitionSpec.setPartition_fields(partitionFields);
+    return partitionSpec;
+  }
+
   /**
    * Build TCreateTableParams by source
    */
diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
index 412e930a6..7369aff50 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
@@ -2905,6 +2905,25 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalysisError("create table test_like like 
functional_parquet.paimon_partitioned" +
             " STORED BY PAIMON",
         "CREATE TABLE LIKE is not supported for PAIMON tables.");
+
+    // Test creating Iceberg tables from non-Iceberg sources
+    // Non-partitioned table to Iceberg
+    AnalyzesOk("create table functional.ice_tbl like " +
+        "functional_parquet.complextypestbl stored by iceberg");
+    // Partitioned table to Iceberg
+    AnalyzesOk("create table functional.ice_part_tbl like " +
+        "functional.alltypes stored by iceberg");
+    // With IF NOT EXISTS
+    AnalyzesOk("create table if not exists functional.ice_tbl2 like " +
+        "functional_parquet.complextypestbl stored by iceberg");
+    // External Iceberg table from non-Iceberg source
+    AnalyzesOk("create external table functional.ice_external like " +
+        "functional.alltypes stored by iceberg");
+    // Kudu to Iceberg should fail (not supported)
+    AnalysisError("create table ice_from_kudu like functional_kudu.alltypes " +
+        "stored by iceberg",
+        "functional_kudu.alltypes cannot be cloned into a ICEBERG table: 
CREATE TABLE " +
+        "LIKE is not supported between Kudu tables and non-Kudu tables.");
   }
 
   @Test
diff --git 
a/testdata/workloads/functional-query/queries/QueryTest/iceberg-create-table-like-non-iceberg.test
 
b/testdata/workloads/functional-query/queries/QueryTest/iceberg-create-table-like-non-iceberg.test
new file mode 100644
index 000000000..97e2db5b1
--- /dev/null
+++ 
b/testdata/workloads/functional-query/queries/QueryTest/iceberg-create-table-like-non-iceberg.test
@@ -0,0 +1,349 @@
+====
+---- QUERY
+# Test creating Iceberg table from non-Iceberg table (non-partitioned)
+# Create source table with various types
+CREATE TABLE non_ice_src (
+  id INT COMMENT 'id column',
+  name STRING,
+  age BIGINT,
+  score DOUBLE,
+  active BOOLEAN,
+  created_date DATE,
+  created_ts TIMESTAMP,
+  price DECIMAL(10,2),
+  `data` BINARY
+) STORED AS PARQUET;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Create Iceberg table from non-Iceberg source
+CREATE TABLE ice_from_non_ice LIKE non_ice_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify the Iceberg table schema matches source
+DESCRIBE ice_from_non_ice;
+---- RESULTS
+'id','int','id column','true'
+'name','string','','true'
+'age','bigint','','true'
+'score','double','','true'
+'active','boolean','','true'
+'created_date','date','','true'
+'created_ts','timestamp','','true'
+'price','decimal(10,2)','','true'
+'data','binary','','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Verify it's an Iceberg table
+DESCRIBE FORMATTED ice_from_non_ice;
+---- RESULTS: VERIFY_IS_SUBSET
+'# col_name            ','data_type           ','comment             '
+'','NULL','NULL'
+'id','int','id column'
+'name','string','NULL'
+'age','bigint','NULL'
+'score','double','NULL'
+'active','boolean','NULL'
+'created_date','date','NULL'
+'created_ts','timestamp','NULL'
+'price','decimal(10,2)','NULL'
+'data','binary','NULL'
+'Location:           
','$NAMENODE/test-warehouse/$DATABASE.db/ice_from_non_ice','NULL'
+'','storage_handler     
','org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
+'SerDe Library:      ','org.apache.iceberg.mr.hive.HiveIcebergSerDe','NULL'
+'InputFormat:        
','org.apache.iceberg.mr.hive.HiveIcebergInputFormat','NULL'
+'OutputFormat:       
','org.apache.iceberg.mr.hive.HiveIcebergOutputFormat','NULL'
+---- TYPES
+string, string, string
+====
+---- QUERY
+# Insert data into the Iceberg table to verify it works
+INSERT INTO ice_from_non_ice VALUES (1, 'Alice', 30, 95.5, true, '2024-01-01', 
'2024-01-01 10:00:00', 100.50, cast('test' as binary));
+---- RUNTIME_PROFILE
+row_regex: .*NumModifiedRows: 1.*
+---- LABELS
+====
+---- QUERY
+# Query the data back
+SELECT id, name, age, score, active FROM ice_from_non_ice ORDER BY id;
+---- RESULTS
+1,'Alice',30,95.5,true
+---- TYPES
+INT,STRING,BIGINT,DOUBLE,BOOLEAN
+====
+---- QUERY
+# Test with partitioned source table
+CREATE TABLE part_src (
+  id INT,
+  name STRING,
+  value DOUBLE
+) PARTITIONED BY (year INT, month INT)
+STORED AS PARQUET;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Insert data to create partitions
+INSERT INTO part_src PARTITION(year=2024, month=1) VALUES (1, 'Q1', 100.0);
+---- RUNTIME_PROFILE
+row_regex: .*NumModifiedRows: 1.*
+---- LABELS
+====
+---- QUERY
+# Create Iceberg table from partitioned source
+CREATE TABLE part_ice LIKE part_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify schema - note that partition columns become regular columns
+DESCRIBE part_ice;
+---- RESULTS
+'id','int','','true'
+'name','string','','true'
+'value','double','','true'
+'year','int','','true'
+'month','int','','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Verify partition transform information (should have identity transforms for 
year and month)
+DESCRIBE FORMATTED part_ice;
+---- RESULTS: VERIFY_IS_SUBSET
+'# col_name            ','data_type           ','comment             '
+'','NULL','NULL'
+'id','int','NULL'
+'name','string','NULL'
+'value','double','NULL'
+'year','int','NULL'
+'month','int','NULL'
+'# Partition Transform Information','NULL','NULL'
+'# col_name            ','transform_type      ','NULL'
+'year','IDENTITY','NULL'
+'month','IDENTITY','NULL'
+'','storage_handler     
','org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
+---- TYPES
+string, string, string
+====
+---- QUERY
+# Insert data into partitioned Iceberg table
+INSERT INTO part_ice VALUES (2, 'Q2', 200.0, 2024, 2);
+---- RUNTIME_PROFILE
+row_regex: .*NumModifiedRows: 1.*
+---- LABELS
+====
+---- QUERY
+# Query partitioned data
+SELECT id, name, value, year, month FROM part_ice ORDER BY id;
+---- RESULTS
+2,'Q2',200,2024,2
+---- TYPES
+INT,STRING,DOUBLE,INT,INT
+====
+---- QUERY
+# Test with external table
+CREATE EXTERNAL TABLE ext_ice LIKE non_ice_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify external table properties
+DESCRIBE FORMATTED ext_ice;
+---- RESULTS: VERIFY_IS_SUBSET
+'# col_name            ','data_type           ','comment             '
+'','NULL','NULL'
+'id','int','id column'
+'Table Type:         ','EXTERNAL_TABLE      ','NULL'
+'','storage_handler     
','org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
+---- TYPES
+string, string, string
+====
+---- QUERY
+# Test with complex types from functional_parquet.complextypestbl
+CREATE TABLE complex_ice LIKE functional_parquet.complextypestbl STORED BY 
ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify complex types are preserved in the schema
+DESCRIBE complex_ice;
+---- RESULTS
+'id','bigint','','true'
+'int_array','array<int>','','true'
+'int_array_array','array<array<int>>','','true'
+'int_map','map<string,int>','','true'
+'int_map_array','array<map<string,int>>','','true'
+'nested_struct','struct<\n  a:int,\n  b:array<int>,\n  c:struct<\n    
d:array<array<struct<\n      e:int,\n      f:string\n    >>>\n  >,\n  
g:map<string,struct<\n    h:struct<\n      i:array<double>\n    >\n  
>>\n>','','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Verify Iceberg table properties
+DESCRIBE FORMATTED complex_ice;
+---- RESULTS: VERIFY_IS_SUBSET
+'# col_name            ','data_type           ','comment             '
+'','NULL','NULL'
+'id','bigint','NULL'
+'','storage_handler     
','org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
+---- TYPES
+string, string, string
+====
+---- HIVE_QUERY
+use $DATABASE;
+INSERT INTO complex_ice (id, int_array, int_map) VALUES
+  (1, array(1,2,3), map('k1', 10)),
+  (2, array(4,5,6), map('k2', 20)),
+  (3, array(7,8,9), map('k3', 30));
+====
+---- QUERY
+# Refresh metadata to see Hive changes
+REFRESH complex_ice;
+====
+---- QUERY
+# Verify Impala can query the actual complex type data inserted via Hive
+SELECT id, int_array, int_map FROM complex_ice ORDER BY id;
+---- RESULTS
+1,'[1,2,3]','{"k1":10}'
+2,'[4,5,6]','{"k2":20}'
+3,'[7,8,9]','{"k3":30}'
+---- TYPES
+BIGINT,STRING,STRING
+====
+---- QUERY
+# Test IF NOT EXISTS
+CREATE TABLE IF NOT EXISTS ice_from_non_ice LIKE non_ice_src STORED BY ICEBERG;
+---- RESULTS
+'Table already exists.'
+====
+---- QUERY
+# Negative test: Kudu to Iceberg should fail
+CREATE TABLE ice_from_kudu LIKE functional_kudu.alltypes STORED BY ICEBERG;
+---- CATCH
+functional_kudu.alltypes cannot be cloned into a ICEBERG table: CREATE TABLE 
LIKE is not supported between Kudu tables and non-Kudu tables.
+====
+---- QUERY
+# Test with table that has comments
+CREATE TABLE commented_src (
+  col1 INT COMMENT 'first column',
+  col2 STRING COMMENT 'second column'
+) COMMENT 'source table comment' STORED AS PARQUET;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Create Iceberg table and verify comments are preserved
+CREATE TABLE commented_ice LIKE commented_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify column comments are preserved
+DESCRIBE commented_ice;
+---- RESULTS
+'col1','int','first column','true'
+'col2','string','second column','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Test with ORC source format
+CREATE TABLE orc_src (
+  id INT,
+  name STRING,
+  score DOUBLE
+) STORED AS ORC;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Create Iceberg table from ORC source
+CREATE TABLE ice_from_orc LIKE orc_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify schema from ORC source
+DESCRIBE ice_from_orc;
+---- RESULTS
+'id','int','','true'
+'name','string','','true'
+'score','double','','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Test with Avro source format - create a simple Avro table
+CREATE TABLE avro_src (
+  id INT,
+  value BIGINT,
+  description STRING
+) STORED AS AVRO;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Create Iceberg table from Avro source
+CREATE TABLE ice_from_avro LIKE avro_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify schema from Avro source
+DESCRIBE ice_from_avro;
+---- RESULTS
+'id','int','from deserializer','true'
+'value','bigint','from deserializer','true'
+'description','string','from deserializer','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Test with Text source format - create a simple Text table
+CREATE TABLE text_src (
+  id INT,
+  name STRING,
+  age INT
+) STORED AS TEXTFILE;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Create Iceberg table from Text source
+CREATE TABLE ice_from_text LIKE text_src STORED BY ICEBERG;
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+# Verify schema from Text source
+DESCRIBE ice_from_text;
+---- RESULTS
+'id','int','','true'
+'name','string','','true'
+'age','int','','true'
+---- TYPES
+STRING,STRING,STRING,STRING
+====
+---- QUERY
+# Negative test: Creating non-Iceberg table from Iceberg source should fail
+CREATE TABLE parquet_from_ice LIKE ice_from_non_ice STORED AS PARQUET;
+---- CATCH
+CREATE TABLE LIKE is not supported for creating PARQUET table from Iceberg 
table
+====
+---- QUERY
+# Negative test: Creating ORC table from Iceberg source should fail
+CREATE TABLE orc_from_ice LIKE ice_from_non_ice STORED AS ORC;
+---- CATCH
+CREATE TABLE LIKE is not supported for creating ORC table from Iceberg table
+====
+---- QUERY
+# Negative test: Creating Text table from Iceberg source should fail
+CREATE TABLE text_from_ice LIKE ice_from_non_ice STORED AS TEXTFILE;
+---- CATCH
+CREATE TABLE LIKE is not supported for creating TEXT table from Iceberg table
+====
diff --git 
a/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test 
b/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
index 1f5d68760..18505ed8b 100644
--- 
a/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
+++ 
b/testdata/workloads/functional-query/queries/QueryTest/iceberg-negative.test
@@ -678,9 +678,10 @@ ALTER TABLE iceberg_alter_part SET PARTITION SPEC 
(HOUR(d));
 ImpalaRuntimeException: Failed to ALTER table 'iceberg_alter_part': Cannot 
bind: hour cannot transform date values from 'd'
 ====
 ---- QUERY
+# TINYINT, SMALLINT not supported in Iceberg
 CREATE TABLE clone_ice LIKE functional_parquet.alltypestiny STORED AS ICEBERG;
 ---- CATCH
-functional_parquet.alltypestiny cannot be cloned into an Iceberg table because 
it is not an Iceberg table.
+Type TINYINT is not supported in Iceberg
 ====
 ---- QUERY
 select * from functional_parquet.iceberg_alltypes_part for system_time as of 
'2000-01-01 01:02:03';
diff --git a/tests/query_test/test_iceberg.py b/tests/query_test/test_iceberg.py
index be72fac13..87e8bddc4 100644
--- a/tests/query_test/test_iceberg.py
+++ b/tests/query_test/test_iceberg.py
@@ -1287,6 +1287,12 @@ class TestIcebergTable(IcebergTestSuite):
     self.run_test_case('QueryTest/iceberg-create-table-like-table', vector,
                        use_db=unique_database)
 
+  @SkipIfFS.hive
+  def test_create_table_like_non_iceberg(self, vector, unique_database):
+    """Test creating Iceberg table from non-Iceberg source"""
+    self.run_test_case('QueryTest/iceberg-create-table-like-non-iceberg', 
vector,
+                       use_db=unique_database)
+
   def test_table_owner(self, vector, unique_database):
     self.run_table_owner_test(vector, unique_database, "some_random_user")
     self.run_table_owner_test(vector, unique_database, "another_random_user")

Reply via email to