Skip to content

Commit

Permalink
Don't include pure object fields in ZQuery collection (#2015)
Browse files Browse the repository at this point in the history
* Don't include pure values in ZQuery collection

* Fix for Scala 2.12

* Go back to using mutable.HashMap
  • Loading branch information
kyri-petrou authored Nov 22, 2023
1 parent 2646d9a commit 8ef7fb3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ object NestedZQueryBenchmarkSchema {
case class MultifieldRoot(entities: Query[List[MultifieldEntity]])
case class MultifieldEntity(
id: Int,
nested0: Query[Int],
nested1: Query[Int],
nested0: Int,
nested1: Int,
nested2: Query[Int],
nested3: Query[Int],
nested4: Query[Int],
Expand Down Expand Up @@ -167,8 +167,8 @@ object NestedZQueryBenchmarkSchema {
val qi = ZQuery.succeed(i)
MultifieldEntity(
i,
qi,
qi,
i + 1,
i + 2,
qi,
qi,
qi,
Expand Down
43 changes: 35 additions & 8 deletions core/src/main/scala/caliban/execution/Executor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import zio.query.{ Cache, ZQuery }
import zio.stream.ZStream

import scala.annotation.tailrec
import scala.collection.mutable
import scala.jdk.CollectionConverters._

object Executor {
Expand Down Expand Up @@ -157,20 +158,46 @@ object Executor {
val q = if (isPure && !wrapper.wrapPureValues) query else wrapper.wrap(query, fieldInfo)
loop(q, tail)
}
if (isPure && !wrapPureValues) query
else loop(query, wrappers)
loop(query, wrappers)
}

def objectFieldQuery(name: String, step: ReducedStep[R], info: FieldInfo) = {
val q = wrap(loop(step), step.isPure)(fieldWrappers, info)
if (info.details.fieldType.isNullable) q.catchAll(handleError).map((name, _))
else q.map((name, _))
}

def loop(step: ReducedStep[R]): ZQuery[R, ExecutionError, ResponseValue] =
step match {
case PureStep(value) => ZQuery.succeed(value)
case ReducedStep.ObjectStep(steps) =>
val queries = steps.map { case (name, step, info) =>
val q = wrap(loop(step), step.isPure)(fieldWrappers, info)
(if (info.details.fieldType.isNullable) q.catchAll(handleError) else q)
.map(name -> _)
}
collectAll(queries).map(ObjectValue.apply)
var resolved: mutable.HashMap[String, ResponseValue] = null

val queries =
if (wrapPureValues) steps.map((objectFieldQuery _).tupled)
else {
val queries = List.newBuilder[ZQuery[R, ExecutionError, (String, ResponseValue)]]

var remaining = steps
while (!remaining.isEmpty) {
remaining.head match {
case (name, PureStep(value), _) =>
if (null == resolved) resolved = new mutable.HashMap[String, ResponseValue]()
resolved.update(name, value)
case (name, step, info) =>
queries += objectFieldQuery(name, step, info)
}
remaining = remaining.tail
}
queries.result()
}

if (null == resolved) collectAll(queries).map(ObjectValue.apply)
else
collectAll(queries).map { results =>
results.foreach(kv => resolved.update(kv._1, kv._2))
ObjectValue(steps.map { case (name, _, _) => name -> resolved(name) })
}
case ReducedStep.QueryStep(step) =>
step.flatMap(loop)
case ReducedStep.ListStep(steps, areItemsNullable) =>
Expand Down

0 comments on commit 8ef7fb3

Please sign in to comment.