Search code examples
haskellyesodpersistentesqueleto

esqueleto: outer join doesn't compile


Here's a subset of my model:

ServerWebsite
    desc Text
    url Text
    text Text
    username Text
    password Password
    serverDatabaseId ServerDatabaseId Maybe
    groupName Text Maybe
    serverId ServerId
    deriving Show Typeable
ServerDatabase
    desc Text
    name Text
    text Text
    username Text
    password Password
    groupName Text Maybe
    serverId ServerId
    deriving Show Typeable

I can't make this query build:

filterServerWebsites :: SqlExpr (Value Text) -> SqlPersistM [Entity ServerWebsite]
filterServerWebsites query = select $ from $ \(w `LeftOuterJoin` db) -> do
    on (w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)
    where_ ((w ^. ServerWebsiteDesc `like` query)
        ||. (w ^. ServerWebsiteUrl `like` query)
        ||. (w ^. ServerWebsiteText `like` query)
        ||. (db ?. ServerDatabaseDesc `like` just query))
    return w

I don't understand the build errors:

    • Couldn't match expected type ‘SqlQuery a1’
                  with actual type ‘(a0 -> b0) -> a0 -> a0 -> c0’
    • Probable cause: ‘on’ is applied to too few arguments
      In a stmt of a 'do' block:
        on (w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)

and:

    • Couldn't match expected type ‘b0 -> b0 -> c0’
                  with actual type ‘SqlExpr (Value Bool)’
    • Possible cause: ‘(==.)’ is applied to too many arguments
      In the first argument of ‘on’, namely
        ‘(w ^. ServerWebsiteServerDatabaseId ==. db ?. ServerDatabaseId)’

I don't understand where I'm going wrong?

EDIT I was starting from this code, which does work:

filterServerWebsites :: SqlExpr (Value Text) -> SqlPersistM [Entity ServerWebsite]
filterServerWebsites query = select $ from $ \w -> do
    where_ ((w ^. ServerWebsiteDesc `like` query)
        ||. (w ^. ServerWebsiteUrl `like` query)
        ||. (w ^. ServerWebsiteText `like` query))
    return w

Solution

  • Right. So really my own stupidity. I should have made a sample project to reproduce the issue, then I would have spotted the issue.

    The issue was that I had at the top of the file...

    import Database.Esqueleto hiding (on)
    import Data.Function
    

    ... because I was using somewhere else in that file on from Data.Function.

    I changed that to...

    import Database.Esqueleto
    import qualified Data.Function as F
    

    And now all works fine...