@@ -52,6 +52,13 @@ object CatalystTypeConverters {
5252 }
5353 }
5454
55+ private def isWholePrimitive (dt : DataType ): Boolean = dt match {
56+ case dt if isPrimitive(dt) => true
57+ case ArrayType (elementType, _) => isWholePrimitive(elementType)
58+ case MapType (keyType, valueType, _) => isWholePrimitive(keyType) && isWholePrimitive(valueType)
59+ case _ => false
60+ }
61+
5562 private def getConverterForType (dataType : DataType ): CatalystTypeConverter [Any , Any , Any ] = {
5663 val converter = dataType match {
5764 case udt : UserDefinedType [_] => UDTConverter (udt)
@@ -148,6 +155,8 @@ object CatalystTypeConverters {
148155
149156 private [this ] val elementConverter = getConverterForType(elementType)
150157
158+ private [this ] val isNoChange = isWholePrimitive(elementType)
159+
151160 override def toCatalystImpl (scalaValue : Any ): Seq [Any ] = {
152161 scalaValue match {
153162 case a : Array [_] => a.toSeq.map(elementConverter.toCatalyst)
@@ -166,8 +175,10 @@ object CatalystTypeConverters {
166175 override def toScala (catalystValue : Seq [Any ]): Seq [Any ] = {
167176 if (catalystValue == null ) {
168177 null
178+ } else if (isNoChange) {
179+ catalystValue
169180 } else {
170- catalystValue.asInstanceOf [ Seq [_]]. map(elementConverter.toScala)
181+ catalystValue.map(elementConverter.toScala)
171182 }
172183 }
173184
@@ -183,6 +194,8 @@ object CatalystTypeConverters {
183194 private [this ] val keyConverter = getConverterForType(keyType)
184195 private [this ] val valueConverter = getConverterForType(valueType)
185196
197+ private [this ] val isNoChange = isWholePrimitive(keyType) && isWholePrimitive(valueType)
198+
186199 override def toCatalystImpl (scalaValue : Any ): Map [Any , Any ] = scalaValue match {
187200 case m : Map [_, _] =>
188201 m.map { case (k, v) =>
@@ -203,6 +216,8 @@ object CatalystTypeConverters {
203216 override def toScala (catalystValue : Map [Any , Any ]): Map [Any , Any ] = {
204217 if (catalystValue == null ) {
205218 null
219+ } else if (isNoChange) {
220+ catalystValue
206221 } else {
207222 catalystValue.map { case (k, v) =>
208223 keyConverter.toScala(k) -> valueConverter.toScala(v)
@@ -258,24 +273,22 @@ object CatalystTypeConverters {
258273 toScala(row(column).asInstanceOf [InternalRow ])
259274 }
260275
261- private object StringConverter extends CatalystTypeConverter [Any , String , Any ] {
276+ private object StringConverter extends CatalystTypeConverter [Any , String , UTF8String ] {
262277 override def toCatalystImpl (scalaValue : Any ): UTF8String = scalaValue match {
263278 case str : String => UTF8String .fromString(str)
264279 case utf8 : UTF8String => utf8
265280 }
266- override def toScala (catalystValue : Any ): String = catalystValue match {
267- case null => null
268- case str : String => str
269- case utf8 : UTF8String => utf8.toString()
270- }
281+ override def toScala (catalystValue : UTF8String ): String =
282+ if (catalystValue == null ) null else catalystValue.toString
271283 override def toScalaImpl (row : InternalRow , column : Int ): String = row(column).toString
272284 }
273285
274286 private object DateConverter extends CatalystTypeConverter [Date , Date , Any ] {
275287 override def toCatalystImpl (scalaValue : Date ): Int = DateTimeUtils .fromJavaDate(scalaValue)
276288 override def toScala (catalystValue : Any ): Date =
277289 if (catalystValue == null ) null else DateTimeUtils .toJavaDate(catalystValue.asInstanceOf [Int ])
278- override def toScalaImpl (row : InternalRow , column : Int ): Date = toScala(row.getInt(column))
290+ override def toScalaImpl (row : InternalRow , column : Int ): Date =
291+ DateTimeUtils .toJavaDate(row.getInt(column))
279292 }
280293
281294 private object TimestampConverter extends CatalystTypeConverter [Timestamp , Timestamp , Any ] {
@@ -285,7 +298,7 @@ object CatalystTypeConverters {
285298 if (catalystValue == null ) null
286299 else DateTimeUtils .toJavaTimestamp(catalystValue.asInstanceOf [Long ])
287300 override def toScalaImpl (row : InternalRow , column : Int ): Timestamp =
288- toScala (row.getLong(column))
301+ DateTimeUtils .toJavaTimestamp (row.getLong(column))
289302 }
290303
291304 private object BigDecimalConverter extends CatalystTypeConverter [Any , JavaBigDecimal , Decimal ] {
@@ -296,10 +309,7 @@ object CatalystTypeConverters {
296309 }
297310 override def toScala (catalystValue : Decimal ): JavaBigDecimal = catalystValue.toJavaBigDecimal
298311 override def toScalaImpl (row : InternalRow , column : Int ): JavaBigDecimal =
299- row.get(column) match {
300- case d : JavaBigDecimal => d
301- case d : Decimal => d.toJavaBigDecimal
302- }
312+ row.get(column).asInstanceOf [Decimal ].toJavaBigDecimal
303313 }
304314
305315 private abstract class PrimitiveConverter [T ] extends CatalystTypeConverter [T , Any , Any ] {
@@ -362,6 +372,19 @@ object CatalystTypeConverters {
362372 }
363373 }
364374
375+ /**
376+ * Creates a converter function that will convert Catalyst types to Scala type.
377+ * Typical use case would be converting a collection of rows that have the same schema. You will
378+ * call this function once to get a converter, and apply it to every row.
379+ */
380+ private [sql] def createToScalaConverter (dataType : DataType ): Any => Any = {
381+ if (isPrimitive(dataType)) {
382+ identity
383+ } else {
384+ getConverterForType(dataType).toScala
385+ }
386+ }
387+
365388 /**
366389 * Converts Scala objects to Catalyst rows / types.
367390 *
@@ -389,15 +412,6 @@ object CatalystTypeConverters {
389412 * produced by createToScalaConverter.
390413 */
391414 def convertToScala (catalystValue : Any , dataType : DataType ): Any = {
392- getConverterForType(dataType).toScala(catalystValue)
393- }
394-
395- /**
396- * Creates a converter function that will convert Catalyst types to Scala type.
397- * Typical use case would be converting a collection of rows that have the same schema. You will
398- * call this function once to get a converter, and apply it to every row.
399- */
400- private [sql] def createToScalaConverter (dataType : DataType ): Any => Any = {
401- getConverterForType(dataType).toScala
415+ createToScalaConverter(dataType)(catalystValue)
402416 }
403417}
0 commit comments