diff options
author | Jakob Odersky <jakob@odersky.com> | 2016-09-21 22:06:10 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2016-09-21 22:06:10 -0700 |
commit | 3e7eb398930d2ef302a04021ae7145fc1b901a21 (patch) | |
tree | abca25bfd7e4171f2a6fc103fcbc739079066fb1 | |
parent | 8fe58dbd9dbd70f2160acd79754e2d3729243c9e (diff) | |
download | spark-3e7eb398930d2ef302a04021ae7145fc1b901a21.tar.gz spark-3e7eb398930d2ef302a04021ae7145fc1b901a21.tar.bz2 spark-3e7eb398930d2ef302a04021ae7145fc1b901a21.zip |
now it really compiles
-rw-r--r-- | sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaMacros.scala | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaMacros.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaMacros.scala index 343ce1ace1..2e45b14801 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaMacros.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaMacros.scala @@ -3,19 +3,9 @@ package org.apache.spark.sql.catalyst import scala.reflect.macros.blackbox.Context import scala.reflect.api.Universe - -class ScalaMacros(val context: Context) extends ScalaReflection { - - val universe: context.universe.type = context.universe - - def mirror: universe.Mirror = context.mirror - -} - - -import scala.language.experimental.macros - +import scala.reflect.ClassTag import org.apache.spark.sql.Encoder +import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder //import org.apache.spark.sql.catalyst.{InternalRow, JavaTypeInference, ScalaReflection} import org.apache.spark.sql.catalyst.analysis.{Analyzer, GetColumnByOrdinal, SimpleAnalyzer, UnresolvedAttribute, UnresolvedExtractValue} import org.apache.spark.sql.catalyst.expressions._ @@ -26,20 +16,22 @@ import org.apache.spark.sql.catalyst.plans.logical.{CatalystSerde, DeserializeTo import org.apache.spark.sql.types.{BooleanType, ObjectType, StructField, StructType} import org.apache.spark.util.Utils -object Macros { +/** Type parameter is required for a workaround described here http://docs.scala-lang.org/overviews/macros/overview.html + * TODO: remove the type parameter once Scala 2.10 is dropped */ +class MacrosHelper[C <: Context](val context: C) extends ScalaReflection { - implicit def encoder[T]: Encoder[T] = macro encoderImpl[T] + val universe: context.universe.type = context.universe - def encoderImpl[T: c.WeakTypeTag](c: Context): c.Expr[Encoder[T]] = { - val helper = new ScalaMacros(c) - import helper.universe._ + val mirror: universe.Mirror = context.mirror - val tag = implicitly[WeakTypeTag[T]] + import universe._ + def generate[T: context.WeakTypeTag]: context.Tree = { + val tag = implicitly[WeakTypeTag[T]] val tpe = tag.tpe - val flat = !helper.definedByConstructorParams(tpe) - val inputObject = BoundReference(0, helper.dataTypeFor[T](tag), nullable = true) + val flat = !definedByConstructorParams(tpe) + val inputObject = BoundReference(0, dataTypeFor[T](tag), nullable = true) val nullSafeInput = if (flat) { inputObject } else { @@ -47,16 +39,34 @@ object Macros { // doesn't allow top-level row to be null, only its columns can be null. AssertNotNull(inputObject, Seq("top level non-flat input object")) } - val serializer = helper.serializerFor[T](nullSafeInput)(tag) - val deserializer = helper.deserializerFor[T](tag) + val serializer = serializerFor[T](nullSafeInput)(tag) + val deserializer = deserializerFor[T](tag) - val schema = helper.schemaFor[T](tag) match { - case helper.Schema(s: StructType, _) => s - case helper.Schema(dt, nullable) => new StructType().add("value", dt, nullable) + val schema = schemaFor[T](tag) match { + case Schema(s: StructType, _) => s + case Schema(dt, nullable) => new StructType().add("value", dt, nullable) } - ??? + q"""new _root_.org.apache.spark.sql.catalyst.encoders.ExpressionEncoder[T]( + ${reify(schema)}, + ${reify(flat)}, + ${reify(serializer.flatten)}, + ${reify(deserializer)}, + classTag[$tpe])""" } +} + + +import scala.language.experimental.macros + +object ScalaMacros { + + final def newEncoder[T]: ExpressionEncoder[T] = macro newEncoderImpl[T] + + def newEncoderImpl[T: c.WeakTypeTag](c: Context): c.Expr[ExpressionEncoder[T]] = { + val helper = new MacrosHelper[c.type](c) + c.Expr[ExpressionEncoder[T]](helper.generate) + } } |