srielau commented on code in PR #58317:
URL: https://github.com/apache/spark/pull/58317#discussion_r3887233560


##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/orc/OrcUtils.scala:
##########
@@ -437,6 +437,9 @@ object OrcUtils extends Logging {
       s"array<${getOrcSchemaString(a.elementType)}>"
     case m: MapType =>
       
s"map<${getOrcSchemaString(m.keyType)},${getOrcSchemaString(m.valueType)}>"
+    // Keep Spark responsible for CHAR/VARCHAR assignment and scan checks. 
Native ORC
+    // CHAR/VARCHAR would truncate or pad before Spark can validate the 
original value.
+    case _: CharType | _: VarcharType => StringType.catalogString

Review Comment:
   Addressed in 46e1980b947. `OrcDeserializer` now matches all `StringType` 
subtypes, and its existing recursive struct/array/map writers carry that 
support into nested positions. `getOrcSchemaString` requests physical ORC 
STRING only under `standardSemantics`; preserve-only mode retains native 
CHAR/VARCHAR enforcement. The regression matrix covers V1/V2 and vectorized/row 
readers, and verifies preserve-only `VARCHAR(4)` still yields `abcd` for 
`abcdef`. The targeted SPARK-58814 test passes.



##########
sql/core/src/test/scala/org/apache/spark/sql/CharVarcharTestSuite.scala:
##########
@@ -1697,33 +1697,94 @@ class BasicCharVarcharTestSuite extends 
SharedSparkSession {
         sql("DROP TEMPORARY FUNCTION IF EXISTS std_char_param")
         sql("DROP TEMPORARY FUNCTION IF EXISTS std_varchar_param")
       }
+    }
+  }
 
-      // ORC catalog tables stamp the catalyst type so typeof survives 
write/read.
-      withTable("std_orc") {
-        sql("CREATE TABLE std_orc (c CHAR(5), v VARCHAR(5)) USING orc")
-        sql("INSERT INTO std_orc VALUES ('ab', 'cd')")
-        assert(spark.table("std_orc").schema.map(_.dataType) ===
-          Seq(CharType(5), VarcharType(5)))
-        checkAnswer(
-          sql("SELECT concat('<', c, '>'), concat('<', v, '>') FROM std_orc"),
-          Row("<ab   >", "<cd>"))
+  test("SPARK-58814: major formats preserve CHAR/VARCHAR schemas and values") {
+    withSQLConf(SQLConf.CHAR_VARCHAR_STANDARD_SEMANTICS.key -> "true") {
+      Seq("parquet", "orc").foreach { format =>
+        Seq("v1" -> format, "v2" -> "").foreach { case (sourceVersion, 
useV1List) =>
+          withSQLConf(SQLConf.USE_V1_SOURCE_LIST.key -> useV1List) {
+            withTempPath { dir =>
+              val path = dir.getCanonicalPath
+              val input = spark.range(1).selectExpr(
+                "cast('ab' AS CHAR(4)) AS c",
+                "cast('xy' AS VARCHAR(3)) AS v",
+                "named_struct('c', cast('z' AS CHAR(2))) AS s",
+                "array(cast('q' AS VARCHAR(2))) AS a",
+                "map(cast('k' AS CHAR(2)), cast('v' AS VARCHAR(2))) AS m")
+              input.write.mode("overwrite").format(format).save(path)
+
+              val readBack = spark.read.format(format).load(path)
+              assert(DataType.equalsIgnoreNullability(readBack.schema, 
input.schema),
+                s"$format $sourceVersion lost CHAR/VARCHAR schema")
+              checkAnswer(
+                readBack.selectExpr("concat('<', c, '>')", "v", "concat('<', 
s.c, '>')"),

Review Comment:
   Addressed in 46e1980b947. The inferred round-trip assertion now materializes 
both `a` and `m`. Added explicit-schema overflow cases for nested struct 
(`s.c`), array element (`a`), map key (`mk`), and map value (`mv`), each 
checked for `EXCEED_LIMIT_LENGTH` across ORC V1/V2 and vectorized/row readers. 
The targeted SPARK-58814 test passes.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to