From 1b78ce4c3a1e9f8b99890dd763714aee71f20027 Mon Sep 17 00:00:00 2001 From: Michael Nedokushev Date: Mon, 8 Apr 2024 22:29:56 +0100 Subject: [PATCH] Finish polishing concatImpl for scala 2.13 --- .../internal/ColumnPathConcatMacro.scala | 23 ++++++++----------- .../apache/parquet/core/filter/Column.scala | 13 +++++------ .../apache/parquet/core/filter/package.scala | 4 ++-- .../apache/parquet/core/filter/ExprSpec.scala | 7 ++++-- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/modules/core/src/main/scala-2/me/mnedokushev/zio/apache/parquet/core/filter/internal/ColumnPathConcatMacro.scala b/modules/core/src/main/scala-2/me/mnedokushev/zio/apache/parquet/core/filter/internal/ColumnPathConcatMacro.scala index b216c58..e56e951 100644 --- a/modules/core/src/main/scala-2/me/mnedokushev/zio/apache/parquet/core/filter/internal/ColumnPathConcatMacro.scala +++ b/modules/core/src/main/scala-2/me/mnedokushev/zio/apache/parquet/core/filter/internal/ColumnPathConcatMacro.scala @@ -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 = "." @@ -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)}") } } diff --git a/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/Column.scala b/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/Column.scala index e44bd98..bd1c09d 100644 --- a/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/Column.scala +++ b/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/Column.scala @@ -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()) @@ -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]] diff --git a/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/package.scala b/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/package.scala index bbffdae..7cd999d 100644 --- a/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/package.scala +++ b/modules/core/src/main/scala/me/mnedokushev/zio/apache/parquet/core/filter/package.scala @@ -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] } diff --git a/modules/core/src/test/scala/me/mnedokushev/zio/apache/parquet/core/filter/ExprSpec.scala b/modules/core/src/test/scala/me/mnedokushev/zio/apache/parquet/core/filter/ExprSpec.scala index f3bb9b9..3259b35 100644 --- a/modules/core/src/test/scala/me/mnedokushev/zio/apache/parquet/core/filter/ExprSpec.scala +++ b/modules/core/src/test/scala/me/mnedokushev/zio/apache/parquet/core/filter/ExprSpec.scala @@ -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