zio / zio-quill

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

AST resolution is invalid with implicit class in EntityQuery #1124

Closed kenchan0130 closed 6 years ago

kenchan0130 commented 6 years ago

Version: (e.g. 2.5.4) Module: (e.g. quill-finagle-mysql) Database: (e.g. MariaDB)

Expected behavior

If we use the implicit class with type parameter, resolution of AST will not be as expected.

Actual behavior

Executed SQL='UPDATE `TestTable` SET unused = 'unused''

Steps to reproduce the behavior

CREATE TABLE IF NOT EXISTS `TestTable` (
  `time` DATETIME(6)
);
case class TestTable(time: LocalDateTime)
// I have created this process expecting to operate generically so that the column name may be different depending on the table
implicit class UpdateCurrentTime[T](entityQuery: EntityQuery[T]) {
  def updateCurrentTime[C](identifyColumn: T => C) = quote {
    entityQuery.update { r =>
      val column = identifyColumn(r)
      column -> infix"CURRENT_TIMESTAMP(6)".as[C]
    }
  }
}
val updataeCurrentTimeQuote = quote {
  query[TestTable].updateCurrentTime[LocalDateTime](_.time)
}
ctx.run(updataeCurrentTimeQuote)

// println(updataeCurrentTimeQuote.ast.toString)
// => querySchema("TestTable").update(unused => unused -> "unused")

Workaround

Although versatility will be lowered, define the specific type in advance as follows:

type TimeAttribute = { def time: LocalDateTime }
implicit class UpdateCurrentTime[T <: TimeAttribute](entityQuery: EntityQuery[T]) {
  def updateCurrentTime = quote {
    entityQuery.update { r =>
      r.time -> infix"CURRENT_TIMESTAMP(6)".as[LocalDateTime]
    }
  }
}
val updataeCurrentTimeQuote = quote {
  query[TestTable].updateCurrentTime
}
ctx.run(updataeCurrentTimeQuote)

@getquill/maintainers

mosyp commented 6 years ago

Hello @kenchan0130, function which is defined outside of a quotation could not be parsed and used.

A duplicate of #1120