haskell-beam / beam

A type-safe, non-TH Haskell SQL library and ORM
https://haskell-beam.github.io/beam/
576 stars 171 forks source link

Writing custom queries #620

Open hasufell opened 2 years ago

hasufell commented 2 years ago

I read these both pages:

  1. https://hackage.haskell.org/package/beam-core-0.9.2.0/docs/Database-Beam-Query-CustomSQL.html
  2. https://haskell-beam.github.io/beam/user-guide/extensibility/#custom-expressions

And have still no idea how to write a custom query. I followed the first page, which points to the non-existent page https://haskell-beam.github.io/beam/user-guide/extensibility/extensibility. Then I followed the second page and I end up getting errors:

    • No instance for (IsCustomSqlSyntax
                         (Database.Beam.Backend.SQL.SQL92.Sql92SelectTableExpressionSyntax
                            (Database.Beam.Backend.SQL.SQL92.Sql92SelectSelectTableSyntax
                               (Database.Beam.Backend.SQL.SQL92.Sql92SelectSyntax
                                  (Database.Beam.Backend.SQL.BeamSqlBackendSyntax ctxt)))))
        arising from a use of ‘customExpr_’
    • In the expression: customExpr_ myFuncImpl
      In an equation for ‘instr_’:
          instr_
            = customExpr_ myFuncImpl
            where
                myFuncImpl :: (Monoid a, IsString a) => a -> a -> a
                myFuncImpl str needle = "instr(" <> str <> ", " <> needle <> ")"

The page says:

Your backend's syntax must implement the IsSqlCustomExpressionSyntax type class.

I don't know what that means. How to implement this? Where's an example?

kmicklas commented 2 years ago

The instance it's complaining about is just the constraint you need to add to the declaration of instr_. It's implemented by the backend (Postgres or SQLite).

The Haddocks definitely don't make this clear enough, and we should probably have an example of this in the markdown docs too.

kmicklas commented 2 years ago

Actually it turns out we do have an example in the docs, but it's in the context of a query with a concrete backend, so we don't demonstrate the necessary context for defining a custom combinator.