zio / zio-quill

Compile-time Language Integrated Queries for Scala
https://zio.dev/zio-quill
Apache License 2.0
2.14k stars 347 forks source link

Replace sheath leaf clauses with SqlQuery-centric logic #3057

Open deusaquilus opened 1 week ago

deusaquilus commented 1 week ago

SheathLeafClauses is buggy and fails for even simple examples like this:

  case class Parent(id: Int, name: String)
  case class Child(parentId: Int, name: String)

  val ids = quote {
    (for {
      p <- query[Parent]
      a <- query[Child].join(a => a.parentId == p.id)
    } yield p.id).distinct
  }

  val parentChildJoined = quote {
    for {
      id <- ids
      p  <- query[Parent].join(p => p.id == id)
      c  <- query[Child].join(c => c.parentId == p.id)
    } yield (p, c)
  }

Throws an error during beta reduction (TODO get the error).

We want to replace the logic with a more practical set of transforms that happen on SqlQuery since that is the place where it should mater that clauses cannot be primitive. The ideal place to do this is between SqlQuery and ExpandNestedQuery because at that time every single SqlQuery that has only one primitive-valued SelectValue (in the FlattenSqlQuery.select) must correspond to a type of situation resembling SELECT primitive FROM (SELECT x.primitive FROM ...) AS primitive. It makes it easier to turn the whole construct into something friendly to SQL like: SELECT primitive.value FROM (SELECT x.primitive AS value FROM ...) AS primitive.