@@ -71,74 +71,32 @@ case class GetItem(child: Expression, ordinal: Expression) extends Expression {
71
71
}
72
72
73
73
/**
74
- * Returns the value of fields in the `child`.
75
- * The type of `child` can be struct, or array of struct,
76
- * or array of array of struct, or array of array ... of struct.
74
+ * Returns the value of fields in the Struct `child`.
77
75
*/
78
76
case class GetField (child : Expression , fieldName : String ) extends UnaryExpression {
79
77
type EvaluatedType = Any
80
78
81
- lazy val dataType = {
82
- structType
83
- buildDataType(field.dataType)
84
- }
85
-
79
+ def dataType = field.dataType
86
80
override def nullable = child.nullable || field.nullable
87
81
override def foldable = child.foldable
88
82
89
- private var _buildDataType = identity[DataType ] _
90
- private lazy val buildDataType = {
91
- structType
92
- _buildDataType
93
- }
94
-
95
- private var _nestedArrayCount = 0
96
- private lazy val nestedArrayCount = {
97
- structType
98
- _nestedArrayCount
99
- }
100
-
101
- private def getStructType (t : DataType ): StructType = t match {
102
- case ArrayType (elementType, containsNull) =>
103
- _buildDataType = {(t : DataType ) => ArrayType (t, containsNull)} andThen _buildDataType
104
- _nestedArrayCount += 1
105
- getStructType(elementType)
83
+ protected def structType = child.dataType match {
106
84
case s : StructType => s
107
85
case otherType => sys.error(s " GetField is not valid on fields of type $otherType" )
108
86
}
109
87
110
- protected lazy val structType : StructType = {
111
- child match {
112
- case n : GetField =>
113
- this ._buildDataType = n._buildDataType
114
- this ._nestedArrayCount = n._nestedArrayCount
115
- getStructType(n.field.dataType)
116
- case _ => getStructType(child.dataType)
117
- }
118
- }
119
-
120
88
lazy val field =
121
89
structType.fields
122
90
.find(_.name == fieldName)
123
91
.getOrElse(sys.error(s " No such field $fieldName in ${child.dataType}" ))
124
92
125
93
lazy val ordinal = structType.fields.indexOf(field)
126
94
127
- override lazy val resolved = childrenResolved
95
+ override lazy val resolved = childrenResolved && child.dataType. isInstanceOf [ StructType ]
128
96
129
97
override def eval (input : Row ): Any = {
130
- val baseValue = child.eval(input)
131
- evaluateValue(baseValue, nestedArrayCount)
132
- }
133
-
134
- private def evaluateValue (v : Any , count : Int ): Any = {
135
- if (v == null ) {
136
- null
137
- } else if (count > 0 ) {
138
- v.asInstanceOf [Seq [_]].map(r => evaluateValue(r, count - 1 ))
139
- } else {
140
- v.asInstanceOf [Row ](ordinal)
141
- }
98
+ val baseValue = child.eval(input).asInstanceOf [Row ]
99
+ if (baseValue == null ) null else baseValue(ordinal)
142
100
}
143
101
144
102
override def toString = s " $child. $fieldName"
0 commit comments