@@ -8,6 +8,7 @@ import org.apache.spark.sql.catalyst.types._
88import scala .language .experimental .macros
99
1010import records ._
11+ import Macros .RecordMacros
1112
1213import org .apache .spark .annotation .Experimental
1314import org .apache .spark .rdd .RDD
@@ -89,17 +90,46 @@ object SQLMacros {
8990
9091 val analyzedPlan = analyzer(logicalPlan)
9192
92- val fields = analyzedPlan.output.zipWithIndex.map {
93- case (attr, i) =>
94- q """ ${attr.name} -> row. ${newTermName(" get" + primitiveForType(attr.dataType))}( $i) """
93+ // TODO: This shouldn't probably be here but somewhere generic
94+ // which defines the catalyst <-> Scala type mapping
95+ def toScalaType (dt : DataType ) = dt match {
96+ case IntegerType => definitions.IntTpe
97+ case LongType => definitions.LongTpe
98+ case ShortType => definitions.ShortTpe
99+ case ByteType => definitions.ByteTpe
100+ case DoubleType => definitions.DoubleTpe
101+ case FloatType => definitions.FloatTpe
102+ case BooleanType => definitions.BooleanTpe
103+ case StringType => definitions.StringClass .toType
95104 }
96105
106+ val schema = analyzedPlan.output.map(attr => (attr.name, toScalaType(attr.dataType)))
107+ val dataImpl = {
108+ // Generate a case for each field
109+ val cases = analyzedPlan.output.zipWithIndex.map {
110+ case (attr, i) =>
111+ cq """ ${attr.name} => row. ${newTermName(" get" + primitiveForType(attr.dataType))}( $i) """
112+ }
113+
114+ // Implement __data using these cases.
115+ // TODO: Unfortunately, this still boxes. We cannot resolve this
116+ // since the R abstraction depends on the fully generic __data.
117+ // The only way to change this is to create __dataLong, etc. on
118+ // R itself
119+ q """
120+ val res = fieldName match {
121+ case .. $cases
122+ case _ => ???
123+ }
124+ res.asInstanceOf[T]
125+ """
126+ }
127+
128+ val record : c.Expr [Nothing ] = new RecordMacros [c.type ](c).record(schema)(tq " Serializable " )()(dataImpl)
97129 val tree = q """
98- import records.R
99130 .. ${args.zipWithIndex.map{ case (r,i) => q """ $r.registerAsTable( ${s " table $i" }) """ }}
100131 val result = sql( $query)
101- // TODO: Avoid double copy
102- result.map(row => R(.. $fields))
132+ result.map(row => $record)
103133 """
104134
105135 println(tree)
0 commit comments