zio-protoquill icon indicating copy to clipboard operation
zio-protoquill copied to clipboard

Date/Time types fail to compile with comparison operators

Open ajrnz opened this issue 2 years ago • 4 comments

I tried this with the new LocalDateTimeOps but the same thing happens with a hand rolled comparator

Version: 0.4.5, 0.4.6 maybe more (scala 3) Module: quill-jdbc Database: postgres

The following results in an error:

import java.time.LocalDateTime
import io.getquill.extras.LocalDateTimeOps

case class Table(
  age: Double,
  date: LocalDateTime
)

object TestTQuery {
  import io.getquill._
  val ctx = new PostgresJdbcContext(SnakeCase, "abc")

  import ctx._

  object DynQuery {
    private val initQuery = quote { query[Table] }
    def apply() = new DynQuery(initQuery)
  }
  case class DynQuery(query: Quoted[Query[Table]]) {
    inline def olderThan(age: Double) = DynQuery( query.filter(_.age > lift(age)))
    inline def after(dateTime: LocalDateTime) = DynQuery( query.filter(_.date > lift(dateTime)))
  }

  def test = {
    val q = DynQuery()
      .olderThan(21)
      .after(LocalDateTime.now().minusHours(2))
  }
}
[error] -- Error: /Users/ajr/trackabus/dev/scala-projects/scala-common/serverlib/src-3/tkb/QuillTest.scala:29:12 
[error] 27 |    val q = DynQuery()
[error] 28 |      .olderThan(21)
[error] 29 |      .after(LocalDateTime.now().minusHours(2))
[error]    |            ^
[error]    |
[error]    |s"==== Tree cannot be parsed to 'Ast' ====
[error]    |  LocalDateTimeOps(_$2.date)
[error]    |==== Extractors ===
[error]    |  Apply(Ident("LocalDateTimeOps"), List(Select(Ident("_$2"), "date")))
[error]    |==== Stacktrace ===
[error]    |  java.base/java.lang.Thread.getStackTrace(Thread.java:1610)
[error]    |  io.getquill.parser.engine.failParse$.apply(failParse.scala:27)
[error]    |  io.getquill.parser.engine.failParse$.apply(failParse.scala:12)
[error]    |  io.getquill.parser.engine.Parser.error(Parser.scala:10)
[error]    |  io.getquill.parser.engine.Parser.error$(Parser.scala:7)
[error]    |  io.getquill.parser.engine.ParserChain$$anon$1.error(ParserChain.scala:15)
[error]    |  io.getquill.parser.engine.Parser.apply$$anonfun$1(Parser.scala:9)

etc

When I don't use a date/time type (eg remove the after() method) it compiles fine

The equivalent under scala 2 compiles fine:

import java.time.LocalDateTime

case class Table(
  age: Double,
  date: LocalDateTime
)

object TestTQuery {
  import io.getquill._
  val ctx = new PostgresJdbcContext(SnakeCase, "abc")
  import ctx._

  implicit class DateComparison(left: LocalDateTime) {
    def >(right: LocalDateTime) = quote(infix"$left > $right".as[Boolean])
  }

  object DynQuery {
    private val initQuery = quote { query[Table] }
    def apply() = new DynQuery(initQuery)
  }

  case class DynQuery(query: Quoted[Query[Table]]) {
    def olderThan(age: Double) = DynQuery( quote { query.filter(_.age > lift(age)) })
    def after(dateTime: LocalDateTime) = DynQuery( quote { query.filter(_.date > lift(dateTime)) })
  }

  def test = {
    val q = DynQuery()
      .olderThan(21)
      .after(LocalDateTime.now().minusHours(2))
  }
}

ajrnz avatar Oct 17 '22 08:10 ajrnz

I think I got the same issue with Instant. Did you find any workaround ?

ylaurent avatar Oct 22 '22 02:10 ylaurent

Yes it seems to happen with all the modern date/time classes. I have no workaround at the moment.

ajrnz avatar Oct 22 '22 07:10 ajrnz

With scala 3 this extension allows me to add date operators

extension (inline date: LocalDateTime)
    inline def >(inline other: LocalDateTime) = quote { sql"$date > $other".as[Boolean] }
    inline def <(inline other: LocalDateTime) = quote { sql"$date < $other".as[Boolean] }

sky0hunter avatar Jan 11 '23 12:01 sky0hunter

Comparison of dates seems to compile fine with the current version of quill (4.8.5).

mprihoda avatar Aug 29 '24 13:08 mprihoda