Skip to content

Commit

Permalink
fix aggregation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
sviezypan committed Jan 26, 2022
1 parent 360fe14 commit c3489e1
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 210 deletions.
9 changes: 4 additions & 5 deletions core/jvm/src/main/scala/zio/sql/Sql.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ trait Sql extends SelectModule with DeleteModule with UpdateModule with ExprModu
*
* SELECT ARBITRARY(age), COUNT(*) FROM person GROUP BY age
*/
def select[F, A, B <: SelectionSet[A]](selection: Selection[F, A, B]): SelectBuilder[F, A, B] =
SelectBuilder(selection)

def select[F, A, B <: SelectionSet[A]](selection: AggSelection[F, A, B]): AggSelectBuilder[F, A, B] =
AggSelectBuilder(selection)
def select[F, A, B <: SelectionSet[A]](selection: Selection[F, A, B])(
implicit i: Features.IsPartiallyAggregated[F]
): Selector[F, A, B, i.Unaggregated] =
Selector[F, A, B, i.Unaggregated](selection)

def subselect[ParentTable]: SubselectPartiallyApplied[ParentTable] = new SubselectPartiallyApplied[ParentTable]

Expand Down
17 changes: 6 additions & 11 deletions core/jvm/src/main/scala/zio/sql/expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,8 @@ trait ExprModule extends NewtypesModule with FeaturesModule with OpsModule {
}
}

