crecto icon indicating copy to clipboard operation
crecto copied to clipboard

Querying Time field with Time object breaks the Crystal compiler

Open zbaylin opened this issue 7 years ago • 2 comments

Using Crystal 0.25.0, if a query is formulated as such:

order = Repo.get_by(Order, day: Time.now)

with field day being defined of type Time in the schema, the following exception is thrown at compile-time:

Module validation failed: Function return type does not match operand type of return inst!
  ret %"(Hash(Symbol, Array(Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil)) | Hash(Symbol, Array(Int32 | Int64 | String | Nil)) | Hash(Symbol, Array(Int32)) | Hash(Symbol, Array(Int64)) | Hash(Symbol, Array(String)) | Hash(Symbol, Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil) | Hash(Symbol, Int32 | Int64 | String | Nil) | Hash(Symbol, Int32 | Int64 | String | Time | Nil) | Hash(Symbol, Int32 | Int64 | String) | Hash(Symbol, Int32 | String) | Hash(Symbol, Int32) | Hash(Symbol, Int64 | String) | Hash(Symbol, Int64) | Hash(Symbol, Nil) | Hash(Symbol, String) | NamedTuple(clause: String, params: Array(Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil)))" %1, !dbg !24
 %"(Hash(Symbol, Array(Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil)) | Hash(Symbol, Array(Int32 | Int64 | String | Nil)) | Hash(Symbol, Array(Int32)) | Hash(Symbol, Array(Int64)) | Hash(Symbol, Array(String)) | Hash(Symbol, Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil) | Hash(Symbol, Int32 | Int64 | String | Nil) | Hash(Symbol, Int32 | Int64 | String) | Hash(Symbol, Int32 | String) | Hash(Symbol, Int32) | Hash(Symbol, Int64 | String) | Hash(Symbol, Int64) | Hash(Symbol, Nil) | Hash(Symbol, String) | NamedTuple(clause: String, params: Array(Bool | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::Any | String | Time | Nil)))" = type { i32, [2 x i64] }
???
???
???
???
???
???
???
???
???

Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues

However, if the query is formatted with the Time.to_s method invoked, as such:

order = Repo.get_by(Order, day: Time.now.to_s)

the program compiles (and runs) perfectly fine.

Not sure if I should make this an issue in the Crystal repo until it's determined if it's a bug with crecto

zbaylin avatar Jun 24 '18 21:06 zbaylin

I'm getting a similar issue with module validation, but with Bool values. Something like

Repo.get(Session, session_id, Query.where(valid: true))

will fail with a module validation failure. Similarly,

Repo.get(Session, session_id, Query.where(valid: "true"))

successfully compiles.

With that, I think this is an issue with how the NamedTuple parameters to Query.where are handled. Specifically, the resolved type of the Hash created by parsing the parameters is too precise. In my case, the error had an extra Hash(Symbol, Bool) entry in the type union, and in yours, there's at least one type I saw that had Time, and Nil added to the value type of Hash.

I wonder if a solution might be to always cast where values to strings when they get stored?

faultyserver avatar Sep 22 '18 01:09 faultyserver

Curious if this is still an issue. Crystal has been updated a lot since 2018.

watzon avatar Dec 22 '23 18:12 watzon