Skip to content

Commit

Permalink
Fix semantics of not_ applied over &&. and ||. (#379)
Browse files Browse the repository at this point in the history
* Add tests for not_ applied to more complex expressions

* Always parenthesize arguments to not_

* Update test/Common/Test.hs

---------

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>
  • Loading branch information
blujupiter32 and parsonsmatt authored Dec 26, 2024
1 parent 2b8f2cf commit c0a381e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 14 deletions.
7 changes: 3 additions & 4 deletions src/Database/Esqueleto/Internal/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -717,16 +717,15 @@ countDistinct :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a)
countDistinct = countHelper "(DISTINCT " ")"

not_ :: SqlExpr (Value Bool) -> SqlExpr (Value Bool)
not_ v = ERaw noMeta $ \p info -> first ("NOT " <>) $ x p info
not_ v = ERaw noMeta (const $ first ("NOT " <>) . x)
where
x p info =
x info =
case v of
ERaw m f ->
if hasCompositeKeyMeta m then
throw (CompositeKeyErr NotError)
else
let (b, vals) = f Never info
in (parensM p b, vals)
f Parens info

(==.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(==.) = unsafeSqlBinOpComposite " = " " AND "
Expand Down
55 changes: 45 additions & 10 deletions test/Common/Test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -878,16 +878,6 @@ testSelectWhere = describe "select where_" $ do
return p
asserting $ ret `shouldBe` [ p1e ]

itDb "works for a simple example with (>.) and not_ [uses just . val]" $ do
_ <- insert' p1
_ <- insert' p2
p3e <- insert' p3
ret <- select $
from $ \p -> do
where_ (not_ $ p ^. PersonAge >. just (val 17))
return p
asserting $ ret `shouldBe` [ p3e ]

describe "when using between" $ do
itDb "works for a simple example with [uses just . val]" $ do
p1e <- insert' p1
Expand Down Expand Up @@ -921,6 +911,51 @@ testSelectWhere = describe "select where_" $ do
, val $ PointKey 5 6 )
asserting $ ret `shouldBe` [()]

describe "when using not_" $ do
itDb "works for a single expression" $ do
ret <-
select $
pure $ not_ $ val True
asserting $ do
ret `shouldBe` [Value False]

itDb "works for a simple example with (>.) [uses just . val]" $ do
_ <- insert' p1
_ <- insert' p2
p3e <- insert' p3
ret <- select $
from $ \p -> do
where_ (not_ $ p ^. PersonAge >. just (val 17))
return p
asserting $ ret `shouldBe` [ p3e ]
itDb "works with (==.) and (||.)" $ do
_ <- insert' p1
_ <- insert' p2
p3e <- insert' p3
ret <- select $
from $ \p -> do
where_ (not_ $ p ^. PersonName ==. val "John" ||. p ^. PersonName ==. val "Rachel")
return p
asserting $ ret `shouldBe` [ p3e ]
itDb "works with (>.), (<.) and (&&.) [uses just . val]" $ do
p1e <- insert' p1
_ <- insert' p2
_ <- insert' p3
ret <- select $
from $ \p -> do
where_ (not_ $ (p ^. PersonAge >. just (val 10)) &&. (p ^. PersonAge <. just (val 30)))
return p
asserting $ ret `shouldBe` [ p1e ]
itDb "works with between [uses just . val]" $ do
_ <- insert' p1
_ <- insert' p2
p3e <- insert' p3
ret <- select $
from $ \p -> do
where_ (not_ $ (p ^. PersonAge) `between` (just $ val 20, just $ val 40))
return p
asserting $ ret `shouldBe` [ p3e ]

itDb "works with avg_" $ do
_ <- insert' p1
_ <- insert' p2
Expand Down

0 comments on commit c0a381e

Please sign in to comment.