trait ExprToSelectionLowerPrio {
implicit def expToSelection[F: Features.IsNotAggregated, A, B](
expr: Expr[F, A, B]
): Selection[F, A, SelectionSet.Cons[A, B, SelectionSet.Empty]] =
Selection.computedOption(expr, Expr.exprName(expr))
}
object Expr {

object Expr extends ExprToSelectionLowerPrio {
implicit val subqueryToExpr = self.Read.Subselect.subselectToExpr _

sealed trait InvariantExpr[F, -A, B] extends Expr[F, A, B] {
Expand All @@ -132,14 +126,15 @@ trait ExprModule extends NewtypesModule with FeaturesModule with OpsModule {
case _ => None
}

implicit def aggregatedExprToSelection[F: Features.IsFullyAggregated, A, B](
implicit def expToSelection[F, A, B](
expr: Expr[F, A, B]
): AggSelection[F, A, SelectionSet.Cons[A, B, SelectionSet.Empty]] =
AggSelection.computedOption(expr, exprName(expr))
): Selection[F, A, SelectionSet.Cons[A, B, SelectionSet.Empty]] =
Selection.computedOption[F, A, B](expr, Expr.exprName(expr))

// aggregated F should not be propagated
sealed case class Subselect[F <: Features.Aggregated[_], Repr, Source, Subsource, Head](
subselect: Read.Subselect[F, Repr, _ <: Source, Subsource, Head, SelectionSet.Empty]
) extends InvariantExpr[F, Any, Head] {
) extends InvariantExpr[Features.Derived, Any, Head] {
override def typeTag: TypeTag[Head] = subselect.selection.value.head.toColumn.typeTag
}

Expand Down
59 changes: 41 additions & 18 deletions core/jvm/src/main/scala/zio/sql/features.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ package zio.sql

import scala.annotation.implicitNotFound

trait FeaturesModule {
trait FeaturesModule {

type :||:[A, B] = Features.Union[A, B]

object Features extends PartialAggregationLowerPrio {
object Features {
type Aggregated[_]
type Union[_, _]
type Source[_]
//TODO make Derived and Join tables return Expr of type "Derived" when .columns is called
type Derived
type Literal
type Function0
type Derived

sealed trait IsNotAggregated[A]
object IsNotAggregated {
Expand All @@ -23,12 +22,12 @@ trait FeaturesModule {
implicit def SourceIsNotAggregated[A]: IsNotAggregated[Source[A]] =
new IsNotAggregated[Source[A]] {}

implicit val DerivedIsNotAggregated: IsNotAggregated[Derived] =
new IsNotAggregated[Derived] {}

implicit val LiteralIsNotAggregated: IsNotAggregated[Literal] =
new IsNotAggregated[Literal] {}

implicit val DerivedIsNotAggregated: IsNotAggregated[Derived] =
new IsNotAggregated[Derived] {}

implicit val Function0IsNotAggregated: IsNotAggregated[Function0] =
new IsNotAggregated[Function0] {}
}
Expand All @@ -40,6 +39,8 @@ trait FeaturesModule {

implicit def AggregatedIsAggregated[A]: IsFullyAggregated[Aggregated[A]] = new IsFullyAggregated[Aggregated[A]] {}

implicit val LiteralIsAggregated: IsFullyAggregated[Literal] = new IsFullyAggregated[Literal] {}

implicit def UnionIsAggregated[A: IsFullyAggregated, B: IsFullyAggregated]: IsFullyAggregated[Union[A, B]] =
new IsFullyAggregated[Union[A, B]] {}
}
Expand All @@ -50,22 +51,44 @@ trait FeaturesModule {
object IsSource {
implicit def isSource[ColumnIdentity]: IsSource[Source[ColumnIdentity]] = new IsSource[Source[ColumnIdentity]] {}
}
}

trait PartialAggregationLowerPrio {
sealed trait IsPartiallyAggregated[A]
sealed trait IsPartiallyAggregated[A] {
type Unaggregated
}

object IsPartiallyAggregated {

def apply[A](implicit is: IsPartiallyAggregated[A]): IsPartiallyAggregated[A] = is
object IsPartiallyAggregated extends IsPartiallyAggregatedLowPriorityImplicits {

type WithRemainder[F, R] = IsPartiallyAggregated[F] {
type Unaggregated = R
}

def apply[A](implicit is: IsPartiallyAggregated[A]): IsPartiallyAggregated.WithRemainder[A, is.Unaggregated] = is

implicit def AggregatedIsAggregated[A]: IsPartiallyAggregated[Features.Aggregated[A]] = new IsPartiallyAggregated[Features.Aggregated[A]] {}
implicit def AggregatedIsAggregated[A]: IsPartiallyAggregated.WithRemainder[Aggregated[A], Any] = new IsPartiallyAggregated[Aggregated[A]] {
override type Unaggregated = Any
}

implicit def UnionIsAggregatedInB[A, B](implicit instB: IsPartiallyAggregated[B]): IsPartiallyAggregated[Features.Union[A, B]] =
new IsPartiallyAggregated[Features.Union[A, B]] {}
implicit def UnionIsAggregated[A, B](implicit inA: IsPartiallyAggregated[A], inB: IsPartiallyAggregated[B]): IsPartiallyAggregated.WithRemainder[Union[A, B], inA.Unaggregated with inB.Unaggregated] =
new IsPartiallyAggregated[Union[A, B]] {
override type Unaggregated = inA.Unaggregated with inB.Unaggregated
}

implicit val LiteralIsAggregated: IsPartiallyAggregated.WithRemainder[Literal, Any] = new IsPartiallyAggregated[Literal] {
override type Unaggregated = Any
}

implicit val DerivedIsAggregated: IsPartiallyAggregated.WithRemainder[Derived, Any] = new IsPartiallyAggregated[Derived] {
override type Unaggregated = Any
}

implicit val FunctionIsAggregated: IsPartiallyAggregated.WithRemainder[Function0, Any] = new IsPartiallyAggregated[Function0] {
override type Unaggregated = Any
}
}

implicit def UnionIsAggregatedInA[A, B](implicit instB: IsPartiallyAggregated[A]): IsPartiallyAggregated[Features.Union[A, B]] =
new IsPartiallyAggregated[Features.Union[A, B]] {}
trait IsPartiallyAggregatedLowPriorityImplicits {
implicit def SourceIsAggregated[A]: IsPartiallyAggregated.WithRemainder[Features.Source[A], Features.Source[A]] = new IsPartiallyAggregated[Features.Source[A]] { override type Unaggregated = Features.Source[A]
}
}
}
}
Loading

0 comments on commit c3489e1

Please sign in to comment.