You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@spark.apache.org by "Cheng Lian (JIRA)" <ji...@apache.org> on 2016/05/26 05:53:12 UTC
[jira] [Created] (SPARK-15547) Encoder validation is too strict for
inner nested structs
Cheng Lian created SPARK-15547:
----------------------------------
Summary: Encoder validation is too strict for inner nested structs
Key: SPARK-15547
URL: https://issues.apache.org/jira/browse/SPARK-15547
Project: Spark
Issue Type: Bug
Components: SQL
Affects Versions: 1.6.1, 2.0.0
Reporter: Cheng Lian
Assignee: Cheng Lian
The following Spark shell snippet reproduces this issue:
{code}
case class ClassData(a: String, b: Long)
case class NestedStruct(f: ClassData)
val data =
s"""{"f": {"b": 1, "a": "foo", "c": "extra"}}
|{"f": {"b": 2, "a": "bar", "c": "extra"}}
|""".stripMargin.trim.split("\n")
val df = spark.read.json(sc.parallelize(data))
val ds = df.as[NestedStruct]
{code}
Exception thrown:
{noformat}
org.apache.spark.sql.AnalysisException: Try to map struct<a:string,b:bigint,c:string> to Tuple2, but failed as the number of fields does not line up.
- Input schema: struct<f:struct<a:string,b:bigint,c:string>>
- Target schema: struct<f:struct<a:string,b:bigint>>;
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder.org$apache$spark$sql$catalyst$encoders$ExpressionEncoder$$fail$1(ExpressionEncoder.scala:267)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$$anonfun$validate$3.apply(ExpressionEncoder.scala:311)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$$anonfun$validate$3.apply(ExpressionEncoder.scala:307)
at scala.collection.mutable.HashMap$$anonfun$foreach$1.apply(HashMap.scala:99)
at scala.collection.mutable.HashMap$$anonfun$foreach$1.apply(HashMap.scala:99)
at scala.collection.mutable.HashTable$class.foreachEntry(HashTable.scala:230)
at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:40)
at scala.collection.mutable.HashMap.foreach(HashMap.scala:99)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder.validate(ExpressionEncoder.scala:307)
at org.apache.spark.sql.Dataset.<init>(Dataset.scala:201)
at org.apache.spark.sql.Dataset.<init>(Dataset.scala:168)
at org.apache.spark.sql.Dataset$.apply(Dataset.scala:57)
at org.apache.spark.sql.Dataset.as(Dataset.scala:360)
... 39 elided
{noformat}
We can workaround this exception by removing inner nested field {{c}}:
{code}
val data =
s"""{"f": {"b": 1, "a": "foo"}}
|{"f": {"b": 2, "a": "bar"}}
|""".stripMargin.trim.split("\n")
{code}
Dataset is just a "view" of its underlying logical plan. The encoder and logical plan of the Dataset may have different field number and/or field order. This is OK as long as all fields referred by the encoder exist in the logical plan. This is because encoder de/serializer expressions are resolved by name rather than ordinal.
However, as illustrated above, length of an inner nested struct must align with field number of the corresponding case class/Java bean.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@spark.apache.org
For additional commands, e-mail: issues-help@spark.apache.org