@@ -119,20 +119,19 @@ object DropUnitValues {
119119 }
120120}
121121
122- class RecordEncoder [F , G <: HList , H <: HList ]
122+ abstract class RecordEncoder [F , G <: HList , H <: HList ]
123123 (implicit
124- i0 : LabelledGeneric .Aux [F , G ],
125- i1 : DropUnitValues .Aux [G , H ],
126- i2 : IsHCons [H ],
127- fields : Lazy [RecordEncoderFields [H ]],
128- newInstanceExprs : Lazy [NewInstanceExprs [G ]],
124+ stage1 : RecordEncoderStage1 [G , H ],
129125 classTag : ClassTag [F ]
130126 ) extends TypedEncoder [F ] {
127+
128+ import stage1 ._
129+
131130 def nullable : Boolean = false
132131
133- def jvmRepr : DataType = FramelessInternals .objectTypeFor[F ]
132+ lazy val jvmRepr : DataType = FramelessInternals .objectTypeFor[F ]
134133
135- def catalystRepr : DataType = {
134+ lazy val catalystRepr : DataType = {
136135 val structFields = fields.value.value.map { field =>
137136 StructField (
138137 name = field.name,
@@ -145,41 +144,94 @@ class RecordEncoder[F, G <: HList, H <: HList]
145144 StructType (structFields)
146145 }
147146
147+ }
148+
149+ object RecordEncoder {
150+
151+ case class ForGeneric [F , G <: HList , H <: HList ](
152+ )(implicit
153+ stage1 : RecordEncoderStage1 [G , H ],
154+ classTag : ClassTag [F ])
155+ extends RecordEncoder [F , G , H ] {
156+
157+ import stage1 ._
158+
148159 def toCatalyst (path : Expression ): Expression = {
149- val nameExprs = fields.value.value.map { field =>
150- Literal (field.name)
151- }
152160
153161 val valueExprs = fields.value.value.map { field =>
154162 val fieldPath = Invoke (path, field.name, field.encoder.jvmRepr, Nil )
155163 field.encoder.toCatalyst(fieldPath)
156164 }
157165
158- // the way exprs are encoded in CreateNamedStruct
159- val exprs = nameExprs.zip(valueExprs).flatMap {
160- case (nameExpr, valueExpr) => nameExpr :: valueExpr :: Nil
161- }
166+ val createExpr = stage1.cellsToCatalyst(valueExprs)
162167
163- val createExpr = CreateNamedStruct (exprs)
164168 val nullExpr = Literal .create(null , createExpr.dataType)
165169
166170 If (IsNull (path), nullExpr, createExpr)
167171 }
168172
169173 def fromCatalyst (path : Expression ): Expression = {
170- val exprs = fields.value.value.map { field =>
171- field.encoder.fromCatalyst(
172- GetStructField (path, field.ordinal, Some (field.name)))
173- }
174174
175- val newArgs = newInstanceExprs.value.from(exprs )
175+ val newArgs = stage1.fromCatalystToCells(path )
176176 val newExpr = NewInstance (
177177 classTag.runtimeClass, newArgs, jvmRepr, propagateNull = true )
178178
179179 val nullExpr = Literal .create(null , jvmRepr)
180180
181181 If (IsNull (path), nullExpr, newExpr)
182182 }
183+ }
184+
185+ case class ForTypedRow [G <: HList , H <: HList ](
186+ )(implicit
187+ stage1 : RecordEncoderStage1 [G , H ],
188+ classTag : ClassTag [TypedRow [G ]])
189+ extends RecordEncoder [TypedRow [G ], G , H ] {
190+
191+ import stage1 ._
192+
193+ private final val _apply = " apply"
194+ private final val _fromInternalRow = " fromInternalRow"
195+
196+ def toCatalyst (path : Expression ): Expression = {
197+
198+ val valueExprs = fields.value.value.zipWithIndex.map {
199+ case (field, i) =>
200+ val fieldPath = Invoke (
201+ path,
202+ _apply,
203+ field.encoder.jvmRepr,
204+ Seq (Literal .create(i, IntegerType ))
205+ )
206+ field.encoder.toCatalyst(fieldPath)
207+ }
208+
209+ val createExpr = stage1.cellsToCatalyst(valueExprs)
210+
211+ val nullExpr = Literal .create(null , createExpr.dataType)
212+
213+ If (IsNull (path), nullExpr, createExpr)
214+ }
215+
216+ def fromCatalyst (path : Expression ): Expression = {
217+
218+ val newArgs = stage1.fromCatalystToCells(path)
219+ val aggregated = CreateStruct (newArgs)
220+
221+ val partial = TypedRow .WithCatalystTypes (newArgs.map(_.dataType))
222+
223+ val newExpr = Invoke (
224+ Literal .fromObject(partial),
225+ _fromInternalRow,
226+ TypedRow .catalystType,
227+ Seq (aggregated)
228+ )
229+
230+ val nullExpr = Literal .create(null , jvmRepr)
231+
232+ If (IsNull (path), nullExpr, newExpr)
233+ }
234+ }
183235}
184236
185237final class RecordFieldEncoder [T ](
0 commit comments