This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 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 409dd85e51 [spark] Fix view query failure with VARCHAR/CHAR column
types (#7585)
409dd85e51 is described below
commit 409dd85e51065496301aa3db55babf72de250368
Author: Zouxxyy <[email protected]>
AuthorDate: Thu Apr 2 21:52:18 2026 +0800
[spark] Fix view query failure with VARCHAR/CHAR column types (#7585)
Fix querying Paimon View fails with "Cannot up cast from STRING to
VARCHAR(n)" when the underlying table has VARCHAR or CHAR columns.
Spark replaces CharType/VarcharType with StringType during V2 table
resolution, but the view schema still preserves the original types. This
causes UpCast(StringType → VarcharType(n)) to fail. The fix uses
CharVarcharUtils.replaceCharVarcharWithStringInSchema to normalize the
view schema before applying UpCast.
---
.../catalyst/analysis/PaimonViewResolver.scala | 9 +++-
.../paimon/spark/sql/PaimonViewTestBase.scala | 48 ++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/catalyst/analysis/PaimonViewResolver.scala
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/catalyst/analysis/PaimonViewResolver.scala
index b45463e916..95b8ab6e18 100644
---
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/catalyst/analysis/PaimonViewResolver.scala
+++
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/catalyst/analysis/PaimonViewResolver.scala
@@ -30,6 +30,7 @@ import org.apache.spark.sql.catalyst.parser.ParseException
import org.apache.spark.sql.catalyst.parser.extensions.{CurrentOrigin, Origin}
import org.apache.spark.sql.catalyst.plans.logical.{LeafNode, LogicalPlan,
Project, SubqueryAlias}
import org.apache.spark.sql.catalyst.rules.Rule
+import org.apache.spark.sql.catalyst.util.CharVarcharUtils
import org.apache.spark.sql.connector.catalog.{Identifier, PaimonLookupCatalog}
case class PaimonViewResolver(spark: SparkSession)
@@ -66,7 +67,13 @@ case class PaimonViewResolver(spark: SparkSession)
val earlyRules = Seq(CTESubstitution, SubstituteUnresolvedOrdinals)
val rewritten = earlyRules.foldLeft(parsedPlan)((plan, rule) =>
rule.apply(plan))
- val aliases =
SparkTypeUtils.fromPaimonRowType(view.rowType()).fields.zipWithIndex.map {
+ // Spark internally replaces CharType/VarcharType with StringType during
V2 table resolution,
+ // so the view's schema must also use StringType to avoid UpCast failures
+ // (e.g., "Cannot up cast from STRING to VARCHAR(50)").
+ val viewSchema = CharVarcharUtils.replaceCharVarcharWithStringInSchema(
+ SparkTypeUtils.fromPaimonRowType(view.rowType()))
+
+ val aliases = viewSchema.fields.zipWithIndex.map {
case (expected, pos) =>
val attr = GetColumnByOrdinal(pos, expected.dataType)
Alias(UpCast(attr, expected.dataType), expected.name)(explicitMetadata
=
diff --git
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonViewTestBase.scala
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonViewTestBase.scala
index 7c503d98a5..a0c29bfcbc 100644
---
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonViewTestBase.scala
+++
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonViewTestBase.scala
@@ -242,4 +242,52 @@ abstract class PaimonViewTestBase extends
PaimonHiveTestBase {
}
}
}
+
+ test("Paimon View: create view on table with VARCHAR columns") {
+ Seq(sparkCatalogName, paimonHiveCatalogName).foreach {
+ catalogName =>
+ sql(s"USE $catalogName")
+ withDatabase("test_db") {
+ sql("CREATE DATABASE test_db")
+ sql("USE test_db")
+ withTable("t") {
+ withView("v1") {
+ sql("CREATE TABLE t (id INT, name VARCHAR(50), country STRING)
USING paimon")
+ sql("INSERT INTO t VALUES (1, 'alice', 'beijing'), (2, 'bob',
'shanghai')")
+ sql("CREATE VIEW v1 AS SELECT * FROM t")
+ checkAnswer(
+ sql("SELECT * FROM v1"),
+ Seq(Row(1, "alice", "beijing"), Row(2, "bob", "shanghai")))
+ }
+ }
+ }
+ }
+ }
+
+ test("Paimon View: create view on table with nested VARCHAR and CHAR
columns") {
+ Seq(sparkCatalogName, paimonHiveCatalogName).foreach {
+ catalogName =>
+ sql(s"USE $catalogName")
+ withDatabase("test_db") {
+ sql("CREATE DATABASE test_db")
+ sql("USE test_db")
+ withTable("t") {
+ withView("v1") {
+ sql("""CREATE TABLE t (
+ | id INT,
+ | tags ARRAY<VARCHAR(100)>,
+ | props MAP<STRING, VARCHAR(200)>
+ |) USING paimon""".stripMargin)
+ sql("""INSERT INTO t VALUES
+ | (1, ARRAY('a', 'b'), MAP('k1', 'v1')),
+ | (2, ARRAY('c'), MAP('k2', 'v2'))""".stripMargin)
+ sql("CREATE VIEW v1 AS SELECT * FROM t")
+ checkAnswer(
+ sql("SELECT * FROM v1"),
+ Seq(Row(1, Seq("a", "b"), Map("k1" -> "v1")), Row(2, Seq("c"),
Map("k2" -> "v2"))))
+ }
+ }
+ }
+ }
+ }
}