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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5d3752ce88 [spark] Expose external table type to Spark (#8306)
5d3752ce88 is described below

commit 5d3752ce88c5166f5ab4679d75f1c76eaa24af94
Author: huangxiaoping <[email protected]>
AuthorDate: Wed Jun 24 14:48:45 2026 +0800

    [spark] Expose external table type to Spark (#8306)
    
    Fix an inconsistency where Spark did not recognize Paimon external
    tables as external in Spark-facing metadata.
    Before this change, a Paimon table could already be stored as
    `table.type=EXTERNAL`, but Spark-side logic relies on the reserved
    property `TableCatalog.PROP_EXTERNAL` to classify a table as external.
    Because that property was not exposed from `PaimonSparkTableBase`, Spark
    metadata output could report the wrong table type, such as showing a
    Paimon external table as managed in `DESC FORMATTED.`
    This change fixes that by exposing `PROP_EXTERNAL` from
    `PaimonSparkTableBase` when the underlying Paimon table is external.
    That keeps Spark behavior consistent with the existing property-based
    contract already used by Spark-side commands like `SHOW TABLE EXTENDED.`
---
 .../apache/paimon/spark/PaimonSparkTableBase.scala |  9 +++++++-
 .../paimon/spark/SparkCatalogWithHiveTest.java     | 24 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git 
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/PaimonSparkTableBase.scala
 
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/PaimonSparkTableBase.scala
index bd69174be7..6be314cee8 100644
--- 
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/PaimonSparkTableBase.scala
+++ 
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/PaimonSparkTableBase.scala
@@ -20,13 +20,14 @@ package org.apache.paimon.spark
 
 import org.apache.paimon.CoreOptions
 import org.apache.paimon.CoreOptions.BucketFunctionType
+import org.apache.paimon.options.CatalogOptions.TABLE_TYPE
 import org.apache.paimon.options.Options
 import org.apache.paimon.spark.catalog.functions.BucketFunction
 import org.apache.paimon.spark.read.PaimonSplitScanBuilder
 import org.apache.paimon.spark.schema.PaimonMetadataColumn
 import org.apache.paimon.spark.util.OptionUtils
 import org.apache.paimon.spark.write.{PaimonV2WriteBuilder, PaimonWriteBuilder}
-import org.apache.paimon.table.{Table, _}
+import org.apache.paimon.table.{CatalogTableType, Table, _}
 import org.apache.paimon.table.BucketMode.{BUCKET_UNAWARE, HASH_FIXED, 
POSTPONE_MODE}
 
 import org.apache.spark.sql.connector.catalog._
@@ -84,6 +85,12 @@ abstract class PaimonSparkTableBase(val table: Table)
         if (properties.containsKey(CoreOptions.PATH.key())) {
           properties.put(TableCatalog.PROP_LOCATION, 
properties.get(CoreOptions.PATH.key()))
         }
+        if (
+          CatalogTableType.EXTERNAL.toString.equalsIgnoreCase(
+            dataTable.options().get(TABLE_TYPE.key()))
+        ) {
+          properties.put(TableCatalog.PROP_EXTERNAL, "true")
+        }
         properties
       case _ => Collections.emptyMap()
     }
diff --git 
a/paimon-spark/paimon-spark-ut/src/test/java/org/apache/paimon/spark/SparkCatalogWithHiveTest.java
 
b/paimon-spark/paimon-spark-ut/src/test/java/org/apache/paimon/spark/SparkCatalogWithHiveTest.java
index 583522822b..f71e5df3c0 100644
--- 
a/paimon-spark/paimon-spark-ut/src/test/java/org/apache/paimon/spark/SparkCatalogWithHiveTest.java
+++ 
b/paimon-spark/paimon-spark-ut/src/test/java/org/apache/paimon/spark/SparkCatalogWithHiveTest.java
@@ -156,6 +156,30 @@ public class SparkCatalogWithHiveTest {
         }
     }
 
+    @Test
+    public void testDescribeExternalAndManagedTableType() throws IOException {
+        try (SparkSession spark = createSessionBuilder().getOrCreate()) {
+            spark.sql("CREATE DATABASE IF NOT EXISTS type_test_db");
+            spark.sql("USE spark_catalog.type_test_db");
+
+            spark.sql("CREATE EXTERNAL TABLE external_type_table (a INT, bb 
INT, c STRING)");
+            assertThat(
+                            spark.sql("DESC FORMATTED external_type_table")
+                                    .filter("col_name = 'Type'")
+                                    .head()
+                                    .getString(1))
+                    .isEqualTo("EXTERNAL");
+
+            spark.sql("CREATE TABLE managed_type_table (a INT)");
+            assertThat(
+                            spark.sql("DESC FORMATTED managed_type_table")
+                                    .filter("col_name = 'Type'")
+                                    .head()
+                                    .getString(1))
+                    .isEqualTo("MANAGED");
+        }
+    }
+
     private SparkSession.Builder createSessionBuilder() {
         Path warehousePath = new Path("file:" + tempDir.toString());
         return SparkSession.builder()

Reply via email to