Avoid generating an empty list as the left operand to NOT IN (#273)

* Avoid generating an empty list as the left operand to NOT IN

Postgres treats 'x in ()' and 'x not in ()' as syntax errors. Instead
translate:

  x in ()      ⇒  FALSE
  x not in ()  ⇒  TRUE

Older versions of esqueleto did this, but apparently the latter got
lost.

* Bump version and update changelog
This commit is contained in:
Chris Parks 2021-07-08 17:27:32 -07:00 committed by GitHub
parent 3a12a15d00
commit e8271a00d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 2 deletions

View File

@ -1,3 +1,9 @@
3.5.2.1
=======
- @cdparks
- [#273](https://github.com/bitemyapp/esqueleto/pull/273)
- Avoid generating an empty list as the left operand to `NOT IN`.
3.5.2.0
=======
- @ivanbakel

View File

@ -1,7 +1,7 @@
cabal-version: 1.12
name: esqueleto
version: 3.5.2.0
version: 3.5.2.1
synopsis: Type-safe EDSL for SQL queries on persistent backends.
description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime.
.

View File

@ -939,7 +939,11 @@ notIn :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> S
ERaw noMeta $ \_ info ->
let (b1, vals1) = v Parens info
(b2, vals2) = list Parens info
in (b1 <> " NOT IN " <> b2, vals1 <> vals2)
in
if b2 == "()" then
("TRUE", [])
else
(b1 <> " NOT IN " <> b2, vals1 <> vals2)
-- | @EXISTS@ operator. For example:
--

View File

@ -1431,6 +1431,19 @@ testListOfValues = describe "lists of values" $ do
return p
asserting $ ret `shouldBe` [ Entity p2k p2 ]
itDb "NOT IN works for valList (null list)" $ do
p1k <- insert p1
p2k <- insert p2
p3k <- insert p3
ret <- select $
from $ \p -> do
where_ (p ^. PersonName `notIn` valList [])
return p
asserting $ ret `shouldMatchList` [ Entity p1k p1
, Entity p2k p2
, Entity p3k p3
]
itDb "EXISTS works for subList_select" $ do
p1k <- insert p1
_p2k <- insert p2