prowdsponsor / esqueleto

Bare bones, type-safe EDSL for SQL queries on persistent backends.
http://hackage.haskell.org/package/esqueleto
BSD 3-Clause "New" or "Revised" License
178 stars 51 forks source link

`like` doesn't work with Maybe fields #68

Closed rehno-lindeque closed 9 years ago

rehno-lindeque commented 10 years ago

It looks like like doesn't work with a Maybe field in the database because it expects the arguments to satisfy IsString s.

E.g. This does not work if field of table A is a Maybe type

  results <- select $ from $ \a -> do
      where_ $ (a ^. AField) `like`  concat_ [(%), val "some text", (%)]
      return a
mitchellwrosen commented 10 years ago

Indeed. Can you try using this instead?

unsafeLike :: SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeLike = unsafeSqlBinOp " LIKE "
rehno-lindeque commented 10 years ago

I will report back once I've tried it, thank you (that looks like it should work though, I'm happy to close the issue and reopen if I run into trouble)

mitchellwrosen commented 10 years ago

I don't know if you should close the issue, as my "solution" kind of sucks. Some rethinking of the types might be in order.

rehno-lindeque commented 10 years ago

Good point, it's probably not ideal. I'll leave it open for now.

Pamelloes commented 9 years ago

Just ran into this same issue. I worked out a solution using coalesceDefault, but that seems kind of ridiculous. Has there been any progress lately?

AaronFriel commented 9 years ago

I just want to chime in that someone reported having some pain with this in #haskell.

It looks like this is an issue with almost all of the comparison ops, e.g.:

(>.) :: PersistField typ => expr (Value typ) -> expr (Value typ) -> expr (Value Bool) 

ANSI SQL implementations have well-defined behavior for nullableColumn > value and value > NULL. I am not sure how it would be typed, but they are valid operations.

meteficha commented 9 years ago

@AaronFriel, just use just, your case shouldn't have any problem.

AaronFriel commented 9 years ago

@meteficha I was trying to help @Pamelloes with this, and they were having a lot of difficulty using just correctly.

Pinging @Pamelloes to share the code snippet, as it's not mine to share and I'm not an esqueleto user myself.

Pamelloes commented 9 years ago

The code snippet @AaronFriel provided works if you use just. However when using the like operator, there's an IsString requirement and since there is no IsString instance for IsString a => Maybe a, using just will not work. @mitchellwrosen posted a temporary solution around a year ago, however a more type safe/robust solution should probably exist.

On Jul 25, 2015, at 15:33, Aaron Friel notifications@github.com wrote:

@meteficha I was trying to help @Pamelloes with this, and they were having a lot of difficulty using just correctly.

Pinging @Pamelloes to share the code snippet, as it's not mine to share and I'm not an esqueleto user myself.

— Reply to this email directly or view it on GitHub.

meteficha commented 9 years ago

@Pamelloes: like is problematic due to IsString. However, (>.) should work just fine, which is what @AaronFriel mentioned.

Pamelloes commented 9 years ago

@meteficha Exactly :) That's what I was trying to say in my comment though it might not have been as clear as it could be.

AaronFriel commented 9 years ago

@meteficha My bad. I wasn't aware the other instances would work. like and any other string ops should definitely support operations when the column is nullable.

meteficha commented 9 years ago

I've released esqueleto-2.4.0 with a new SqlString class of which Maybe is an instance. Also, there's now castString. Please re-open this issue if you feel something is missing :).