Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make call side of udf match the param side at compile time #151

Merged
merged 9 commits into from
Sep 14, 2023
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ ThisBuild / developers := List(
tlGitHubDev("oyvindberg", "Øyvind Raddum Berg"),
tlGitHubDev("lysebraate", "Alfred Sandvik Lysebraate"),
tlGitHubDev("HenningKoller", "Henning Grimeland Koller"),
tlGitHubDev("ingararb", "Ingar Abrahamsen"),
tlGitHubDev("ingarabr", "Ingar Abrahamsen"),
tlGitHubDev("hamnis", "Erlend Hamnaberg")
)
ThisBuild / tlCiHeaderCheck := true
ThisBuild / tlCiScalafmtCheck := true
ThisBuild / tlSonatypeUseLegacyHost := true
ThisBuild / Test / fork := true

// publish website from this branch
//ThisBuild / tlSitePublishBranch := Some("main")
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/scala-2/no/nrk/bigquery/internal/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2020 NRK
*
* SPDX-License-Identifier: Apache-2.0
*/

package no.nrk.bigquery

package object internal {
type Nat = shapeless.Nat
val nat = shapeless.nat
type Sized[+Repr, L <: shapeless.Nat] = shapeless.Sized[Repr, L]
val Sized = shapeless.Sized
type SizedBuilder[CC[_]] = shapeless.SizedBuilder[CC]
}
37 changes: 37 additions & 0 deletions core/src/main/scala-3/no/nrk/bigquery/internal/NatImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020 NRK
*
* SPDX-License-Identifier: Apache-2.0
*/

package no.nrk.bigquery.internal

sealed trait NatImpl
type Nat = NatImpl

object nat {

type _0 = 0 with NatImpl
type _1 = 1 with NatImpl
type _2 = 2 with NatImpl
type _3 = 3 with NatImpl
type _4 = 4 with NatImpl
type _5 = 5 with NatImpl
type _6 = 6 with NatImpl
type _7 = 7 with NatImpl
type _8 = 8 with NatImpl
type _9 = 9 with NatImpl
type _10 = 10 with NatImpl
type _11 = 11 with NatImpl
type _12 = 12 with NatImpl
type _13 = 13 with NatImpl
type _14 = 14 with NatImpl
type _15 = 15 with NatImpl
type _16 = 16 with NatImpl
type _17 = 17 with NatImpl
type _18 = 18 with NatImpl
type _19 = 19 with NatImpl
type _20 = 20 with NatImpl
type _21 = 21 with NatImpl
type _22 = 22 with NatImpl
}
32 changes: 32 additions & 0 deletions core/src/main/scala-3/no/nrk/bigquery/internal/Sized.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2020 NRK
*
* SPDX-License-Identifier: Apache-2.0
*/

package no.nrk.bigquery.internal

final class Sized[+Repr, N <: Nat](val unsized: Repr) {
override def toString = unsized.toString

override def equals(other: Any): Boolean =
other match {
case o: Sized[_, _] => unsized == o.unsized
case _ => false
}

override def hashCode: Int = unsized.hashCode
}

object Sized {

def apply[CC[_]] = new SizedBuilder[CC]

def wrap[Repr, L <: Nat](r: Repr): Sized[Repr, L] =
new Sized[Repr, L](r)

extension [A, N <: Nat](sized: Sized[IndexedSeq[A], N])
def map[B](f: A => B): Sized[IndexedSeq[B], N] =
new Sized[IndexedSeq[B], N](sized.unsized.map(f(_)))
def length: Int = sized.unsized.length
}
198 changes: 198 additions & 0 deletions core/src/main/scala-3/no/nrk/bigquery/internal/SizedBuilder.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*
* Copyright 2020 NRK
*
* SPDX-License-Identifier: Apache-2.0
*/

package no.nrk.bigquery.internal

