You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by gu...@apache.org on 2019/07/25 11:55:32 UTC
[spark] branch master updated: [SPARK-28497][SQL] Disallow
upcasting complex data types to string type
This is an automated email from the ASF dual-hosted git repository.
gurwls223 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new b367b32 [SPARK-28497][SQL] Disallow upcasting complex data types to string type
b367b32 is described below
commit b367b323d2d69c6fcb8d4c83d87813e3924b7dc8
Author: Gengliang Wang <ge...@databricks.com>
AuthorDate: Thu Jul 25 20:55:01 2019 +0900
[SPARK-28497][SQL] Disallow upcasting complex data types to string type
## What changes were proposed in this pull request?
In the current implementation. complex types like Array/Map/StructType are allowed to upcast as StringType.
This is not safe casting. We should disallow it.
## How was this patch tested?
Update the existing test case
Closes #25242 from gengliangwang/fixUpCastStringType.
Authored-by: Gengliang Wang <ge...@databricks.com>
Signed-off-by: HyukjinKwon <gu...@apache.org>
---
.../org/apache/spark/sql/catalyst/expressions/Cast.scala | 3 ++-
.../sql/catalyst/encoders/EncoderResolutionSuite.scala | 15 +++++++++++++++
.../apache/spark/sql/catalyst/expressions/CastSuite.scala | 5 +++++
.../scala/org/apache/spark/sql/UserDefinedTypeSuite.scala | 5 +++++
4 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
index 9691288..85bad74 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
@@ -131,7 +131,8 @@ object Cast {
case (from: DecimalType, to: NumericType) if from.isTighterThan(to) => true
case (f, t) if legalNumericPrecedence(f, t) => true
case (DateType, TimestampType) => true
- case (_, StringType) => true
+ case (_: AtomicType, StringType) => true
+ case (_: CalendarIntervalType, StringType) => true
// Spark supports casting between long and timestamp, please see `longToTimestamp` and
// `timestampToLong` for details.
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala
index da1b695..53cb8bc 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala
@@ -196,6 +196,21 @@ class EncoderResolutionSuite extends PlanTest {
encoder.resolveAndBind(attrs)
}
+ test("SPARK-28497: complex type is not compatible with string encoder schema") {
+ val encoder = ExpressionEncoder[String]
+
+ Seq('a.struct('x.long), 'a.array(StringType), 'a.map(StringType, StringType)).foreach { attr =>
+ val attrs = Seq(attr)
+ assert(intercept[AnalysisException](encoder.resolveAndBind(attrs)).message ==
+ s"""
+ |Cannot up cast `a` from ${attr.dataType.catalogString} to string.
+ |The type path of the target object is:
+ |- root class: "java.lang.String"
+ |You can either add an explicit cast to the input data or choose a higher precision type
+ """.stripMargin.trim + " of the field in the target object")
+ }
+ }
+
test("throw exception if real type is not compatible with encoder schema") {
val msg1 = intercept[AnalysisException] {
ExpressionEncoder[StringIntClass].resolveAndBind(Seq('a.string, 'b.long))
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
index 4d667fd..44825c7 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
@@ -1002,6 +1002,11 @@ class CastSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}
+ numericTypes.foreach { dt =>
+ makeComplexTypes(dt, true).foreach { complexType =>
+ assert(!Cast.canUpCast(complexType, StringType))
+ }
+ }
}
test("SPARK-27671: cast from nested null type in struct") {
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/UserDefinedTypeSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/UserDefinedTypeSuite.scala
index 6628d36..49f0000 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/UserDefinedTypeSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/UserDefinedTypeSuite.scala
@@ -272,4 +272,9 @@ class UserDefinedTypeSuite extends QueryTest with SharedSQLContext with ParquetT
val ret = Cast(Literal(data, udt), StringType, None)
checkEvaluation(ret, "(1.0, 3.0, 5.0, 7.0, 9.0)")
}
+
+ test("SPARK-28497 Can't up cast UserDefinedType to string") {
+ val udt = new TestUDT.MyDenseVectorUDT()
+ assert(!Cast.canUpCast(udt, StringType))
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org