Skip to content

Commit

Permalink
Finish polishing concatImpl for scala 2.13
Browse files Browse the repository at this point in the history
  • Loading branch information
grouzen committed Apr 8, 2024
1 parent d8c1cb6 commit 1b78ce4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import me.mnedokushev.zio.apache.parquet.core.filter.Column
class ColumnPathConcatMacro(val c: blackbox.Context) extends MacroUtils(c) {
import c.universe._

def concatImpl[A, B](parent: Expr[Column[A]], child: Expr[Column[B]])(implicit ptt: c.WeakTypeTag[A]): Tree = {
val childField = getIdentName(child)
def concatImpl[A, B, F](parent: Expr[Column[A]], child: Expr[Column.Named[B, F]])(implicit
ptt: c.WeakTypeTag[A],
ftt: c.WeakTypeTag[F]
): Tree = {
val childField = getSingletonTypeName(ftt.tpe)
val parentFields = ptt.tpe.members.collect {
case p: TermSymbol if p.isCaseAccessor && !p.isMethod => p.name.toString.trim
}.toList

// childField.debugged()
// parentFields.debugged()
// parentFields.contains(childField).debugged()

if (parentFields.exists(_ == childField)) {
val pathTermName = "path"
val dotStringLiteral = "."
Expand All @@ -24,15 +23,13 @@ class ColumnPathConcatMacro(val c: blackbox.Context) extends MacroUtils(c) {

q"_root_.me.mnedokushev.zio.apache.parquet.core.filter.Column.Named($concatExpr)"
} else
c.abort(c.enclosingPosition, "parent/child relation is wrong")
c.abort(c.enclosingPosition, s"Parent column doesn't contain a column named $childField")
}

def getIdentName[A](arg: Expr[A]): String =
arg.tree match {
case Ident(TermName(name)) =>
name
case _ =>
c.abort(c.enclosingPosition, s"Couldn't get a name of identifier: ${arg.tree}")
private def getSingletonTypeName(tpe: Type): String =
tpe match {
case ConstantType(Constant(name)) => name.toString
case _ => c.abort(c.enclosingPosition, s"Couldn't get a name of a singleton type ${showRaw(tpe)}")
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ trait Column[A] { self =>
val path: String
val typeTag: TypeTag[A]

// TODO: validate parent/child relation via macros
// def /[B](child: Column[B]): Column[B] = ???
// me.mnedokushev.zio.apache.parquet.core.filter.concatPaths[A, B](self, child)
// TODO: overcome the limitation of scala macros for having a better API
// I found out the compiler throws an error that macro is not found as
// the macro itself depends on Column. The only option is to move the definition
// of "concat" outside the Column class.
// def /[B](child: Column[B]): Column[B] =
// ColumnPathConcatMacro.concatImpl[A, B]

def >(value: A)(implicit ev: OperatorSupport.LtGt[A]): Predicate[A] =
Predicate.Binary(self, value, Operator.Binary.GreaterThen())
Expand Down Expand Up @@ -39,10 +42,6 @@ trait Column[A] { self =>

object Column {

type Aux[A, Identity0] = Column[A] {
type Identity = Identity0
}

final case class Named[A: TypeTag, Identity0](path: String) extends Column[A] {
override type Identity = Identity0
override val typeTag: TypeTag[A] = implicitly[TypeTag[A]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ package object filter {
def compile[A](predicate: Predicate[A]): Either[String, FilterPredicate] =
macro CompilePredicateMacro.compileImpl[A]

def concat[A, B](parent: Column[A], child: Column[B]): Column[B] =
macro ColumnPathConcatMacro.concatImpl[A, B]
def concat[A, B, F](parent: Column[A], child: Column.Named[B, F]): Column[B] =
macro ColumnPathConcatMacro.concatImpl[A, B, F]

}
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,14 @@ object ExprSpec extends ZIOSpecDefault {
},
test("column path concatenation") {
val (a, b, child, _, _) = Filter[MyRecord].columns
val (c, _) = Filter[MyRecord.Child].columns
// Show that the macro determines the names of the child fields no matter how we name
// the variables that represent the child columns
val (c0, d0) = Filter[MyRecord.Child].columns

assert(a.path)(equalTo("a")) &&
assert(b.path)(equalTo("b")) &&
assert(concat(child, c).path)(equalTo("child.c"))
assert(concat(child, c0).path)(equalTo("child.c")) &&
assert(concat(child, d0).path)(equalTo("child.d"))
// assert(/:(child, d).path)(equalTo("child.d"))
// assert((child / d).path)(equalTo("child.d")) &&
// assert((d / child).path)(equalTo("d.child")) // TODO: must fail
Expand Down

0 comments on commit 1b78ce4

Please sign in to comment.