1

I want to use a LEFT JOIN to fetch products and their (optional) attributes. I have types like:

type ProductPGR = ProductPoly (Column (PGID Product)) (Column PGText)
type ProductAttributePGR = ProductAttributePoly (Column (PGID ProductAttribute)) (Column (PGID Product)) (Column PGInt4)

My intention was to use:

  (p :: ProductPGR, pa :: Maybe ProductAttributePGR) <- leftJoinF
    (\p' pa' -> (p', Just pa'))
    (\p'     -> (p', Nothing))
    (\p' pa' -> productId p' .== paProductId pa')
    productQuery
    productAttributeQuery -< ()

This doesn't compile because:

No instance for (Default
                     IfPP
                     (Maybe
                        (ProductAttributePoly
                           (Column (PGID ProductAttribute))
                           (Column (PGID Product))
                           (Column PGInt4))))
                     (Maybe
                        (ProductAttributePoly
                           (Column (PGID ProductAttribute))
                           (Column (PGID Product))
                           (Column PGInt4))))
arising from a use of ‘leftJoinF’

Am I really supposed to define this instance? What is it for and how would I do that?

Or if I'm not supposed to use Maybe, what else would I do?

limick
  • 55
  • 3
  • What is the SQL interpretation of the `Maybe` type? If you would like to use `Maybe` in the generated SQL, you must define and implement such an interpretation. But you should not write any instances; you need functions `_Nothing :: Column (Maybe a)` and `_Just :: Column a -> Column (Maybe a)` (and probably a destructor - `caseMaybe :: Column b -> (Column a -> Column b) -> Column (Maybe a) -> b`) – user2407038 May 01 '18 at 20:23
  • `Nothing :: Maybe ProductAttributePGR` was supposed to mean that all the relevant columns are null, but from your comment and from [here](http://haskell.vacationlabs.com/en/latest/docs/opaleye/basic-db-mapping.html#different-types-for-read-write-again) it seems that `Maybe` has no business being there, instead all the columns on the right side of the join have to be `Nullable`. I thought that `leftJoinF` would help me get around that, but apparently that's not the case. – limick May 01 '18 at 21:09

1 Answers1

0

You can't return a Maybe out of a functional join. Functional join allows you to avoid Nullable in the sense that it hides the IS NULL check from you. It doesn't allow you to "lift the nullability" onto the Haskell side.

Tom Ellis
  • 9,224
  • 1
  • 29
  • 54