aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2016-09-21 22:06:10 -0700
committerJakob Odersky <jakob@odersky.com>2016-09-21 22:06:10 -0700
commit3e7eb398930d2ef302a04021ae7145fc1b901a21 (patch)
treeabca25bfd7e4171f2a6fc103fcbc739079066fb1
parent8fe58dbd9dbd70f2160acd79754e2d3729243c9e (diff)
downloadspark-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.scala62
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)
+ }
}