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

Seemingly inlined column match fails compilation #253

Open
arturaz opened this issue Mar 13, 2023 · 0 comments
Open

Seemingly inlined column match fails compilation #253

arturaz opened this issue Mar 13, 2023 · 0 comments

Comments

@arturaz
Copy link
Contributor

arturaz commented Mar 13, 2023

Version: 4.6.0.2-SNAPSHOT
Module: quill-sql

In theory, if all parts of the inline def are known to the compiler you should be able to generate different queries based on the value that is given at the compile time.

This fails, though:

import io.getquill._

class MyContext extends SqlMirrorContext(MirrorSqlDialect, Literal)

val ctx = new MyContext()
import ctx.*

enum ColIdx:
	case Idx1, Idx2

case class Inventory(col1: Int, col2: Int) {
  inline def forIdx(inline idx: ColIdx): Int =
  	inline idx match
  		case ColIdx.Idx1 => col1
  		case ColIdx.Idx2 => col2
}

inline def queryFor(inline idx: ColIdx) =
  println(ctx.run(quote {
    query[Inventory].map(_.forIdx(idx))
  }))

/**
This results in:

Found the following variables: List(Inventory_this) that seem to originate outside of a `quote {...}` or `run {...}`
block. In the AST:
querySchema("Inventory").map(x1 => Inventory_this.col1)
Quotes and run blocks cannot use values outside their scope directly (with the exception of inline expressions in Scala 3).
In order to use runtime values in a quotation, you need to lift them, so instead
of this `Inventory_this` do this: `lift(Inventory_this)`.
Here is a more complete example:
Instead of this: `def byName(n: String) = quote(query[Person].filter(_.name == n))`
        Do this: `def byName(n: String) = quote(query[Person].filter(_.name == lift(n)))`

**/
queryFor(ColIdx.Idx1)
queryFor(ColIdx.Idx2)

https://scastie.scala-lang.org/OGDGYy6MTgeDuYXbPHUxuQ

I am not sure if this is an inherent limitation or could be fixed.

It seems that we need to replace the Inventory_this to x1 when compiling.

Workaround

inline def queryForWorkaround(inline idx: ColIdx) =
  println(ctx.run(quote {
    query[Inventory].map { t =>
      inline idx match {
        case ColIdx.Idx1 => t.col1
        case ColIdx.Idx2 => t.col2
      }
    }
  }))
queryForWorkaround(ColIdx.Idx1)

@getquill/maintainers

@arturaz arturaz changed the title Seemingly inlined column switch fails compilation Seemingly inlined column match fails compilation Mar 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant