@@ -143,20 +143,19 @@ object DropUnitValues {
143143 }
144144}
145145
146- class RecordEncoder [F , G <: HList , H <: HList ](
146+ abstract class RecordEncoder [F , G <: HList , H <: HList ](
147147 implicit
148- i0 : LabelledGeneric .Aux [F , G ],
149- i1 : DropUnitValues .Aux [G , H ],
150- i2 : IsHCons [H ],
151- fields : Lazy [RecordEncoderFields [H ]],
152- newInstanceExprs : Lazy [NewInstanceExprs [G ]],
148+ stage1 : RecordEncoderStage1 [G , H ],
153149 classTag : ClassTag [F ])
154150 extends TypedEncoder [F ] {
151+
152+ import stage1 ._
153+
155154 def nullable : Boolean = false
156155
157- def jvmRepr : DataType = FramelessInternals .objectTypeFor[F ]
156+ lazy val jvmRepr : DataType = FramelessInternals .objectTypeFor[F ]
158157
159- def catalystRepr : DataType = {
158+ lazy val catalystRepr : DataType = {
160159 val structFields = fields.value.value.map { field =>
161160 StructField (
162161 name = field.name,
@@ -169,39 +168,99 @@ class RecordEncoder[F, G <: HList, H <: HList](
169168 StructType (structFields)
170169 }
171170
172- def toCatalyst (path : Expression ): Expression = {
173- val nameExprs = fields.value.value.map { field => Literal (field.name) }
171+ }
174172
175- val valueExprs = fields.value.value.map { field =>
176- val fieldPath = Invoke (path, field.name, field.encoder.jvmRepr, Nil )
177- field.encoder.toCatalyst(fieldPath)
178- }
173+ object RecordEncoder {
174+
175+ case class ForGeneric [F , G <: HList , H <: HList ](
176+ )(implicit
177+ stage1 : RecordEncoderStage1 [G , H ],
178+ classTag : ClassTag [F ])
179+ extends RecordEncoder [F , G , H ] {
180+
181+ import stage1 ._
182+
183+ def toCatalyst (path : Expression ): Expression = {
184+
185+ val valueExprs = fields.value.value.map { field =>
186+ val fieldPath = Invoke (path, field.name, field.encoder.jvmRepr, Nil )
187+ field.encoder.toCatalyst(fieldPath)
188+ }
189+
190+ val createExpr = stage1.cellsToCatalyst(valueExprs)
179191
180- // the way exprs are encoded in CreateNamedStruct
181- val exprs = nameExprs.zip(valueExprs).flatMap {
182- case (nameExpr, valueExpr) => nameExpr :: valueExpr :: Nil
192+ val nullExpr = Literal .create( null , createExpr.dataType)
193+
194+ If ( IsNull (path), nullExpr, createExpr)
183195 }
184196
185- val createExpr = CreateNamedStruct (exprs)
186- val nullExpr = Literal .create(null , createExpr.dataType)
197+ def fromCatalyst (path : Expression ): Expression = {
198+
199+ val newArgs = stage1.fromCatalystToCells(path)
200+
201+ val newExpr =
202+ NewInstance (
203+ classTag.runtimeClass,
204+ newArgs,
205+ jvmRepr,
206+ propagateNull = true
207+ )
208+
209+ val nullExpr = Literal .create(null , jvmRepr)
187210
188- If (IsNull (path), nullExpr, createExpr)
211+ If (IsNull (path), nullExpr, newExpr)
212+ }
189213 }
190214
191- def fromCatalyst (path : Expression ): Expression = {
192- val exprs = fields.value.value.map { field =>
193- field.encoder.fromCatalyst(
194- GetStructField (path, field.ordinal, Some (field.name))
195- )
215+ case class ForTypedRow [G <: HList , H <: HList ](
216+ )(implicit
217+ stage1 : RecordEncoderStage1 [G , H ],
218+ classTag : ClassTag [TypedRow [G ]])
219+ extends RecordEncoder [TypedRow [G ], G , H ] {
220+
221+ import stage1 ._
222+
223+ private final val _apply = " apply"
224+ private final val _fromInternalRow = " fromInternalRow"
225+
226+ def toCatalyst (path : Expression ): Expression = {
227+
228+ val valueExprs = fields.value.value.zipWithIndex.map {
229+ case (field, i) =>
230+ val fieldPath = Invoke (
231+ path,
232+ _apply,
233+ field.encoder.jvmRepr,
234+ Seq (Literal .create(i, IntegerType ))
235+ )
236+ field.encoder.toCatalyst(fieldPath)
237+ }
238+
239+ val createExpr = stage1.cellsToCatalyst(valueExprs)
240+
241+ val nullExpr = Literal .create(null , createExpr.dataType)
242+
243+ If (IsNull (path), nullExpr, createExpr)
196244 }
197245
198- val newArgs = newInstanceExprs.value.from(exprs)
199- val newExpr =
200- NewInstance (classTag.runtimeClass, newArgs, jvmRepr, propagateNull = true )
246+ def fromCatalyst (path : Expression ): Expression = {
201247
202- val nullExpr = Literal .create(null , jvmRepr)
248+ val newArgs = stage1.fromCatalystToCells(path)
249+ val aggregated = CreateStruct (newArgs)
203250
204- If (IsNull (path), nullExpr, newExpr)
251+ val partial = TypedRow .WithCatalystTypes (newArgs.map(_.dataType))
252+
253+ val newExpr = Invoke (
254+ Literal .fromObject(partial),
255+ _fromInternalRow,
256+ TypedRow .catalystType,
257+ Seq (aggregated)
258+ )
259+
260+ val nullExpr = Literal .create(null , jvmRepr)
261+
262+ If (IsNull (path), nullExpr, newExpr)
263+ }
205264 }
206265}
207266
0 commit comments