valderman / selda

A type-safe, high-level SQL library for Haskell
https://selda.link
MIT License
478 stars 58 forks source link

Comparison between Nullable SqlType could crash the code #153

Open kamoii opened 3 years ago

kamoii commented 3 years ago

Comparison operators, like (.==), accepts aribtrary SqlType value.

(.==) :: (Same s t, SqlType a) => Col s a -> Col t a -> Col s Bool

Since Maybe Int is also an SqlTpye, the following code type checks. But one of the operand is NULL, the result will be NULL, making the code crash.

test :: IO Bool
test = withSQLite "test.sqlite" $ do
    [b] <- query $ pure $ just (4 :: Col s Int) .== literal Nothing
    pure b

Using Nullable module's operator (?==) will get the proper result type Col s (Maybe Bool). But the need to correctly use (.==) and (?==) is error-prone.

First thing that comes to my mind, is to add type IsNullable a :: 'Bool to SqlType type class. SqlType (Maybe a) instance will be the only instance to have IsNullable (Maybe a) = 'True, and other instances will have False.Then we could wrap Bool with Maybe when SqlType is IsNullable.