I build a query that joins a few tables and restricts the result further unless one field called IncludeAll
equals True
.
I'm trying to write it like this
fetch i = runDb . select . from $ \(a, b, c) -> do
where_ $
a ^. AId ==. valkey i
&&. b ^. BField1 ==. a ^. AField2
&&. c ^. CField1 ==. a ^. AField3
unless (unValue $ b ^. BIncludeAll) $
where_ $ b ^. BField2 == c ^. CField2
return b
But I get the following error
Couldn't match expected type
Bool
with actual typeDatabase.Esqueleto.Internal.Language.Value Bool
in the first argument ofunless
So the unValue
somehow does not do the trick. Indeed, something like b ^. BIncludeAll
has the type expr (Value a)
.
Looking at the definition of SqlExpr
in the source didn't help me, either:
It's an ADT:
data SqlExpr a where ...
PS: I use an SQL backend, but ideally that should not matter, right?
unless
expects a Bool
as its argument, that means a boolean in the "Haskell world". You are passing it unValue $ b ^. BIncludeAll
, but b ^. BIncludeAll
is not of type Value Bool
, it's an SqlExpr (Value Bool)
, which represents a boolean expression in the "database world". It's an SQL statement that, when evaluated, returns a boolean. The only way to turn SqlExpr (Value Bool)
into an actual Value Bool
is by calling select $ from $ ...
.
As others have noted, the correct way to do this is to just use where_ (b ^. BIncludeAll ||. b ^. BField2 ==. c ^. CField2)
.