class SizedBuilder[CC[_]] {
def apply[A](a1: A) = new Sized[IndexedSeq[A], nat._1](IndexedSeq(a1))
def apply[A](a1: A, a2: A) = new Sized[IndexedSeq[A], nat._2](IndexedSeq(a1, a2))
def apply[A](a1: A, a2: A, a3: A) = new Sized[IndexedSeq[A], nat._3](IndexedSeq(a1, a2, a3))
def apply[A](a1: A, a2: A, a3: A, a4: A) = new Sized[IndexedSeq[A], nat._4](IndexedSeq(a1, a2, a3, a4))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A) = new Sized[IndexedSeq[A], nat._5](IndexedSeq(a1, a2, a3, a4, a5))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A) =
new Sized[IndexedSeq[A], nat._6](IndexedSeq(a1, a2, a3, a4, a5, a6))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A) =
new Sized[IndexedSeq[A], nat._7](IndexedSeq(a1, a2, a3, a4, a5, a6, a7))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A) =
new Sized[IndexedSeq[A], nat._8](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A) =
new Sized[IndexedSeq[A], nat._9](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A, a10: A) =
new Sized[IndexedSeq[A], nat._10](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A, a10: A, a11: A) =
new Sized[IndexedSeq[A], nat._11](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A, a10: A, a11: A, a12: A) =
new Sized[IndexedSeq[A], nat._12](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A, a10: A, a11: A, a12: A, a13: A) =
new Sized[IndexedSeq[A], nat._13](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13))
def apply[A](a1: A, a2: A, a3: A, a4: A, a5: A, a6: A, a7: A, a8: A, a9: A, a10: A, a11: A, a12: A, a13: A, a14: A) =
new Sized[IndexedSeq[A], nat._14](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A) =
new Sized[IndexedSeq[A], nat._15](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A) =
new Sized[IndexedSeq[A], nat._16](IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A) = new Sized[IndexedSeq[A], nat._17](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A,
a18: A) = new Sized[IndexedSeq[A], nat._18](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A,
a18: A,
a19: A) = new Sized[IndexedSeq[A], nat._19](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A,
a18: A,
a19: A,
a20: A) = new Sized[IndexedSeq[A], nat._20](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A,
a18: A,
a19: A,
a20: A,
a21: A) = new Sized[IndexedSeq[A], nat._21](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21))
def apply[A](
a1: A,
a2: A,
a3: A,
a4: A,
a5: A,
a6: A,
a7: A,
a8: A,
a9: A,
a10: A,
a11: A,
a12: A,
a13: A,
a14: A,
a15: A,
a16: A,
a17: A,
a18: A,
a19: A,
a20: A,
a21: A,
a22: A) = new Sized[IndexedSeq[A], nat._22](
IndexedSeq(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22))

}
6 changes: 3 additions & 3 deletions core/src/main/scala/no/nrk/bigquery/BQSqlFrag.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ sealed trait BQSqlFrag {
}

final lazy val asStringWithUDFs: String = {
val udfs = allReferencedUDFs.collect { case udf: UDF.Temporary => udf.definition.asString }
val udfs = allReferencedUDFs.collect { case udf: UDF.Temporary[_] => udf.definition.asString }
val udfsAsString = udfs.mkString("\n\n") + (if (udfs.nonEmpty) "\n\n" else "")
udfsAsString + asString
}
Expand Down Expand Up @@ -161,7 +161,7 @@ sealed trait BQSqlFrag {
allReferencedAsPartitions(expandAndExcludeViews = true)
.filterNot(pid => pid.wholeTable.isInstanceOf[BQTableDef.View[_]])

final def allReferencedUDFs: Seq[UDF[UDF.UDFId]] =
final def allReferencedUDFs: Seq[UDF[UDF.UDFId, _]] =
this.collect { case BQSqlFrag.Call(udf, _) => udf }.distinct

override def toString: String = asString
Expand All @@ -172,7 +172,7 @@ object BQSqlFrag {
def backticks(string: String): BQSqlFrag = Frag("`" + string + "`")

case class Frag(string: String) extends BQSqlFrag
case class Call(udf: UDF[UDF.UDFId], args: List[BQSqlFrag]) extends BQSqlFrag {
case class Call(udf: UDF[UDF.UDFId, _], args: List[BQSqlFrag]) extends BQSqlFrag {
require(
udf.params.length == args.length,
show"UDF ${udf.name}: Expected ${udf.params.length} arguments, got ${args.length}"
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/scala/no/nrk/bigquery/EnsureUpdated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ case class TableDefOperationMeta(
}
case class UdfOperationMeta(
routine: RoutineInfo,
persistentUdf: UDF.Persistent
persistentUdf: UDF.Persistent[_]
) extends OperationMeta {
override def identifier: String = persistentUdf.name.asString
}
Expand Down Expand Up @@ -56,12 +56,12 @@ object UpdateOperation {
) extends Success

case class CreatePersistentUdf(
persistentUdf: UDF.Persistent,
persistentUdf: UDF.Persistent[_],
routine: RoutineInfo
) extends Success

case class UpdatePersistentUdf(
persistentUdf: UDF.Persistent,
persistentUdf: UDF.Persistent[_],
routine: RoutineInfo
) extends Success

Expand Down Expand Up @@ -89,7 +89,7 @@ class EnsureUpdated[F[_]](
TableUpdateOperation.from(template, maybeExisting)
}

def check(persistentUdf: UDF.Persistent): F[UpdateOperation] =
def check(persistentUdf: UDF.Persistent[_]): F[UpdateOperation] =
bqClient.getRoutine(persistentUdf.name).map { maybeExisting =>
UdfUpdateOperation.from(persistentUdf, maybeExisting)
}
Expand Down
Loading