17
17
18
18
package org .apache .spark .sql .catalyst .expressions
19
19
20
+ import java .lang .{Boolean => JavaBoolean }
21
+ import java .lang .{Byte => JavaByte }
22
+ import java .lang .{Double => JavaDouble }
23
+ import java .lang .{Float => JavaFloat }
24
+ import java .lang .{Integer => JavaInteger }
25
+ import java .lang .{Long => JavaLong }
26
+ import java .lang .{Short => JavaShort }
27
+ import java .math .{BigDecimal => JavaBigDecimal }
20
28
import java .nio .charset .StandardCharsets
21
29
import java .sql .{Date , Timestamp }
22
30
import java .util
23
31
import java .util .Objects
24
32
import javax .xml .bind .DatatypeConverter
25
33
34
+ import scala .math .{BigDecimal , BigInt }
35
+
26
36
import org .json4s .JsonAST ._
27
37
38
+ import org .apache .spark .sql .AnalysisException
28
39
import org .apache .spark .sql .catalyst .{CatalystTypeConverters , InternalRow }
29
40
import org .apache .spark .sql .catalyst .expressions .codegen ._
30
41
import org .apache .spark .sql .catalyst .util .DateTimeUtils
@@ -46,19 +57,63 @@ object Literal {
46
57
case s : String => Literal (UTF8String .fromString(s), StringType )
47
58
case b : Boolean => Literal (b, BooleanType )
48
59
case d : BigDecimal => Literal (Decimal (d), DecimalType (Math .max(d.precision, d.scale), d.scale))
49
- case d : java.math. BigDecimal =>
60
+ case d : JavaBigDecimal =>
50
61
Literal (Decimal (d), DecimalType (Math .max(d.precision, d.scale), d.scale()))
51
62
case d : Decimal => Literal (d, DecimalType (Math .max(d.precision, d.scale), d.scale))
52
63
case t : Timestamp => Literal (DateTimeUtils .fromJavaTimestamp(t), TimestampType )
53
64
case d : Date => Literal (DateTimeUtils .fromJavaDate(d), DateType )
54
65
case a : Array [Byte ] => Literal (a, BinaryType )
66
+ case a : Array [_] =>
67
+ val elementType = componentTypeToDataType(a.getClass.getComponentType())
68
+ val dataType = ArrayType (elementType)
69
+ val convert = CatalystTypeConverters .createToCatalystConverter(dataType)
70
+ Literal (convert(a), dataType)
55
71
case i : CalendarInterval => Literal (i, CalendarIntervalType )
56
72
case null => Literal (null , NullType )
57
73
case v : Literal => v
58
74
case _ =>
59
75
throw new RuntimeException (" Unsupported literal type " + v.getClass + " " + v)
60
76
}
61
77
78
+ /**
79
+ * Returns the Spark SQL DataType for a given class object. Since this type needs to be resolved
80
+ * in runtime, we use match-case idioms for class objects here. However, there are similar
81
+ * functions in other files (e.g., HiveInspectors), so these functions need to merged into one.
82
+ */
83
+ private [this ] def componentTypeToDataType (clz : Class [_]): DataType = clz match {
84
+ // primitive types
85
+ case JavaShort .TYPE => ShortType
86
+ case JavaInteger .TYPE => IntegerType
87
+ case JavaLong .TYPE => LongType
88
+ case JavaDouble .TYPE => DoubleType
89
+ case JavaByte .TYPE => ByteType
90
+ case JavaFloat .TYPE => FloatType
91
+ case JavaBoolean .TYPE => BooleanType
92
+
93
+ // java classes
94
+ case _ if clz == classOf [Date ] => DateType
95
+ case _ if clz == classOf [Timestamp ] => TimestampType
96
+ case _ if clz == classOf [JavaBigDecimal ] => DecimalType .SYSTEM_DEFAULT
97
+ case _ if clz == classOf [Array [Byte ]] => BinaryType
98
+ case _ if clz == classOf [JavaShort ] => ShortType
99
+ case _ if clz == classOf [JavaInteger ] => IntegerType
100
+ case _ if clz == classOf [JavaLong ] => LongType
101
+ case _ if clz == classOf [JavaDouble ] => DoubleType
102
+ case _ if clz == classOf [JavaByte ] => ByteType
103
+ case _ if clz == classOf [JavaFloat ] => FloatType
104
+ case _ if clz == classOf [JavaBoolean ] => BooleanType
105
+
106
+ // other scala classes
107
+ case _ if clz == classOf [String ] => StringType
108
+ case _ if clz == classOf [BigInt ] => DecimalType .SYSTEM_DEFAULT
109
+ case _ if clz == classOf [BigDecimal ] => DecimalType .SYSTEM_DEFAULT
110
+ case _ if clz == classOf [CalendarInterval ] => CalendarIntervalType
111
+
112
+ case _ if clz.isArray => ArrayType (componentTypeToDataType(clz.getComponentType))
113
+
114
+ case _ => throw new AnalysisException (s " Unsupported component type $clz in arrays " )
115
+ }
116
+
62
117
/**
63
118
* Constructs a [[Literal ]] of [[ObjectType ]], for example when you need to pass an object
64
119
* into code generation.
0 commit comments