rel8 icon indicating copy to clipboard operation
rel8 copied to clipboard

Improve documentation for ordering nulls

Open elldritch opened this issue 4 years ago • 4 comments

How do I order by a nullable column? This doesn't work:

data SomeTable f = SomeTable {
  someColumn :: Column f (Maybe UTCTime)
}

-- ...

someQuery = do
  row <- each someTableSchema
  orderBy (someColumn >$< desc) row

GHC complains:

    • No instance for (DBOrd (Maybe UTCTime))
        arising from a use of ‘desc’
    • In the second argument of ‘(>$<)’, namely ‘desc’
      In the first argument of ‘orderBy’, namely ‘(someColumn >$< desc)’
      In the expression: orderBy (someColumn >$< desc)

I was surprised to discover that there is no instance (DBOrd a) => DBOrd (Maybe a). Is this missing, or is this intentional? Is there a better way to order a nullable field?

elldritch avatar Jan 31 '22 23:01 elldritch

Hi @liftM,

To order by nullable, you need to use nullsFirst (or nullsLast). Also, orderBy operates on a whole Query rather than a single row (much like how sort operates on a [a] rather than just an a). Putting this all together, we have:

someQuery = orderBy (someColumn >$< nullsFirst desc) $ do
  each someTableSchema

ocharles avatar Feb 01 '22 09:02 ocharles

Ah, thanks! It wasn't clear that this is how nullsFirst and nullsLast was meant to be used. Thanks for the assist!

elldritch avatar Feb 01 '22 10:02 elldritch

@liftM Ok, sounds like we should improve the documentation around this. I'll re-open this and repurpose the issue.

ocharles avatar Feb 01 '22 10:02 ocharles

I think also something helpful would be explicitly categorizing which query functions are monadic guards (like where_), which are monadic functions (like with and filter), and which are query functions (like orderBy). I eventually puzzled most of this out on my own using the examples (which are really helpful!), but it took me a while to realize that different query modifiers were meant to be used in different ways.

elldritch avatar Feb 01 '22 21:02 elldritch